diff options
author | kmacy <kmacy@FreeBSD.org> | 2008-10-19 01:27:40 +0000 |
---|---|---|
committer | kmacy <kmacy@FreeBSD.org> | 2008-10-19 01:27:40 +0000 |
commit | 99642cdfcbeeacb6d6d0f21f708aeb286e5de856 (patch) | |
tree | 9e6f1e74f88ede78d8b2f429418a0c2fa823f855 | |
parent | c272550e836db5b7cd2282c4e7ef0e2d6d2b8107 (diff) | |
download | FreeBSD-src-99642cdfcbeeacb6d6d0f21f708aeb286e5de856.zip FreeBSD-src-99642cdfcbeeacb6d6d0f21f708aeb286e5de856.tar.gz |
- 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
-rw-r--r-- | sys/i386/include/cpufunc.h | 8 | ||||
-rw-r--r-- | sys/i386/xen/xen_machdep.c | 99 |
2 files changed, 65 insertions, 42 deletions
diff --git a/sys/i386/include/cpufunc.h b/sys/i386/include/cpufunc.h index 5f28a86..4bf93b1 100644 --- a/sys/i386/include/cpufunc.h +++ b/sys/i386/include/cpufunc.h @@ -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); } diff --git a/sys/i386/xen/xen_machdep.c b/sys/i386/xen/xen_machdep.c index 48caab8..e37d522 100644 --- a/sys/i386/xen/xen_machdep.c +++ b/sys/i386/xen/xen_machdep.c @@ -202,21 +202,20 @@ static struct mmu_log xpq_queue_log[MAX_VIRT_CPUS][XPQUEUE_SIZE]; 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); |