From: fred@xuni-t01.sc.intel.com Date: Sat, 20 Aug 2005 05:19:39 +0000 (-0800) Subject: First step to remove CONFIG_VTI for final supporting xen0+xenU+xenVTI at runtime... X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~16836^2~2 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=f54c66601e411985e844f7d37bcc538e8d4ae4bb;p=xen.git First step to remove CONFIG_VTI for final supporting xen0+xenU+xenVTI at runtime. This changeset mainly addresses common code like domain creation and rid allocation policy, including: - Boot time vti feature detection - Uniform arch_do_createdomain, new_thread, arch_set_infoguest, and construct_dom0. Now these function level CONFIG_VTIs have been removed with several specific lines still protected by CONFIG_VTIs. With more feature cleanup later, these lines will be free out grandually. - Use same rid allocation policy including physical emulation - Remove duplicated definition rr_t. Verified breaking nothing. ;-) Signed-off-by Kevin Tian --- diff --git a/xen/arch/ia64/Makefile b/xen/arch/ia64/Makefile index 7c397a328b..3b21df4024 100644 --- a/xen/arch/ia64/Makefile +++ b/xen/arch/ia64/Makefile @@ -14,8 +14,11 @@ OBJS = xensetup.o setup.o time.o irq.o ia64_ksyms.o process.o smp.o \ irq_ia64.o irq_lsapic.o vhpt.o xenasm.o hyperprivop.o dom_fw.o \ grant_table.o sn_console.o +# TMP holder to contain *.0 moved out of CONFIG_VTI +OBJS += vmx_init.o + ifeq ($(CONFIG_VTI),y) -OBJS += vmx_init.o vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o \ +OBJS += vmx_virt.o vmx_vcpu.o vmx_process.o vmx_vsa.o vmx_ivt.o\ vmx_phy_mode.o vmx_utility.o vmx_interrupt.o vmx_entry.o vmmu.o \ vtlb.o mmio.o vlsapic.o vmx_hypercall.o mm.o vmx_support.o pal_emul.o endif diff --git a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c index ca8b9a8f0b..bfbddca84a 100644 --- a/xen/arch/ia64/domain.c +++ b/xen/arch/ia64/domain.c @@ -38,25 +38,17 @@ #include /* for function declarations */ #include -#ifdef CONFIG_VTI #include #include #include #include #include -#endif // CONFIG_VTI #define CONFIG_DOMAIN0_CONTIGUOUS unsigned long dom0_start = -1L; -#ifdef CONFIG_VTI unsigned long dom0_size = 512*1024*1024; //FIXME: Should be configurable //FIXME: alignment should be 256MB, lest Linux use a 256MB page size unsigned long dom0_align = 256*1024*1024; -#else // CONFIG_VTI -unsigned long dom0_size = 512*1024*1024; //FIXME: Should be configurable -//FIXME: alignment should be 256MB, lest Linux use a 256MB page size -unsigned long dom0_align = 64*1024*1024; -#endif // CONFIG_VTI #ifdef DOMU_BUILD_STAGING unsigned long domU_staging_size = 32*1024*1024; //FIXME: Should be configurable unsigned long domU_staging_start; @@ -187,60 +179,6 @@ static void init_switch_stack(struct vcpu *v) memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96); } -#ifdef CONFIG_VTI -void arch_do_createdomain(struct vcpu *v) -{ - struct domain *d = v->domain; - struct thread_info *ti = alloc_thread_info(v); - - /* Clear thread_info to clear some important fields, like preempt_count */ - memset(ti, 0, sizeof(struct thread_info)); - init_switch_stack(v); - - /* Shared info area is required to be allocated at domain - * creation, since control panel will write some I/O info - * between front end and back end to that area. However for - * vmx domain, our design is to let domain itself to allcoate - * shared info area, to keep machine page contiguous. So this - * page will be released later when domainN issues request - * after up. - */ - d->shared_info = (void *)alloc_xenheap_page(); - /* Now assume all vcpu info and event indicators can be - * held in one shared page. Definitely later we need to - * consider more about it - */ - - memset(d->shared_info, 0, PAGE_SIZE); - d->shared_info->vcpu_data[v->vcpu_id].arch.privregs = - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); - printf("arch_vcpu_info=%p\n", d->shared_info->vcpu_data[0].arch.privregs); - memset(d->shared_info->vcpu_data[v->vcpu_id].arch.privregs, 0, PAGE_SIZE); - v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id]; - /* Mask all events, and specific port will be unmasked - * when customer subscribes to it. - */ - if(v == d->vcpu[0]) { - memset(&d->shared_info->evtchn_mask[0], 0xff, - sizeof(d->shared_info->evtchn_mask)); - } - - /* Allocate per-domain vTLB and vhpt */ - v->arch.vtlb = init_domain_tlb(v); - - /* Physical->machine page table will be allocated when - * final setup, since we have no the maximum pfn number in - * this stage - */ - - /* FIXME: This is identity mapped address for xenheap. - * Do we need it at all? - */ - d->xen_vastart = XEN_START_ADDR; - d->xen_vaend = XEN_END_ADDR; - d->arch.breakimm = 0x1000; -} -#else // CONFIG_VTI void arch_do_createdomain(struct vcpu *v) { struct domain *d = v->domain; @@ -263,11 +201,26 @@ void arch_do_createdomain(struct vcpu *v) v->vcpu_info = &(d->shared_info->vcpu_data[0]); d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME - if ((d->arch.metaphysical_rr0 = allocate_metaphysical_rr0()) == -1UL) + +#ifdef CONFIG_VTI + /* Per-domain vTLB and vhpt implementation. Now vmx domain will stick + * to this solution. Maybe it can be deferred until we know created + * one as vmx domain */ + v->arch.vtlb = init_domain_tlb(v); +#endif + + /* We may also need emulation rid for region4, though it's unlikely + * to see guest issue uncacheable access in metaphysical mode. But + * keep such info here may be more sane. + */ + if (((d->arch.metaphysical_rr0 = allocate_metaphysical_rr()) == -1UL) + || ((d->arch.metaphysical_rr4 = allocate_metaphysical_rr()) == -1UL)) BUG(); VCPU(v, metaphysical_mode) = 1; v->arch.metaphysical_rr0 = d->arch.metaphysical_rr0; + v->arch.metaphysical_rr4 = d->arch.metaphysical_rr4; v->arch.metaphysical_saved_rr0 = d->arch.metaphysical_rr0; + v->arch.metaphysical_saved_rr4 = d->arch.metaphysical_rr4; #define DOMAIN_RID_BITS_DEFAULT 18 if (!allocate_rid_range(d,DOMAIN_RID_BITS_DEFAULT)) // FIXME BUG(); @@ -292,7 +245,6 @@ void arch_do_createdomain(struct vcpu *v) return -ENOMEM; } } -#endif // CONFIG_VTI void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) { @@ -312,16 +264,28 @@ void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) c->shared = v->domain->shared_info->arch; } -#ifndef CONFIG_VTI int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) { struct pt_regs *regs = (struct pt_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1; + struct domain *d = v->domain; + int i, rc, ret; + unsigned long progress = 0; printf("arch_set_info_guest\n"); + if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + return 0; + + if (c->flags & VGCF_VMX_GUEST) { + if (!vmx_enabled) { + printk("No VMX hardware feature for vmx domain.\n"); + return -EINVAL; + } + + vmx_setup_platform(v, c); + } + *regs = c->regs; - regs->cr_ipsr = IA64_PSR_IT|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_IC|IA64_PSR_I|IA64_PSR_DFH|IA64_PSR_BN|IA64_PSR_SP|IA64_PSR_DI; - regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; - regs->ar_rsc |= (2 << 2); /* force PL2/3 */ + new_thread(v, regs->cr_iip, 0, 0); v->vcpu_info->arch.evtchn_vector = c->vcpu.evtchn_vector; if ( c->vcpu.privregs && copy_from_user(v->vcpu_info->arch.privregs, @@ -330,100 +294,13 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) return -EFAULT; } - init_all_rr(v); - - // this should be in userspace - regs->r28 = dom_fw_setup(v->domain,"nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1",256L); //FIXME v->arch.domain_itm_last = -1L; - VCPU(v, banknum) = 1; - VCPU(v, metaphysical_mode) = 1; + d->shared_info->arch = c->shared; - v->domain->shared_info->arch = c->shared; + /* Don't redo final setup */ + set_bit(_VCPUF_initialised, &v->vcpu_flags); return 0; } -#else // CONFIG_VTI -int arch_set_info_guest( - struct vcpu *v, struct vcpu_guest_context *c) -{ - struct domain *d = v->domain; - int i, rc, ret; - unsigned long progress = 0; - shared_iopage_t *sp; - - if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) - return 0; - - /* Lazy FP not implemented yet */ - clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); - if ( c->flags & VGCF_FPU_VALID ) - set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); - - /* Sync d/i cache conservatively, after domain N is loaded */ - ret = ia64_pal_cache_flush(3, 0, &progress, NULL); - if (ret != PAL_STATUS_SUCCESS) - panic("PAL CACHE FLUSH failed for dom[%d].\n", - v->domain->domain_id); - DPRINTK("Sync i/d cache for dom%d image SUCC\n", - v->domain->domain_id); - - /* Physical mode emulation initialization, including - * emulation ID allcation and related memory request - */ - physical_mode_init(v); - - /* FIXME: only support PMT table continuously by far */ - d->arch.pmt = __va(c->pt_base); - d->arch.max_pfn = c->pt_max_pfn; - d->arch.vmx_platform.shared_page_va = __va(c->share_io_pg); - sp = get_sp(d); - memset((char *)sp,0,PAGE_SIZE); - /* FIXME: temp due to old CP */ - sp->sp_global.eport = 2; -#ifdef V_IOSAPIC_READY - sp->vcpu_number = 1; -#endif - /* TEMP */ - d->arch.vmx_platform.pib_base = 0xfee00000UL; - - - if (c->flags & VGCF_VMX_GUEST) { - if (!vmx_enabled) - panic("No VMX hardware feature for vmx domain.\n"); - - vmx_final_setup_domain(d); - - /* One more step to enable interrupt assist */ - set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); - } - - vlsapic_reset(v); - vtm_init(v); - - /* Only open one port for I/O and interrupt emulation */ - if (v == d->vcpu[0]) { - memset(&d->shared_info->evtchn_mask[0], 0xff, - sizeof(d->shared_info->evtchn_mask)); - clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); - } - /* Setup domain context. Actually IA-64 is a bit different with - * x86, with almost all system resources better managed by HV - * directly. CP only needs to provide start IP of guest, which - * ideally is the load address of guest Firmware. - */ - new_thread(v, c->guest_iip, 0, 0); - - - d->xen_vastart = XEN_START_ADDR; - d->xen_vaend = XEN_END_ADDR; - d->arch.breakimm = 0x1000 + d->domain_id; - v->arch._thread.on_ustack = 0; - - /* Don't redo final setup */ - set_bit(_VCPUF_initialised, &v->vcpu_flags); - - return 0; -} -#endif // CONFIG_VTI void arch_do_boot_vcpu(struct vcpu *v) { @@ -443,7 +320,8 @@ void domain_relinquish_resources(struct domain *d) printf("domain_relinquish_resources: not implemented\n"); } -#ifdef CONFIG_VTI +// heavily leveraged from linux/arch/ia64/kernel/process.c:copy_thread() +// and linux/arch/ia64/kernel/process.c:kernel_thread() void new_thread(struct vcpu *v, unsigned long start_pc, unsigned long start_stack, @@ -453,7 +331,6 @@ void new_thread(struct vcpu *v, struct pt_regs *regs; struct ia64_boot_param *bp; extern char saved_command_line[]; - //char *dom0_cmdline = "BOOT_IMAGE=scsi0:\EFI\redhat\xenlinux nomca root=/dev/sdb1 ro"; #ifdef CONFIG_DOMAIN0_CONTIGUOUS @@ -471,61 +348,31 @@ void new_thread(struct vcpu *v, regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; // domain runs at PL2 } regs->cr_iip = start_pc; - regs->cr_ifs = 0; /* why? - matthewc */ + regs->cr_ifs = 1UL << 63; /* or clear? */ regs->ar_fpsr = FPSR_DEFAULT; - if (VMX_DOMAIN(v)) { - vmx_init_all_rr(v); - } else - init_all_rr(v); if (VMX_DOMAIN(v)) { - if (d == dom0) { +#ifdef CONFIG_VTI + vmx_init_all_rr(v); + if (d == dom0) VMX_VPD(v,vgr[12]) = dom_fw_setup(d,saved_command_line,256L); - printk("new_thread, done with dom_fw_setup\n"); - } /* Virtual processor context setup */ VMX_VPD(v, vpsr) = IA64_PSR_BN; VPD_CR(v, dcr) = 0; +#endif } else { - regs->r28 = dom_fw_setup(d,saved_command_line,256L); + init_all_rr(v); + if (d == dom0) + regs->r28 = dom_fw_setup(d,saved_command_line,256L); + else { + regs->ar_rsc |= (2 << 2); /* force PL2/3 */ + regs->r28 = dom_fw_setup(d,"nomca nosmp xencons=tty0 console=tty0 root=/dev/hda1",256L); //FIXME + } VCPU(v, banknum) = 1; VCPU(v, metaphysical_mode) = 1; d->shared_info->arch.flags = (d == dom0) ? (SIF_INITDOMAIN|SIF_PRIVILEGED|SIF_BLK_BE_DOMAIN|SIF_NET_BE_DOMAIN|SIF_USB_BE_DOMAIN) : 0; } } -#else // CONFIG_VTI - -// heavily leveraged from linux/arch/ia64/kernel/process.c:copy_thread() -// and linux/arch/ia64/kernel/process.c:kernel_thread() -void new_thread(struct vcpu *v, - unsigned long start_pc, - unsigned long start_stack, - unsigned long start_info) -{ - struct domain *d = v->domain; - struct pt_regs *regs; - struct ia64_boot_param *bp; - extern char saved_command_line[]; - -#ifdef CONFIG_DOMAIN0_CONTIGUOUS - if (d == dom0) start_pc += dom0_start; -#endif - - regs = (struct pt_regs *) ((unsigned long) v + IA64_STK_OFFSET) - 1; - regs->cr_ipsr = ia64_getreg(_IA64_REG_PSR) - | IA64_PSR_BITS_TO_SET | IA64_PSR_BN - & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_RI | IA64_PSR_IS); - regs->cr_ipsr |= 2UL << IA64_PSR_CPL0_BIT; // domain runs at PL2 - regs->cr_iip = start_pc; - regs->cr_ifs = 1UL << 63; - regs->ar_fpsr = FPSR_DEFAULT; - init_all_rr(v); - regs->r28 = dom_fw_setup(d,saved_command_line,256L); //FIXME - VCPU(v, banknum) = 1; - VCPU(v, metaphysical_mode) = 1; - d->shared_info->arch.flags = (d == dom0) ? (SIF_INITDOMAIN|SIF_PRIVILEGED|SIF_BLK_BE_DOMAIN|SIF_NET_BE_DOMAIN|SIF_USB_BE_DOMAIN) : 0; -} -#endif // CONFIG_VTI static struct page * map_new_domain0_page(unsigned long mpaddr) { @@ -903,44 +750,6 @@ domU_staging_write_32(unsigned long at, unsigned long a, unsigned long b, } #endif -#ifdef CONFIG_VTI -/* Up to whether domain is vmx one, different context may be setup - * here. - */ -void -post_arch_do_create_domain(struct vcpu *v, int vmx_domain) -{ - struct domain *d = v->domain; - - if (!vmx_domain) { - d->shared_info = (void*)alloc_xenheap_page(); - if (!d->shared_info) - panic("Allocate share info for non-vmx domain failed.\n"); - d->shared_info_va = 0xfffd000000000000; - - printk("Build shared info for non-vmx domain\n"); - build_shared_info(d); - /* Setup start info area */ - } -} - -/* For VMX domain, this is invoked when kernel model in domain - * request actively - */ -void build_shared_info(struct domain *d) -{ - int i; - - /* Set up shared-info area. */ - update_dom_time(d); - - /* Mask all upcalls... */ - for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; - - /* ... */ -} - /* * Domain 0 has direct access to all devices absolutely. However * the major point of this stub here, is to allow alloc_dom_mem @@ -954,175 +763,6 @@ void physdev_init_dom0(struct domain *d) extern unsigned long running_on_sim; unsigned int vmx_dom0 = 0; -int construct_dom0(struct domain *d, - unsigned long image_start, unsigned long image_len, - unsigned long initrd_start, unsigned long initrd_len, - char *cmdline) -{ - char *dst; - int i, rc; - unsigned long pfn, mfn; - unsigned long nr_pt_pages; - unsigned long count; - unsigned long alloc_start, alloc_end; - struct pfn_info *page = NULL; - start_info_t *si; - struct vcpu *v = d->vcpu[0]; - struct domain_setup_info dsi; - unsigned long p_start; - unsigned long pkern_start; - unsigned long pkern_entry; - unsigned long pkern_end; - unsigned long ret; - unsigned long progress = 0; - -//printf("construct_dom0: starting\n"); - /* Sanity! */ -#ifndef CLONE_DOMAIN0 - if ( d != dom0 ) - BUG(); - if ( test_bit(_DOMF_constructed, &d->domain_flags) ) - BUG(); -#endif - - printk("##Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d); - memset(&dsi, 0, sizeof(struct domain_setup_info)); - - printk("*** LOADING DOMAIN 0 ***\n"); - - alloc_start = dom0_start; - alloc_end = dom0_start + dom0_size; - d->tot_pages = d->max_pages = (alloc_end - alloc_start)/PAGE_SIZE; - image_start = __va(ia64_boot_param->initrd_start); - image_len = ia64_boot_param->initrd_size; - - dsi.image_addr = (unsigned long)image_start; - dsi.image_len = image_len; - rc = parseelfimage(&dsi); - if ( rc != 0 ) - return rc; - - /* Temp workaround */ - if (running_on_sim) - dsi.xen_section_string = (char *)1; - - if ((!vmx_enabled) && !dsi.xen_section_string) { - printk("Lack of hardware support for unmodified vmx dom0\n"); - panic(""); - } - - if (vmx_enabled && !dsi.xen_section_string) { - printk("Dom0 is vmx domain!\n"); - vmx_dom0 = 1; - } - - p_start = dsi.v_start; - pkern_start = dsi.v_kernstart; - pkern_end = dsi.v_kernend; - pkern_entry = dsi.v_kernentry; - - printk("p_start=%lx, pkern_start=%lx, pkern_end=%lx, pkern_entry=%lx\n", - p_start,pkern_start,pkern_end,pkern_entry); - - if ( (p_start & (PAGE_SIZE-1)) != 0 ) - { - printk("Initial guest OS must load to a page boundary.\n"); - return -EINVAL; - } - - printk("METAPHYSICAL MEMORY ARRANGEMENT:\n" - " Kernel image: %lx->%lx\n" - " Entry address: %lx\n" - " Init. ramdisk: (NOT IMPLEMENTED YET)\n", - pkern_start, pkern_end, pkern_entry); - - if ( (pkern_end - pkern_start) > (d->max_pages * PAGE_SIZE) ) - { - printk("Initial guest OS requires too much space\n" - "(%luMB is greater than %luMB limit)\n", - (pkern_end-pkern_start)>>20, (d->max_pages<>20); - return -ENOMEM; - } - - // Other sanity check about Dom0 image - - /* Construct a frame-allocation list for the initial domain, since these - * pages are allocated by boot allocator and pfns are not set properly - */ - for ( mfn = (alloc_start>>PAGE_SHIFT); - mfn < (alloc_end>>PAGE_SHIFT); - mfn++ ) - { - page = &frame_table[mfn]; - page_set_owner(page, d); - page->u.inuse.type_info = 0; - page->count_info = PGC_allocated | 1; - list_add_tail(&page->list, &d->page_list); - - /* Construct 1:1 mapping */ - machine_to_phys_mapping[mfn] = mfn; - } - - post_arch_do_create_domain(v, vmx_dom0); - - /* Load Dom0 image to its own memory */ - loaddomainelfimage(d,image_start); - - /* Copy the initial ramdisk. */ - - /* Sync d/i cache conservatively */ - ret = ia64_pal_cache_flush(4, 0, &progress, NULL); - if (ret != PAL_STATUS_SUCCESS) - panic("PAL CACHE FLUSH failed for dom0.\n"); - printk("Sync i/d cache for dom0 image SUCC\n"); - - /* Physical mode emulation initialization, including - * emulation ID allcation and related memory request - */ - physical_mode_init(v); - /* Dom0's pfn is equal to mfn, so there's no need to allocate pmt - * for dom0 - */ - d->arch.pmt = NULL; - - /* Give up the VGA console if DOM0 is configured to grab it. */ - if (cmdline != NULL) - console_endboot(strstr(cmdline, "tty0") != NULL); - - /* VMX specific construction for Dom0, if hardware supports VMX - * and Dom0 is unmodified image - */ - printk("Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d); - if (vmx_dom0) - vmx_final_setup_domain(dom0); - - /* vpd is ready now */ - vlsapic_reset(v); - vtm_init(v); - - set_bit(_DOMF_constructed, &d->domain_flags); - new_thread(v, pkern_entry, 0, 0); - - physdev_init_dom0(d); - // FIXME: Hack for keyboard input -#ifdef CLONE_DOMAIN0 -if (d == dom0) -#endif - serial_input_init(); - if (d == dom0) { - VCPU(v, delivery_mask[0]) = -1L; - VCPU(v, delivery_mask[1]) = -1L; - VCPU(v, delivery_mask[2]) = -1L; - VCPU(v, delivery_mask[3]) = -1L; - } - else __set_bit(0x30,VCPU(v, delivery_mask)); - - return 0; -} - - -#else //CONFIG_VTI - int construct_dom0(struct domain *d, unsigned long image_start, unsigned long image_len, unsigned long initrd_start, unsigned long initrd_len, @@ -1133,8 +773,7 @@ int construct_dom0(struct domain *d, unsigned long pfn, mfn; unsigned long nr_pt_pages; unsigned long count; - //l2_pgentry_t *l2tab, *l2start; - //l1_pgentry_t *l1tab = NULL, *l1start = NULL; + unsigned long alloc_start, alloc_end; struct pfn_info *page = NULL; start_info_t *si; struct vcpu *v = d->vcpu[0]; @@ -1144,6 +783,7 @@ int construct_dom0(struct domain *d, unsigned long pkern_start; unsigned long pkern_entry; unsigned long pkern_end; + unsigned long ret, progress = 0; //printf("construct_dom0: starting\n"); /* Sanity! */ @@ -1158,7 +798,9 @@ int construct_dom0(struct domain *d, printk("*** LOADING DOMAIN 0 ***\n"); - d->max_pages = dom0_size/PAGE_SIZE; + alloc_start = dom0_start; + alloc_end = dom0_start + dom0_size; + d->tot_pages = d->max_pages = dom0_size/PAGE_SIZE; image_start = __va(ia64_boot_param->initrd_start); image_len = ia64_boot_param->initrd_size; //printk("image_start=%lx, image_len=%lx\n",image_start,image_len); @@ -1171,6 +813,23 @@ int construct_dom0(struct domain *d, if ( rc != 0 ) return rc; +#ifdef CONFIG_VTI + /* Temp workaround */ + if (running_on_sim) + dsi.xen_section_string = (char *)1; + + /* Check whether dom0 is vti domain */ + if ((!vmx_enabled) && !dsi.xen_section_string) { + printk("Lack of hardware support for unmodified vmx dom0\n"); + panic(""); + } + + if (vmx_enabled && !dsi.xen_section_string) { + printk("Dom0 is vmx domain!\n"); + vmx_dom0 = 1; + } +#endif + p_start = dsi.v_start; pkern_start = dsi.v_kernstart; pkern_end = dsi.v_kernend; @@ -1214,14 +873,43 @@ int construct_dom0(struct domain *d, for ( i = 0; i < MAX_VIRT_CPUS; i++ ) d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; +#ifdef CONFIG_VTI + /* Construct a frame-allocation list for the initial domain, since these + * pages are allocated by boot allocator and pfns are not set properly + */ + for ( mfn = (alloc_start>>PAGE_SHIFT); + mfn < (alloc_end>>PAGE_SHIFT); + mfn++ ) + { + page = &frame_table[mfn]; + page_set_owner(page, d); + page->u.inuse.type_info = 0; + page->count_info = PGC_allocated | 1; + list_add_tail(&page->list, &d->page_list); + + /* Construct 1:1 mapping */ + machine_to_phys_mapping[mfn] = mfn; + } + + /* Dom0's pfn is equal to mfn, so there's no need to allocate pmt + * for dom0 + */ + d->arch.pmt = NULL; +#endif + /* Copy the OS image. */ - //(void)loadelfimage(image_start); loaddomainelfimage(d,image_start); /* Copy the initial ramdisk. */ //if ( initrd_len != 0 ) // memcpy((void *)vinitrd_start, initrd_start, initrd_len); + /* Sync d/i cache conservatively */ + ret = ia64_pal_cache_flush(4, 0, &progress, NULL); + if (ret != PAL_STATUS_SUCCESS) + panic("PAL CACHE FLUSH failed for dom0.\n"); + printk("Sync i/d cache for dom0 image SUCC\n"); + #if 0 /* Set up start info area. */ //si = (start_info_t *)vstartinfo_start; @@ -1257,14 +945,21 @@ int construct_dom0(struct domain *d, #endif /* Give up the VGA console if DOM0 is configured to grab it. */ -#ifdef IA64 if (cmdline != NULL) -#endif - console_endboot(strstr(cmdline, "tty0") != NULL); + console_endboot(strstr(cmdline, "tty0") != NULL); + + /* VMX specific construction for Dom0, if hardware supports VMX + * and Dom0 is unmodified image + */ + printk("Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d); + if (vmx_dom0) + vmx_final_setup_domain(dom0); set_bit(_DOMF_constructed, &d->domain_flags); new_thread(v, pkern_entry, 0, 0); + physdev_init_dom0(d); + // FIXME: Hack for keyboard input #ifdef CLONE_DOMAIN0 if (d == dom0) @@ -1280,7 +975,6 @@ if (d == dom0) return 0; } -#endif // CONFIG_VTI // FIXME: When dom0 can construct domains, this goes away (or is rewritten) int construct_domU(struct domain *d, diff --git a/xen/arch/ia64/linux-xen/setup.c b/xen/arch/ia64/linux-xen/setup.c index 0a4261d94f..0b6fb0b289 100644 --- a/xen/arch/ia64/linux-xen/setup.c +++ b/xen/arch/ia64/linux-xen/setup.c @@ -51,9 +51,7 @@ #include #include #include -#ifdef CONFIG_VTI #include -#endif // CONFIG_VTI #include #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) @@ -402,9 +400,9 @@ late_setup_arch (char **cmdline_p) cpu_physical_id(0) = hard_smp_processor_id(); #endif -#ifdef CONFIG_VTI +#ifdef XEN identify_vmx_feature(); -#endif // CONFIG_VTI +#endif cpu_init(); /* initialize the bootstrap CPU */ @@ -600,7 +598,7 @@ identify_cpu (struct cpuinfo_ia64 *c) c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1)); c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1)); -#ifdef CONFIG_VTI +#ifdef XEN /* If vmx feature is on, do necessary initialization for vmx */ if (vmx_enabled) vmx_init_env(); diff --git a/xen/arch/ia64/regionreg.c b/xen/arch/ia64/regionreg.c index 3172c2af35..974f380efb 100644 --- a/xen/arch/ia64/regionreg.c +++ b/xen/arch/ia64/regionreg.c @@ -29,9 +29,6 @@ extern void ia64_new_rr7(unsigned long rid,void *shared_info, void *shared_arch_ #define MAX_RID_BLOCKS (1 << (IA64_MAX_IMPL_RID_BITS-IA64_MIN_IMPL_RID_BITS)) #define RIDS_PER_RIDBLOCK MIN_RIDS -// This is the one global memory representation of the default Xen region reg -ia64_rr xen_rr; - #if 0 // following already defined in include/asm-ia64/gcc_intrin.h // it should probably be ifdef'd out from there to ensure all region @@ -65,7 +62,7 @@ unsigned long allocate_reserved_rid(void) // returns -1 if none available -unsigned long allocate_metaphysical_rr0(void) +unsigned long allocate_metaphysical_rr(void) { ia64_rr rrv; @@ -81,17 +78,6 @@ int deallocate_metaphysical_rid(unsigned long rid) return 1; } - -void init_rr(void) -{ - xen_rr.rrval = 0; - xen_rr.ve = 0; - xen_rr.rid = allocate_reserved_rid(); - xen_rr.ps = PAGE_SHIFT; - - printf("initialized xen_rr.rid=0x%lx\n", xen_rr.rid); -} - /************************************* Region Block setup/management *************************************/ @@ -187,34 +173,6 @@ int deallocate_rid_range(struct domain *d) } -// This function is purely for performance... apparently scrambling -// bits in the region id makes for better hashing, which means better -// use of the VHPT, which means better performance -// Note that the only time a RID should be mangled is when it is stored in -// a region register; anytime it is "viewable" outside of this module, -// it should be unmangled - -// NOTE: this function is also implemented in assembly code in hyper_set_rr!! -// Must ensure these two remain consistent! -static inline unsigned long -vmMangleRID(unsigned long RIDVal) -{ - union bits64 { unsigned char bytes[4]; unsigned long uint; }; - - union bits64 t; - unsigned char tmp; - - t.uint = RIDVal; - tmp = t.bytes[1]; - t.bytes[1] = t.bytes[3]; - t.bytes[3] = tmp; - - return t.uint; -} - -// since vmMangleRID is symmetric, use it for unmangling also -#define vmUnmangleRID(x) vmMangleRID(x) - static inline void set_rr_no_srlz(unsigned long rr, unsigned long rrval) { diff --git a/xen/arch/ia64/vcpu.c b/xen/arch/ia64/vcpu.c index ed22389ab5..6ed6dc5ddb 100644 --- a/xen/arch/ia64/vcpu.c +++ b/xen/arch/ia64/vcpu.c @@ -14,9 +14,7 @@ #include #include #include -#ifdef CONFIG_VTI #include -#endif // CONFIG_VTI typedef union { struct ia64_psr ia64_psr; diff --git a/xen/arch/ia64/vmmu.c b/xen/arch/ia64/vmmu.c index d48e617191..4351065adf 100644 --- a/xen/arch/ia64/vmmu.c +++ b/xen/arch/ia64/vmmu.c @@ -81,10 +81,10 @@ u64 get_mfn(domid_t domid, u64 gpfn, u64 pages) /* * The VRN bits of va stand for which rr to get. */ -rr_t vmmu_get_rr(VCPU *vcpu, u64 va) +ia64_rr vmmu_get_rr(VCPU *vcpu, u64 va) { - rr_t vrr; - vmx_vcpu_get_rr(vcpu, va, &vrr.value); + ia64_rr vrr; + vmx_vcpu_get_rr(vcpu, va, &vrr.rrval); return vrr; } @@ -240,7 +240,7 @@ void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb) u64 saved_itir, saved_ifa, saved_rr; u64 pages; thash_data_t mtlb; - rr_t vrr; + ia64_rr vrr; unsigned int cl = tlb->cl; mtlb.ifa = tlb->vadr; @@ -264,7 +264,7 @@ void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb) /* Only access memory stack which is mapped by TR, * after rr is switched. */ - ia64_set_rr(mtlb.ifa, vmx_vrrtomrr(d, vrr.value)); + ia64_set_rr(mtlb.ifa, vmx_vrrtomrr(d, vrr.rrval)); ia64_srlz_d(); if ( cl == ISIDE_TLB ) { ia64_itci(mtlb.page_flags); @@ -287,12 +287,12 @@ u64 machine_thash(PTA pta, u64 va, u64 rid, u64 ps) u64 hash_addr, tag; unsigned long psr; struct vcpu *v = current; - rr_t vrr; + ia64_rr vrr; saved_pta = ia64_getreg(_IA64_REG_CR_PTA); saved_rr0 = ia64_get_rr(0); - vrr.value = saved_rr0; + vrr.rrval = saved_rr0; vrr.rid = rid; vrr.ps = ps; @@ -300,7 +300,7 @@ u64 machine_thash(PTA pta, u64 va, u64 rid, u64 ps) // TODO: Set to enforce lazy mode local_irq_save(psr); ia64_setreg(_IA64_REG_CR_PTA, pta.val); - ia64_set_rr(0, vmx_vrrtomrr(v, vrr.value)); + ia64_set_rr(0, vmx_vrrtomrr(v, vrr.rrval)); ia64_srlz_d(); hash_addr = ia64_thash(va); @@ -318,19 +318,19 @@ u64 machine_ttag(PTA pta, u64 va, u64 rid, u64 ps) u64 hash_addr, tag; u64 psr; struct vcpu *v = current; - rr_t vrr; + ia64_rr vrr; // TODO: Set to enforce lazy mode saved_pta = ia64_getreg(_IA64_REG_CR_PTA); saved_rr0 = ia64_get_rr(0); - vrr.value = saved_rr0; + vrr.rrval = saved_rr0; vrr.rid = rid; vrr.ps = ps; va = (va << 3) >> 3; // set VRN to 0. local_irq_save(psr); ia64_setreg(_IA64_REG_CR_PTA, pta.val); - ia64_set_rr(0, vmx_vrrtomrr(v, vrr.value)); + ia64_set_rr(0, vmx_vrrtomrr(v, vrr.rrval)); ia64_srlz_d(); tag = ia64_ttag(va); @@ -354,15 +354,15 @@ void machine_tlb_purge(u64 rid, u64 va, u64 ps) { u64 saved_rr0; u64 psr; - rr_t vrr; + ia64_rr vrr; va = (va << 3) >> 3; // set VRN to 0. saved_rr0 = ia64_get_rr(0); - vrr.value = saved_rr0; + vrr.rrval = saved_rr0; vrr.rid = rid; vrr.ps = ps; local_irq_save(psr); - ia64_set_rr( 0, vmx_vrrtomrr(current,vrr.value) ); + ia64_set_rr( 0, vmx_vrrtomrr(current,vrr.rrval) ); ia64_srlz_d(); ia64_ptcl(va, ps << 2); ia64_set_rr( 0, saved_rr0 ); @@ -421,14 +421,14 @@ fetch_code(VCPU *vcpu, u64 gip, u64 *code) u64 gpip; // guest physical IP u64 mpa; thash_data_t *tlb; - rr_t vrr; + ia64_rr vrr; u64 mfn; if ( !(VMX_VPD(vcpu, vpsr) & IA64_PSR_IT) ) { // I-side physical mode gpip = gip; } else { - vmx_vcpu_get_rr(vcpu, gip, &vrr.value); + vmx_vcpu_get_rr(vcpu, gip, &vrr.rrval); tlb = vtlb_lookup_ex (vmx_vcpu_get_vtlb(vcpu), vrr.rid, gip, ISIDE_TLB ); if ( tlb == NULL ) panic("No entry found in ITLB\n"); @@ -448,7 +448,7 @@ IA64FAULT vmx_vcpu_itc_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa) thash_data_t data, *ovl; thash_cb_t *hcb; search_section_t sections; - rr_t vrr; + ia64_rr vrr; hcb = vmx_vcpu_get_vtlb(vcpu); data.page_flags=pte & ~PAGE_FLAGS_RV_MASK; @@ -481,7 +481,7 @@ IA64FAULT vmx_vcpu_itc_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa) thash_data_t data, *ovl; thash_cb_t *hcb; search_section_t sections; - rr_t vrr; + ia64_rr vrr; hcb = vmx_vcpu_get_vtlb(vcpu); data.page_flags=pte & ~PAGE_FLAGS_RV_MASK; @@ -511,7 +511,7 @@ int vmx_lock_guest_dtc (VCPU *vcpu, UINT64 va, int lock) { thash_cb_t *hcb; - rr_t vrr; + ia64_rr vrr; u64 preferred_size; vmx_vcpu_get_rr(vcpu, va, &vrr); @@ -527,7 +527,7 @@ IA64FAULT vmx_vcpu_itr_i(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa, UINT64 thash_data_t data, *ovl; thash_cb_t *hcb; search_section_t sections; - rr_t vrr; + ia64_rr vrr; hcb = vmx_vcpu_get_vtlb(vcpu); data.page_flags=pte & ~PAGE_FLAGS_RV_MASK; @@ -559,7 +559,7 @@ IA64FAULT vmx_vcpu_itr_d(VCPU *vcpu, UINT64 pte, UINT64 itir, UINT64 ifa, UINT64 thash_data_t data, *ovl; thash_cb_t *hcb; search_section_t sections; - rr_t vrr; + ia64_rr vrr; hcb = vmx_vcpu_get_vtlb(vcpu); diff --git a/xen/arch/ia64/vmx_init.c b/xen/arch/ia64/vmx_init.c index d313b1b4d9..5f41ca686c 100644 --- a/xen/arch/ia64/vmx_init.c +++ b/xen/arch/ia64/vmx_init.c @@ -22,6 +22,9 @@ */ /* + * 05/08/16 Kun tian (Kevin Tian) : + * Disable doubling mapping + * * 05/03/23 Kun Tian (Kevin Tian) : * Simplied design in first step: * - One virtual environment @@ -39,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -126,8 +130,43 @@ vmx_init_env(void) else ASSERT(tmp_base != __vsa_base); +#ifdef XEN_DBL_MAPPING /* Init stub for rr7 switch */ vmx_init_double_mapping_stub(); +#endif +} + +void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c) +{ + struct domain *d = v->domain; + shared_iopage_t *sp; + + ASSERT(d != dom0); /* only for non-privileged vti domain */ + d->arch.vmx_platform.shared_page_va = __va(c->share_io_pg); + sp = get_sp(d); + memset((char *)sp,0,PAGE_SIZE); + /* FIXME: temp due to old CP */ + sp->sp_global.eport = 2; +#ifdef V_IOSAPIC_READY + sp->vcpu_number = 1; +#endif + /* TEMP */ + d->arch.vmx_platform.pib_base = 0xfee00000UL; + + /* One more step to enable interrupt assist */ + set_bit(ARCH_VMX_INTR_ASSIST, &v->arch.arch_vmx.flags); + /* Only open one port for I/O and interrupt emulation */ + if (v == d->vcpu[0]) { + memset(&d->shared_info->evtchn_mask[0], 0xff, + sizeof(d->shared_info->evtchn_mask)); + clear_bit(iopacket_port(d), &d->shared_info->evtchn_mask[0]); + } + + /* FIXME: only support PMT table continuously by far */ + d->arch.pmt = __va(c->pt_base); + d->arch.max_pfn = c->pt_max_pfn; + + vmx_final_setup_domain(d); } typedef union { @@ -171,7 +210,7 @@ static vpd_t *alloc_vpd(void) } - +#ifdef CONFIG_VTI /* * Create a VP on intialized VMX environment. */ @@ -190,6 +229,7 @@ vmx_create_vp(struct vcpu *v) panic("ia64_pal_vp_create failed. \n"); } +#ifdef XEN_DBL_MAPPING void vmx_init_double_mapping_stub(void) { u64 base, psr; @@ -206,6 +246,7 @@ void vmx_init_double_mapping_stub(void) ia64_srlz_i(); printk("Add TR mapping for rr7 switch stub, with physical: 0x%lx\n", (u64)(__pa(base))); } +#endif /* Other non-context related tasks can be done in context switch */ void @@ -219,12 +260,14 @@ vmx_save_state(struct vcpu *v) if (status != PAL_STATUS_SUCCESS) panic("Save vp status failed\n"); +#ifdef XEN_DBL_MAPPING /* FIXME: Do we really need purge double mapping for old vcpu? * Since rid is completely different between prev and next, * it's not overlap and thus no MCA possible... */ dom_rr7 = vmx_vrrtomrr(v, VMX(v, vrr[7])); vmx_purge_double_mapping(dom_rr7, KERNEL_START, (u64)v->arch.vtlb->ts->vhpt->hash); +#endif /* Need to save KR when domain switch, though HV itself doesn;t * use them. @@ -252,12 +295,14 @@ vmx_load_state(struct vcpu *v) if (status != PAL_STATUS_SUCCESS) panic("Restore vp status failed\n"); +#ifdef XEN_DBL_MAPPING dom_rr7 = vmx_vrrtomrr(v, VMX(v, vrr[7])); pte_xen = pte_val(pfn_pte((xen_pstart >> PAGE_SHIFT), PAGE_KERNEL)); pte_vhpt = pte_val(pfn_pte((__pa(v->arch.vtlb->ts->vhpt->hash) >> PAGE_SHIFT), PAGE_KERNEL)); vmx_insert_double_mapping(dom_rr7, KERNEL_START, (u64)v->arch.vtlb->ts->vhpt->hash, pte_xen, pte_vhpt); +#endif ia64_set_kr(0, v->arch.arch_vmx.vkr[0]); ia64_set_kr(1, v->arch.arch_vmx.vkr[1]); @@ -271,6 +316,7 @@ vmx_load_state(struct vcpu *v) * anchored in vcpu */ } +#ifdef XEN_DBL_MAPPING /* Purge old double mapping and insert new one, due to rr7 change */ void vmx_change_double_mapping(struct vcpu *v, u64 oldrr7, u64 newrr7) @@ -287,6 +333,8 @@ vmx_change_double_mapping(struct vcpu *v, u64 oldrr7, u64 newrr7) vhpt_base, pte_xen, pte_vhpt); } +#endif // XEN_DBL_MAPPING +#endif // CONFIG_VTI /* * Initialize VMX envirenment for guest. Only the 1st vp/vcpu @@ -307,12 +355,21 @@ vmx_final_setup_domain(struct domain *d) v->arch.arch_vmx.vpd = vpd; vpd->virt_env_vaddr = vm_buffer; +#ifdef CONFIG_VTI /* v->arch.schedule_tail = arch_vmx_do_launch; */ vmx_create_vp(v); /* Set this ed to be vmx */ set_bit(ARCH_VMX_VMCS_LOADED, &v->arch.arch_vmx.flags); + /* Physical mode emulation initialization, including + * emulation ID allcation and related memory request + */ + physical_mode_init(v); + + vlsapic_reset(v); + vtm_init(v); +#endif + /* Other vmx specific initialization work */ } - diff --git a/xen/arch/ia64/vmx_phy_mode.c b/xen/arch/ia64/vmx_phy_mode.c index 16c1a457b5..d7a51c9f60 100644 --- a/xen/arch/ia64/vmx_phy_mode.c +++ b/xen/arch/ia64/vmx_phy_mode.c @@ -104,22 +104,8 @@ physical_mode_init(VCPU *vcpu) UINT64 psr; struct domain * d = vcpu->domain; - vcpu->domain->arch.emul_phy_rr0.rid = XEN_RR7_RID+((d->domain_id)<<3); - /* FIXME */ -#if 0 - vcpu->domain->arch.emul_phy_rr0.ps = 28; /* set page size to 256M */ -#endif - vcpu->domain->arch.emul_phy_rr0.ps = EMUL_PHY_PAGE_SHIFT; /* set page size to 4k */ - vcpu->domain->arch.emul_phy_rr0.ve = 1; /* enable VHPT walker on this region */ - - vcpu->domain->arch.emul_phy_rr4.rid = XEN_RR7_RID + ((d->domain_id)<<3) + 4; - vcpu->domain->arch.emul_phy_rr4.ps = EMUL_PHY_PAGE_SHIFT; /* set page size to 4k */ - vcpu->domain->arch.emul_phy_rr4.ve = 1; /* enable VHPT walker on this region */ - vcpu->arch.old_rsc = 0; vcpu->arch.mode_flags = GUEST_IN_PHY; - - return; } extern u64 get_mfn(domid_t domid, u64 gpfn, u64 pages); @@ -246,19 +232,23 @@ void vmx_load_all_rr(VCPU *vcpu) { unsigned long psr; + ia64_rr phy_rr; psr = ia64_clear_ic(); + phy_rr.ps = EMUL_PHY_PAGE_SHIFT; + phy_rr.ve = 1; + /* WARNING: not allow co-exist of both virtual mode and physical * mode in same region */ if (is_physical_mode(vcpu)) { if (vcpu->arch.mode_flags & GUEST_PHY_EMUL) panic("Unexpected domain switch in phy emul\n"); - ia64_set_rr((VRN0 << VRN_SHIFT), - vcpu->domain->arch.emul_phy_rr0.rrval); - ia64_set_rr((VRN4 << VRN_SHIFT), - vcpu->domain->arch.emul_phy_rr4.rrval); + phy_rr.rid = vcpu->domain->arch.metaphysical_rr0; + ia64_set_rr((VRN0 << VRN_SHIFT), phy_rr.rrval); + phy_rr.rid = vcpu->domain->arch.metaphysical_rr4; + ia64_set_rr((VRN4 << VRN_SHIFT), phy_rr.rrval); } else { ia64_set_rr((VRN0 << VRN_SHIFT), vmx_vrrtomrr(vcpu, VMX(vcpu, vrr[VRN0]))); @@ -284,13 +274,18 @@ void switch_to_physical_rid(VCPU *vcpu) { UINT64 psr; + ia64_rr phy_rr; - /* Save original virtual mode rr[0] and rr[4] */ + phy_rr.ps = EMUL_PHY_PAGE_SHIFT; + phy_rr.ve = 1; + /* Save original virtual mode rr[0] and rr[4] */ psr=ia64_clear_ic(); - ia64_set_rr(VRN0<domain->arch.emul_phy_rr0.rrval); + phy_rr.rid = vcpu->domain->arch.metaphysical_rr0; + ia64_set_rr(VRN0<domain->arch.emul_phy_rr4.rrval); + phy_rr.rid = vcpu->domain->arch.metaphysical_rr4; + ia64_set_rr(VRN4<ht == THASH_VHPT ); vrr = (hcb->get_rr_fn)(hcb->vcpu,va); @@ -361,7 +361,7 @@ void vtlb_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va) { thash_data_t *hash_table, *cch; int flag; - rr_t vrr; + ia64_rr vrr; u64 gppn; u64 ppns, ppne; @@ -397,7 +397,7 @@ void vtlb_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va) static void vhpt_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va) { thash_data_t *hash_table, *cch; - rr_t vrr; + ia64_rr vrr; hash_table = (hcb->hash_func)(hcb->pta, va, entry->rid, entry->ps); @@ -425,7 +425,7 @@ static void vhpt_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va) void thash_insert(thash_cb_t *hcb, thash_data_t *entry, u64 va) { thash_data_t *hash_table; - rr_t vrr; + ia64_rr vrr; vrr = (hcb->get_rr_fn)(hcb->vcpu,entry->vadr); if ( entry->ps != vrr.ps && entry->tc ) { @@ -556,7 +556,7 @@ static thash_data_t *vtlb_find_overlap(thash_cb_t *hcb, thash_data_t *hash_table; thash_internal_t *priv = &hcb->priv; u64 tag; - rr_t vrr; + ia64_rr vrr; priv->_curva = va & ~(size-1); priv->_eva = priv->_curva + size; @@ -580,7 +580,7 @@ static thash_data_t *vhpt_find_overlap(thash_cb_t *hcb, thash_data_t *hash_table; thash_internal_t *priv = &hcb->priv; u64 tag; - rr_t vrr; + ia64_rr vrr; priv->_curva = va & ~(size-1); priv->_eva = priv->_curva + size; @@ -633,7 +633,7 @@ static thash_data_t *vtlb_next_overlap(thash_cb_t *hcb) thash_data_t *ovl; thash_internal_t *priv = &hcb->priv; u64 addr,rr_psize; - rr_t vrr; + ia64_rr vrr; if ( priv->s_sect.tr ) { ovl = vtr_find_next_overlap (hcb); @@ -665,7 +665,7 @@ static thash_data_t *vhpt_next_overlap(thash_cb_t *hcb) thash_data_t *ovl; thash_internal_t *priv = &hcb->priv; u64 addr,rr_psize; - rr_t vrr; + ia64_rr vrr; vrr = (hcb->get_rr_fn)(hcb->vcpu,priv->_curva); rr_psize = PSIZE(vrr.ps); @@ -800,7 +800,7 @@ thash_data_t *vtlb_lookup_ex(thash_cb_t *hcb, { thash_data_t *hash_table, *cch; u64 tag; - rr_t vrr; + ia64_rr vrr; ASSERT ( hcb->ht == THASH_VTLB ); diff --git a/xen/arch/ia64/xenmem.c b/xen/arch/ia64/xenmem.c index 35519e0cb8..42b83d97a2 100644 --- a/xen/arch/ia64/xenmem.c +++ b/xen/arch/ia64/xenmem.c @@ -30,8 +30,8 @@ static unsigned long num_dma_physpages; */ #ifdef CONFIG_VTI unsigned long *mpt_table; -unsigned long *mpt_table_size; -#endif +unsigned long mpt_table_size; +#endif // CONFIG_VTI void paging_init (void) @@ -53,21 +53,6 @@ paging_init (void) printk("machine to physical table: 0x%lx\n", (u64)mpt_table); memset(mpt_table, INVALID_M2P_ENTRY, mpt_table_size); - - /* Any more setup here? On VMX enabled platform, - * there's no need to keep guest linear pg table, - * and read only mpt table. MAP cache is not used - * in this stage, and later it will be in region 5. - * IO remap is in region 6 with identity mapping. - */ - /* HV_tlb_init(); */ - -#else // CONFIG_VTI - - /* Allocate and map the machine-to-phys table */ - if ((pg = alloc_domheap_pages(NULL, 10, 0)) == NULL) - panic("Not enough memory to bootstrap Xen.\n"); - memset(page_to_virt(pg), 0x55, 16UL << 20); #endif // CONFIG_VTI /* Other mapping setup */ diff --git a/xen/arch/ia64/xensetup.c b/xen/arch/ia64/xensetup.c index 7bcc2e7b82..3c07df67f9 100644 --- a/xen/arch/ia64/xensetup.c +++ b/xen/arch/ia64/xensetup.c @@ -181,11 +181,6 @@ void start_kernel(void) printk("xen image pstart: 0x%lx, xenheap pend: 0x%lx\n", xen_pstart, xenheap_phys_end); -#ifdef CONFIG_VTI - /* If we want to enable vhpt for all regions, related initialization - * for HV TLB must be done earlier before first TLB miss - */ -#endif // CONFIG_VTI /* Find next hole */ firsthole_start = 0; efi_memmap_walk(xen_find_first_hole, &firsthole_start); diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index d3acb89fc6..30583ec833 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -3,39 +3,28 @@ #include #include -#ifdef CONFIG_VTI #include #include #include #include #include -#endif // CONFIG_VTI #include extern void arch_do_createdomain(struct vcpu *); extern void domain_relinquish_resources(struct domain *); -#ifdef CONFIG_VTI -struct trap_bounce { - // TO add, FIXME Eddie -}; - -#define PMT_SIZE (32L*1024*1024) // 32M for PMT -#endif // CONFIG_VTI - struct arch_domain { struct mm_struct *active_mm; struct mm_struct *mm; int metaphysical_rr0; + int metaphysical_rr4; int starting_rid; /* first RID assigned to domain */ int ending_rid; /* one beyond highest RID assigned to domain */ int rid_bits; /* number of virtual rid bits (default: 18) */ int breakimm; -#ifdef CONFIG_VTI + int imp_va_msb; - ia64_rr emul_phy_rr0; - ia64_rr emul_phy_rr4; unsigned long *pmt; /* physical to machine table */ /* * max_pfn is the maximum page frame in guest physical space, including @@ -44,7 +33,7 @@ struct arch_domain { */ unsigned long max_pfn; struct virutal_platform_def vmx_platform; -#endif //CONFIG_VTI + u64 xen_vastart; u64 xen_vaend; u64 shared_info_va; @@ -78,15 +67,15 @@ struct arch_vcpu { #endif void *regs; /* temporary until find a better way to do privops */ int metaphysical_rr0; // from arch_domain (so is pinned) + int metaphysical_rr4; // from arch_domain (so is pinned) int metaphysical_saved_rr0; // from arch_domain (so is pinned) + int metaphysical_saved_rr4; // from arch_domain (so is pinned) int breakimm; // from arch_domain (so is pinned) int starting_rid; /* first RID assigned to domain */ int ending_rid; /* one beyond highest RID assigned to domain */ struct mm_struct *active_mm; struct thread_struct _thread; // this must be last -#ifdef CONFIG_VTI - void (*schedule_tail) (struct vcpu *); - struct trap_bounce trap_bounce; + thash_cb_t *vtlb; char irq_new_pending; char irq_new_condition; // vpsr.i/vtpr change, check for pending VHPI @@ -94,9 +83,7 @@ struct arch_vcpu { //for phycial emulation unsigned long old_rsc; int mode_flags; - struct arch_vmx_struct arch_vmx; /* Virtual Machine Extensions */ -#endif // CONFIG_VTI }; #define active_mm arch.active_mm diff --git a/xen/include/asm-ia64/linux-xen/asm/pal.h b/xen/include/asm-ia64/linux-xen/asm/pal.h index 55612c1846..ebebcf584b 100644 --- a/xen/include/asm-ia64/linux-xen/asm/pal.h +++ b/xen/include/asm-ia64/linux-xen/asm/pal.h @@ -1559,9 +1559,7 @@ ia64_pal_prefetch_visibility (s64 trans_type) return iprv.status; } -#ifdef CONFIG_VTI #include -#endif // CONFIG_VTI #endif /* __ASSEMBLY__ */ #endif /* _ASM_IA64_PAL_H */ diff --git a/xen/include/asm-ia64/mmu_context.h b/xen/include/asm-ia64/mmu_context.h index 4f51c65756..a08b5fd100 100644 --- a/xen/include/asm-ia64/mmu_context.h +++ b/xen/include/asm-ia64/mmu_context.h @@ -2,11 +2,7 @@ #define __ASM_MMU_CONTEXT_H //dummy file to resolve non-arch-indep include #ifdef XEN -#ifndef CONFIG_VTI #define IA64_REGION_ID_KERNEL 0 -#else // CONFIG_VTI -#define IA64_REGION_ID_KERNEL 0x1e0000 /* Start from all 1 in highest 4 bits */ -#endif // CONFIG_VTI #define ia64_rid(ctx,addr) (((ctx) << 3) | (addr >> 61)) #ifndef __ASSEMBLY__ diff --git a/xen/include/asm-ia64/privop.h b/xen/include/asm-ia64/privop.h index 3e0bf5e213..49c8bd9f11 100644 --- a/xen/include/asm-ia64/privop.h +++ b/xen/include/asm-ia64/privop.h @@ -133,7 +133,6 @@ typedef union U_INST64_M46 { struct { unsigned long qp:6, r1:7, un7:7, r3:7, x6:6, x3:3, un1:1, major:4; }; } INST64_M46; -#ifdef CONFIG_VTI typedef union U_INST64_M47 { IA64_INST inst; struct { unsigned long qp:6, un14:14, r3:7, x6:6, x3:3, un1:1, major:4; }; @@ -169,8 +168,6 @@ typedef union U_INST64_M6 { struct { unsigned long qp:6, f1:7, un7:7, r3:7, x:1, hint:2, x6:6, m:1, major:4; }; } INST64_M6; -#endif // CONFIG_VTI - typedef union U_INST64 { IA64_INST inst; struct { unsigned long :37, major:4; } generic; @@ -182,14 +179,12 @@ typedef union U_INST64 { INST64_I26 I26; // mov register to ar (I unit) INST64_I27 I27; // mov immediate to ar (I unit) INST64_I28 I28; // mov from ar (I unit) -#ifdef CONFIG_VTI - INST64_M1 M1; // ld integer + INST64_M1 M1; // ld integer INST64_M2 M2; INST64_M3 M3; - INST64_M4 M4; // st integer + INST64_M4 M4; // st integer INST64_M5 M5; - INST64_M6 M6; // ldfd floating pointer -#endif // CONFIG_VTI + INST64_M6 M6; // ldfd floating pointer INST64_M28 M28; // purge translation cache entry INST64_M29 M29; // mov register to ar (M unit) INST64_M30 M30; // mov immediate to ar (M unit) @@ -204,9 +199,7 @@ typedef union U_INST64 { INST64_M44 M44; // set/reset system mask INST64_M45 M45; // translation purge INST64_M46 M46; // translation access (tpa,tak) -#ifdef CONFIG_VTI INST64_M47 M47; // purge translation entry -#endif // CONFIG_VTI } INST64; #define MASK_41 ((UINT64)0x1ffffffffff) diff --git a/xen/include/asm-ia64/regionreg.h b/xen/include/asm-ia64/regionreg.h index c942c242ba..ed35dcff35 100644 --- a/xen/include/asm-ia64/regionreg.h +++ b/xen/include/asm-ia64/regionreg.h @@ -1,12 +1,6 @@ #ifndef _REGIONREG_H_ #define _REGIONREG_H_ -#ifdef CONFIG_VTI -#define XEN_DEFAULT_RID 0xf00000 -#define DOMAIN_RID_SHIFT 20 -#define DOMAIN_RID_MASK (~(1U< +#include +#include +#include +#include //#define THASH_TLB_TR 0 //#define THASH_TLB_TC 1 @@ -152,7 +153,7 @@ typedef u64 *(TTAG_FN)(PTA pta, u64 va, u64 rid, u64 ps); typedef u64 *(GET_MFN_FN)(domid_t d, u64 gpfn, u64 pages); typedef void *(REM_NOTIFIER_FN)(struct hash_cb *hcb, thash_data_t *entry); typedef void (RECYCLE_FN)(struct hash_cb *hc, u64 para); -typedef rr_t (GET_RR_FN)(struct vcpu *vcpu, u64 reg); +typedef ia64_rr (GET_RR_FN)(struct vcpu *vcpu, u64 reg); typedef thash_data_t *(FIND_OVERLAP_FN)(struct thash_cb *hcb, u64 va, u64 ps, int rid, char cl, search_section_t s_sect); typedef thash_data_t *(FIND_NEXT_OVL_FN)(struct thash_cb *hcb); @@ -329,7 +330,7 @@ extern u64 machine_ttag(PTA pta, u64 va, u64 rid, u64 ps); extern u64 machine_thash(PTA pta, u64 va, u64 rid, u64 ps); extern void purge_machine_tc_by_domid(domid_t domid); extern void machine_tlb_insert(struct vcpu *d, thash_data_t *tlb); -extern rr_t vmmu_get_rr(struct vcpu *vcpu, u64 va); +extern ia64_rr vmmu_get_rr(struct vcpu *vcpu, u64 va); extern thash_cb_t *init_domain_tlb(struct vcpu *d); #define VTLB_DEBUG diff --git a/xen/include/asm-ia64/vmx.h b/xen/include/asm-ia64/vmx.h index 82bc5c1db8..c740045bf7 100644 --- a/xen/include/asm-ia64/vmx.h +++ b/xen/include/asm-ia64/vmx.h @@ -32,9 +32,12 @@ extern void vmx_final_setup_domain(struct domain *d); extern void vmx_init_double_mapping_stub(void); extern void vmx_save_state(struct vcpu *v); extern void vmx_load_state(struct vcpu *v); +extern void vmx_setup_platform(struct vcpu *v, struct vcpu_guest_context *c); +#ifdef XEN_DBL_MAPPING extern vmx_insert_double_mapping(u64,u64,u64,u64,u64); extern void vmx_purge_double_mapping(u64, u64, u64); extern void vmx_change_double_mapping(struct vcpu *v, u64 oldrr7, u64 newrr7); +#endif extern void vmx_wait_io(void); extern void vmx_io_assist(struct vcpu *v); diff --git a/xen/include/asm-ia64/vmx_vcpu.h b/xen/include/asm-ia64/vmx_vcpu.h index 327cccb1d3..f1c7dbc0ad 100644 --- a/xen/include/asm-ia64/vmx_vcpu.h +++ b/xen/include/asm-ia64/vmx_vcpu.h @@ -308,7 +308,9 @@ vmx_vcpu_set_itm(VCPU *vcpu, u64 val) vtm=&(vcpu->arch.arch_vmx.vtm); VPD_CR(vcpu,itm)=val; +#ifdef CONFIG_VTI vtm_interruption_update(vcpu, vtm); +#endif return IA64_NO_FAULT; } static inline @@ -414,7 +416,9 @@ static inline IA64FAULT vmx_vcpu_set_eoi(VCPU *vcpu, u64 val) { +#ifdef CONFIG_VTI guest_write_eoi(vcpu); +#endif return IA64_NO_FAULT; } @@ -424,7 +428,9 @@ vmx_vcpu_set_itv(VCPU *vcpu, u64 val) { VPD_CR(vcpu,itv)=val; +#ifdef CONFIG_VTI vtm_set_itv(vcpu); +#endif return IA64_NO_FAULT; } static inline @@ -465,13 +471,17 @@ vmx_vcpu_set_lrr1(VCPU *vcpu, u64 val) static inline IA64FAULT vmx_vcpu_set_itc(VCPU *vcpu, UINT64 val) { +#ifdef CONFIG_VTI vtm_set_itc(vcpu, val); +#endif return IA64_NO_FAULT; } static inline IA64FAULT vmx_vcpu_get_itc(VCPU *vcpu,UINT64 *val) { +#ifdef CONFIG_VTI *val = vtm_get_itc(vcpu); +#endif return IA64_NO_FAULT; } static inline @@ -584,15 +594,22 @@ IA64FAULT vmx_vcpu_bsw1(VCPU *vcpu) return (IA64_NO_FAULT); } +/* Another hash performance algorithm */ #define redistribute_rid(rid) (((rid) & ~0xffff) | (((rid) << 8) & 0xff00) | (((rid) >> 8) & 0xff)) static inline unsigned long -vmx_vrrtomrr(VCPU *vcpu,unsigned long val) +vmx_vrrtomrr(VCPU *v, unsigned long val) { ia64_rr rr; u64 rid; + rr.rrval=val; + rr.rid = vmMangleRID(v->arch.starting_rid + rr.rid); +/* Disable this rid allocation algorithm for now */ +#if 0 rid=(((u64)vcpu->domain->domain_id)<