Date: Sun, 19 Oct 2008 01:27:40 +0000 (UTC) From: Kip Macy <kmacy@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r184040 - in head/sys/i386: include xen Message-ID: <200810190127.m9J1ReEj030526@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kmacy Date: Sun Oct 19 01:27:40 2008 New Revision: 184040 URL: http://svn.freebsd.org/changeset/base/184040 Log: - move gdt, ldt allocation to before KPT allocation - fix bugs where we would: - try to map the hypervisors address space - accidentally kick out an existing kernel mapping for some domain creation memory allocation sizes - accidentally skip a 2MB kernel mapping for some domain creation memory allocation sizes - don't rely on trapping in to xen to read rcr2, reference through vcpu - whitespace cleanups Modified: head/sys/i386/include/cpufunc.h head/sys/i386/xen/xen_machdep.c Modified: head/sys/i386/include/cpufunc.h ============================================================================== --- head/sys/i386/include/cpufunc.h Sun Oct 19 01:23:30 2008 (r184039) +++ head/sys/i386/include/cpufunc.h Sun Oct 19 01:27:40 2008 (r184040) @@ -45,6 +45,7 @@ #ifdef XEN extern void xen_cli(void); extern void xen_sti(void); +extern u_int xen_rcr2(void); extern void xen_load_cr3(u_int data); extern void xen_tlb_flush(void); extern void xen_invlpg(u_int addr); @@ -94,7 +95,7 @@ disable_intr(void) #ifdef XEN xen_cli(); #else - __asm __volatile("cli" : : : "memory"); + __asm __volatile("cli" : : : "memory"); #endif } @@ -119,7 +120,7 @@ enable_intr(void) { #ifdef XEN xen_sti(); -#else +#else __asm __volatile("sti"); #endif } @@ -423,6 +424,9 @@ rcr2(void) { u_int data; +#ifdef XEN + return (xen_rcr2()); +#endif __asm __volatile("movl %%cr2,%0" : "=r" (data)); return (data); } Modified: head/sys/i386/xen/xen_machdep.c ============================================================================== --- head/sys/i386/xen/xen_machdep.c Sun Oct 19 01:23:30 2008 (r184039) +++ head/sys/i386/xen/xen_machdep.c Sun Oct 19 01:27:40 2008 (r184040) @@ -202,21 +202,20 @@ static struct mmu_log xpq_queue_log[MAX_ static int xpq_idx[MAX_VIRT_CPUS]; static mmu_update_t xpq_queue[MAX_VIRT_CPUS][XPQUEUE_SIZE]; -#define XPQ_QUEUE xpq_queue[vcpu] -#define XPQ_IDX xpq_idx[vcpu] -#define SET_VCPU() int vcpu = smp_processor_id() - - -#define XPQ_QUEUE_LOG xpq_queue_log[vcpu] +#define XPQ_QUEUE_LOG xpq_queue_log[vcpu] +#define XPQ_QUEUE xpq_queue[vcpu] +#define XPQ_IDX xpq_idx[vcpu] +#define SET_VCPU() int vcpu = smp_processor_id() #else static mmu_update_t xpq_queue[XPQUEUE_SIZE]; static struct mmu_log xpq_queue_log[XPQUEUE_SIZE]; static int xpq_idx = 0; -#define XPQ_QUEUE xpq_queue -#define XPQ_IDX xpq_idx -#define SET_VCPU() +#define XPQ_QUEUE_LOG xpq_queue_log +#define XPQ_QUEUE xpq_queue +#define XPQ_IDX xpq_idx +#define SET_VCPU() #endif /* !SMP */ #define XPQ_IDX_INC atomic_add_int(&XPQ_IDX, 1); @@ -371,6 +370,13 @@ xen_sti(void) __sti(); } +u_int +xen_rcr2(void) +{ + + return (HYPERVISOR_shared_info->vcpu_info[curcpu].arch.cr2); +} + void _xen_machphys_update(vm_paddr_t mfn, vm_paddr_t pfn, char *file, int line) { @@ -810,7 +816,7 @@ void initvalues(start_info_t *startinfo) { int l3_pages, l2_pages, l1_pages, offset; - vm_offset_t cur_space; + vm_offset_t cur_space, cur_space_pt; struct physdev_set_iopl set_iopl; vm_paddr_t KPTphys, IdlePTDma; @@ -825,15 +831,13 @@ initvalues(start_info_t *startinfo) vm_paddr_t pdir_shadow_ma; #endif unsigned long i; - int ncpus; + int ncpus = MAXCPU; - nkpt = min(max((startinfo->nr_pages >> NPGPTD_SHIFT), nkpt), - NPGPTD*NPDEPG - KPTDI); -#ifdef SMP - ncpus = MAXCPU; -#else - ncpus = 1; -#endif + nkpt = min( + min( + max((startinfo->nr_pages >> NPGPTD_SHIFT), nkpt), + NPGPTD*NPDEPG - KPTDI), + (HYPERVISOR_VIRT_START - KERNBASE) >> PDRSHIFT); HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_4gb_segments); #ifdef notyet @@ -859,7 +863,24 @@ initvalues(start_info_t *startinfo) bootmem_start = bootmem_current = (char *)cur_space; cur_space += (4 * PAGE_SIZE); bootmem_end = (char *)cur_space; + + /* allocate page for gdt */ + gdt = (union descriptor *)cur_space; + cur_space += PAGE_SIZE*ncpus; + + /* allocate page for ldt */ + ldt = (union descriptor *)cur_space; cur_space += PAGE_SIZE; + cur_space += PAGE_SIZE; + HYPERVISOR_shared_info = (shared_info_t *)cur_space; + cur_space += PAGE_SIZE; + + xen_store = (struct ringbuf_head *)cur_space; + cur_space += PAGE_SIZE; + + console_page = (char *)cur_space; + cur_space += PAGE_SIZE; + #ifdef ADD_ISA_HOLE shift_phys_machine(xen_phys_machine, xen_start_info->nr_pages); #endif @@ -936,6 +957,16 @@ initvalues(start_info_t *startinfo) * Unpin the current PDPT */ xen_pt_unpin(IdlePDPTma); + + for (i = 0; i < 20; i++) { + int startidx = ((KERNBASE >> 18) & PAGE_MASK) >> 3; + + if (IdlePTD[startidx + i] == 0) { + l1_pages = i; + break; + } + } + #endif /* PAE */ /* unmap remaining pages from initial 4MB chunk @@ -947,7 +978,7 @@ initvalues(start_info_t *startinfo) } PT_UPDATES_FLUSH(); - + memcpy(((uint8_t *)IdlePTDnew) + ((unsigned int)(KERNBASE >> 18)), ((uint8_t *)IdlePTD) + ((KERNBASE >> 18) & PAGE_MASK), l1_pages*sizeof(pt_entry_t)); @@ -960,18 +991,22 @@ initvalues(start_info_t *startinfo) xen_pgdpt_pin(xpmap_ptom(VTOP(IdlePDPTnew))); /* allocate remainder of nkpt pages */ - for (offset = (KERNBASE >> PDRSHIFT), i = l1_pages - 1; i < nkpt; + cur_space_pt = cur_space; + for (offset = (KERNBASE >> PDRSHIFT), i = l1_pages; i < nkpt; i++, cur_space += PAGE_SIZE) { pdir = (offset + i) / NPDEPG; curoffset = ((offset + i) % NPDEPG); - + if (((offset + i) << PDRSHIFT) == VM_MAX_KERNEL_ADDRESS) + break; + /* * make sure that all the initial page table pages * have been zeroed */ - PT_SET_MA(cur_space, xpmap_ptom(VTOP(cur_space)) | PG_V | PG_RW); - bzero((char *)cur_space, PAGE_SIZE); - PT_SET_MA(cur_space, (vm_paddr_t)0); + PT_SET_MA(cur_space_pt, + xpmap_ptom(VTOP(cur_space)) | PG_V | PG_RW); + bzero((char *)cur_space_pt, PAGE_SIZE); + PT_SET_MA(cur_space_pt, (vm_paddr_t)0); xen_pt_pin(xpmap_ptom(VTOP(cur_space))); xen_queue_pt_update((vm_paddr_t)(IdlePTDnewma[pdir] + curoffset*sizeof(vm_paddr_t)), @@ -994,17 +1029,6 @@ initvalues(start_info_t *startinfo) IdlePDPT = IdlePDPTnew; IdlePDPTma = IdlePDPTnewma; - /* allocate page for gdt */ - gdt = (union descriptor *)cur_space; - cur_space += PAGE_SIZE*ncpus; - - /* allocate page for ldt */ - ldt = (union descriptor *)cur_space; cur_space += PAGE_SIZE; - cur_space += PAGE_SIZE; - - HYPERVISOR_shared_info = (shared_info_t *)cur_space; - cur_space += PAGE_SIZE; - /* * shared_info is an unsigned long so this will randomly break if * it is allocated above 4GB - I guess people are used to that @@ -1015,13 +1039,8 @@ initvalues(start_info_t *startinfo) printk("#4\n"); - xen_store = (struct ringbuf_head *)cur_space; - cur_space += PAGE_SIZE; - xen_store_ma = (((vm_paddr_t)xen_start_info->store_mfn) << PAGE_SHIFT); PT_SET_MA(xen_store, xen_store_ma | PG_KERNEL); - console_page = (char *)cur_space; - cur_space += PAGE_SIZE; console_page_ma = (((vm_paddr_t)xen_start_info->console.domU.mfn) << PAGE_SHIFT); PT_SET_MA(console_page, console_page_ma | PG_KERNEL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200810190127.m9J1ReEj030526>