[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] 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:
# HG changeset patch # User fred@xxxxxxxxxxxxxxxxxxxxx # Node ID 1ec2225aa8c696ca4e96e0fc27b4eafe36a9633f # Parent 97675c2dbb40f914a3b891e83fd5d7a40590e8b2 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 <kevin.tian@xxxxxxxxx> diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/Makefile --- a/xen/arch/ia64/Makefile Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/Makefile Sat Aug 20 05:19:39 2005 @@ -14,8 +14,11 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/domain.c --- a/xen/arch/ia64/domain.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/domain.c Sat Aug 20 05:19:39 2005 @@ -38,25 +38,17 @@ #include <asm/vcpu.h> /* for function declarations */ #include <public/arch-ia64.h> -#ifdef CONFIG_VTI #include <asm/vmx.h> #include <asm/vmx_vcpu.h> #include <asm/vmx_vpd.h> #include <asm/pal.h> #include <public/io/ioreq.h> -#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 @@ 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 @@ 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 @@ return -ENOMEM; } } -#endif // CONFIG_VTI void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) { @@ -312,16 +264,28 @@ 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 @@ 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; - - v->domain->shared_info->arch = c->shared; + d->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 @@ 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 @@ 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 @@ 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)) { +#ifdef CONFIG_VTI vmx_init_all_rr(v); - } else - init_all_rr(v); - - if (VMX_DOMAIN(v)) { - if (d == dom0) { + 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 @@ } #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 @@ -959,182 +768,12 @@ 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<<PAGE_SHIFT)>>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, - char *cmdline) -{ char *dst; int i, rc; 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 @@ 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 @@ 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 @@ 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,13 +873,42 @@ 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. */ @@ -1257,14 +945,21 @@ #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 @@ return 0; } -#endif // CONFIG_VTI // FIXME: When dom0 can construct domains, this goes away (or is rewritten) int construct_domU(struct domain *d, diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/linux-xen/setup.c --- a/xen/arch/ia64/linux-xen/setup.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/linux-xen/setup.c Sat Aug 20 05:19:39 2005 @@ -51,9 +51,7 @@ #include <asm/smp.h> #include <asm/system.h> #include <asm/unistd.h> -#ifdef CONFIG_VTI #include <asm/vmx.h> -#endif // CONFIG_VTI #include <asm/io.h> #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE) @@ -402,9 +400,9 @@ 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 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/regionreg.c --- a/xen/arch/ia64/regionreg.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/regionreg.c Sat Aug 20 05:19:39 2005 @@ -29,9 +29,6 @@ #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 @@ // returns -1 if none available -unsigned long allocate_metaphysical_rr0(void) +unsigned long allocate_metaphysical_rr(void) { ia64_rr rrv; @@ -79,17 +76,6 @@ { // fix this when the increment allocation mechanism is fixed. 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); } /************************************* @@ -186,34 +172,6 @@ return 1; } - -// 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/vcpu.c --- a/xen/arch/ia64/vcpu.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/vcpu.c Sat Aug 20 05:19:39 2005 @@ -14,9 +14,7 @@ #include <asm/tlb.h> #include <asm/processor.h> #include <asm/delay.h> -#ifdef CONFIG_VTI #include <asm/vmx_vcpu.h> -#endif // CONFIG_VTI typedef union { struct ia64_psr ia64_psr; diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/vmmu.c --- a/xen/arch/ia64/vmmu.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/vmmu.c Sat Aug 20 05:19:39 2005 @@ -81,10 +81,10 @@ /* * The VRN bits of va stand for which rr to get. */ -rr_t vmmu_get_rr(VCPU *vcpu, u64 va) -{ - rr_t vrr; - vmx_vcpu_get_rr(vcpu, va, &vrr.value); +ia64_rr vmmu_get_rr(VCPU *vcpu, u64 va) +{ + ia64_rr vrr; + vmx_vcpu_get_rr(vcpu, va, &vrr.rrval); return vrr; } @@ -240,7 +240,7 @@ 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 @@ /* 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 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 @@ // 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 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 @@ { 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 @@ 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 @@ 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 @@ 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 @@ { thash_cb_t *hcb; - rr_t vrr; + ia64_rr vrr; u64 preferred_size; vmx_vcpu_get_rr(vcpu, va, &vrr); @@ -527,7 +527,7 @@ 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 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/vmx_init.c --- a/xen/arch/ia64/vmx_init.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/vmx_init.c Sat Aug 20 05:19:39 2005 @@ -22,6 +22,9 @@ */ /* + * 05/08/16 Kun tian (Kevin Tian) <kevin.tian@xxxxxxxxx>: + * Disable doubling mapping + * * 05/03/23 Kun Tian (Kevin Tian) <kevin.tian@xxxxxxxxx>: * Simplied design in first step: * - One virtual environment @@ -39,6 +42,7 @@ #include <xen/lib.h> #include <asm/vmmu.h> #include <public/arch-ia64.h> +#include <public/io/ioreq.h> #include <asm/vmx_phy_mode.h> #include <asm/processor.h> #include <asm/vmx.h> @@ -126,8 +130,43 @@ 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 @@ } - +#ifdef CONFIG_VTI /* * Create a VP on intialized VMX environment. */ @@ -190,6 +229,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ * 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 @@ 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 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/vmx_phy_mode.c --- a/xen/arch/ia64/vmx_phy_mode.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/vmx_phy_mode.c Sat Aug 20 05:19:39 2005 @@ -104,22 +104,8 @@ 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,8 +232,12 @@ 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 @@ -255,10 +245,10 @@ 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 @@ switch_to_physical_rid(VCPU *vcpu) { UINT64 psr; + ia64_rr phy_rr; + + 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<<VRN_SHIFT, vcpu->domain->arch.emul_phy_rr0.rrval); + phy_rr.rid = vcpu->domain->arch.metaphysical_rr0; + ia64_set_rr(VRN0<<VRN_SHIFT, phy_rr.rrval); ia64_srlz_d(); - ia64_set_rr(VRN4<<VRN_SHIFT, vcpu->domain->arch.emul_phy_rr4.rrval); + phy_rr.rid = vcpu->domain->arch.metaphysical_rr4; + ia64_set_rr(VRN4<<VRN_SHIFT, phy_rr.rrval); ia64_srlz_d(); ia64_set_psr(psr); diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/vmx_vcpu.c --- a/xen/arch/ia64/vmx_vcpu.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/vmx_vcpu.c Sat Aug 20 05:19:39 2005 @@ -234,9 +234,11 @@ case VRN7: VMX(vcpu,mrr7)=vmx_vrrtomrr(vcpu,val); /* Change double mapping for this domain */ +#ifdef XEN_DBL_MAPPING vmx_change_double_mapping(vcpu, vmx_vrrtomrr(vcpu,oldrr.rrval), vmx_vrrtomrr(vcpu,newrr.rrval)); +#endif break; default: ia64_set_rr(reg,vmx_vrrtomrr(vcpu,val)); diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/vtlb.c --- a/xen/arch/ia64/vtlb.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/vtlb.c Sat Aug 20 05:19:39 2005 @@ -283,7 +283,7 @@ thash_data_t *vhpt) { u64 pages,mfn; - rr_t vrr; + ia64_rr vrr; ASSERT ( hcb->ht == THASH_VHPT ); vrr = (hcb->get_rr_fn)(hcb->vcpu,va); @@ -361,7 +361,7 @@ { thash_data_t *hash_table, *cch; int flag; - rr_t vrr; + ia64_rr vrr; u64 gppn; u64 ppns, ppne; @@ -397,7 +397,7 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 *hash_table, *cch; u64 tag; - rr_t vrr; + ia64_rr vrr; ASSERT ( hcb->ht == THASH_VTLB ); diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/xenmem.c --- a/xen/arch/ia64/xenmem.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/xenmem.c Sat Aug 20 05:19:39 2005 @@ -30,8 +30,8 @@ */ #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 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/arch/ia64/xensetup.c --- a/xen/arch/ia64/xensetup.c Sat Aug 20 04:45:43 2005 +++ b/xen/arch/ia64/xensetup.c Sat Aug 20 05:19:39 2005 @@ -181,11 +181,6 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/domain.h --- a/xen/include/asm-ia64/domain.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/domain.h Sat Aug 20 05:19:39 2005 @@ -3,39 +3,28 @@ #include <linux/thread_info.h> #include <asm/tlb.h> -#ifdef CONFIG_VTI #include <asm/vmx_vpd.h> #include <asm/vmmu.h> #include <asm/regionreg.h> #include <public/arch-ia64.h> #include <asm/vmx_platform.h> -#endif // CONFIG_VTI #include <xen/list.h> 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 @@ */ 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 @@ #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 @@ //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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/linux-xen/asm/pal.h --- a/xen/include/asm-ia64/linux-xen/asm/pal.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/linux-xen/asm/pal.h Sat Aug 20 05:19:39 2005 @@ -1559,9 +1559,7 @@ return iprv.status; } -#ifdef CONFIG_VTI #include <asm/vmx_pal.h> -#endif // CONFIG_VTI #endif /* __ASSEMBLY__ */ #endif /* _ASM_IA64_PAL_H */ diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/mmu_context.h --- a/xen/include/asm-ia64/mmu_context.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/mmu_context.h Sat Aug 20 05:19:39 2005 @@ -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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/privop.h --- a/xen/include/asm-ia64/privop.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/privop.h Sat Aug 20 05:19:39 2005 @@ -133,7 +133,6 @@ 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; }; @@ -168,8 +167,6 @@ IA64_INST inst; 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; @@ -182,14 +179,12 @@ 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 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/regionreg.h --- a/xen/include/asm-ia64/regionreg.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/regionreg.h Sat Aug 20 05:19:39 2005 @@ -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<<DOMAIN_RID_SHIFT -1)) -#else //CONFIG_VTI #define XEN_DEFAULT_RID 7 -#endif // CONFIG_VTI #define IA64_MIN_IMPL_RID_MSB 17 #define _REGION_ID(x) ({ia64_rr _v; _v.rrval = (long) (x); _v.rid;}) #define _REGION_PAGE_SIZE(x) ({ia64_rr _v; _v.rrval = (long) (x); _v.ps;}) @@ -42,4 +36,32 @@ int set_one_rr(unsigned long rr, unsigned long val); +// 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) + #endif /* !_REGIONREG_H_ */ diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/tlb.h --- a/xen/include/asm-ia64/tlb.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/tlb.h Sat Aug 20 05:19:39 2005 @@ -35,17 +35,4 @@ unsigned long rid; } TR_ENTRY; -#ifdef CONFIG_VTI -typedef union { - unsigned long value; - struct { - unsigned long ve : 1; - unsigned long rv1 : 1; - unsigned long ps : 6; - unsigned long rid : 24; - unsigned long rv2 : 32; - }; -} rr_t; -#endif // CONFIG_VTI - #endif diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/vmmu.h --- a/xen/include/asm-ia64/vmmu.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/vmmu.h Sat Aug 20 05:19:39 2005 @@ -23,10 +23,11 @@ #ifndef XEN_TLBthash_H #define XEN_TLBthash_H -#include "xen/config.h" -#include "xen/types.h" -#include "public/xen.h" -#include "asm/tlb.h" +#include <xen/config.h> +#include <xen/types.h> +#include <public/xen.h> +#include <asm/tlb.h> +#include <asm/regionreg.h> //#define THASH_TLB_TR 0 //#define THASH_TLB_TC 1 @@ -152,7 +153,7 @@ 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_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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/vmx.h --- a/xen/include/asm-ia64/vmx.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/vmx.h Sat Aug 20 05:19:39 2005 @@ -32,9 +32,12 @@ 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 -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/vmx_vcpu.h --- a/xen/include/asm-ia64/vmx_vcpu.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/vmx_vcpu.h Sat Aug 20 05:19:39 2005 @@ -308,7 +308,9 @@ 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 @@ 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 @@ { VPD_CR(vcpu,itv)=val; +#ifdef CONFIG_VTI vtm_set_itv(vcpu); +#endif return IA64_NO_FAULT; } static inline @@ -465,13 +471,17 @@ 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 @@ 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)<<DOMAIN_RID_SHIFT) + rr.rid; rr.rid = redistribute_rid(rid); +#endif + rr.ve=1; return rr.rrval; } diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/vmx_vpd.h --- a/xen/include/asm-ia64/vmx_vpd.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/vmx_vpd.h Sat Aug 20 05:19:39 2005 @@ -61,12 +61,6 @@ unsigned long lrr1; unsigned long rsv6[46]; } cr_t; - -void vmx_enter_scheduler(void); - -//FIXME: Map for LID to vcpu, Eddie -#define MAX_NUM_LPS (1UL<<16) -extern struct vcpu *lid_edt[MAX_NUM_LPS]; struct arch_vmx_struct { // struct virutal_platform_def vmx_platform; diff -r 97675c2dbb40 -r 1ec2225aa8c6 xen/include/asm-ia64/xenprocessor.h --- a/xen/include/asm-ia64/xenprocessor.h Sat Aug 20 04:45:43 2005 +++ b/xen/include/asm-ia64/xenprocessor.h Sat Aug 20 05:19:39 2005 @@ -50,16 +50,11 @@ __u64 ri : 2; __u64 ed : 1; __u64 bn : 1; -#ifdef CONFIG_VTI __u64 ia : 1; __u64 vm : 1; __u64 reserved5 : 17; -#else // CONFIG_VTI - __u64 reserved4 : 19; -#endif // CONFIG_VTI }; -#ifdef CONFIG_VTI /* vmx like above but expressed as bitfields for more efficient access: */ typedef union{ __u64 val; @@ -218,6 +213,4 @@ ret; \ }) -#endif // CONFIG_VTI - #endif // _ASM_IA64_XENPROCESSOR_H _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |