Date: Tue, 25 Dec 2007 06:27:33 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 131566 for review Message-ID: <200712250627.lBP6RXH8008238@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=131566 Change 131566 by kmacy@pandemonium:kmacy:xen31 on 2007/12/25 06:27:11 get pagetable read mappings to the point where they work for PAE so that VA -> MA lookups will work Affected files ... .. //depot/projects/xen31/sys/i386/include/xen/hypercall.h#2 edit .. //depot/projects/xen31/sys/i386/include/xen/xen-public/xen.h#3 edit .. //depot/projects/xen31/sys/i386/include/xen/xenpmap.h#3 edit .. //depot/projects/xen31/sys/i386/include/xen/xenvar.h#3 edit .. //depot/projects/xen31/sys/i386/xen/locore.s#5 edit .. //depot/projects/xen31/sys/i386/xen/xen_machdep.c#4 edit Differences ... ==== //depot/projects/xen31/sys/i386/include/xen/hypercall.h#2 (text+ko) ==== @@ -224,7 +224,7 @@ unsigned long va, pte_t new_val, unsigned long flags) { unsigned long pte_hi = 0; -#ifdef CONFIG_X86_PAE +#ifdef PAE pte_hi = new_val.pte_high; #endif return _hypercall4(int, update_va_mapping, va, ==== //depot/projects/xen31/sys/i386/include/xen/xen-public/xen.h#3 (text+ko) ==== ==== //depot/projects/xen31/sys/i386/include/xen/xenpmap.h#3 (text+ko) ==== @@ -39,6 +39,7 @@ void xen_pt_switch(vm_paddr_t); void xen_set_ldt(vm_paddr_t, unsigned long); void xen_tlb_flush(void); +void xen_pgdpt_pin(vm_paddr_t); void xen_pgd_pin(vm_paddr_t); void xen_pgd_unpin(vm_paddr_t); void xen_pt_pin(vm_paddr_t); @@ -156,15 +157,30 @@ #endif -#define PT_SET_MA(_va, _ma) \ -do { \ - pte_t pte_t_ma; \ - pte_t_ma.pte_low = (uint32_t)(_ma); \ +#ifdef PAE +#define PT_SET_MA(_va, _ma) \ +do { \ + pte_t pte_t_ma; \ + pte_t_ma.pte_high = (uint32_t)((_ma) >> 32); \ + pte_t_ma.pte_low = (uint32_t)((_ma) & 0xFFFFFFFF); \ + PANIC_IF(HYPERVISOR_update_va_mapping(((unsigned long)_va), \ + pte_t_ma, \ + UVMF_INVLPG| UVMF_LOCAL) < 0); \ +} while (/*CONSTCOND*/0) + +#else + +#define PT_SET_MA(_va, _ma) \ +do { \ + pte_t pte_t_ma; \ + pte_t_ma.pte_low = (uint32_t)(_ma); \ PANIC_IF(HYPERVISOR_update_va_mapping(((unsigned long)_va), \ - pte_t_ma, \ + pte_t_ma, \ UVMF_INVLPG| UVMF_LOCAL) < 0); \ } while (/*CONSTCOND*/0) +#endif + #define PT_UPDATES_FLUSH() do { \ xen_flush_queue(); \ } while (/*CONSTCOND*/0) ==== //depot/projects/xen31/sys/i386/include/xen/xenvar.h#3 (text+ko) ==== @@ -7,8 +7,9 @@ #define XENPRINTF printk #else #define XENPRINTF printf -#endif -extern vm_paddr_t *xen_phys_machine; +#endif + +extern xen_pfn_t *xen_phys_machine; #if 0 #define TRACE_ENTER XENPRINTF("(file=%s, line=%d) entered %s\n", __FILE__, __LINE__, __FUNCTION__) @@ -38,11 +39,11 @@ #endif -#define PFNTOMFN(i) (((vm_paddr_t *)xen_phys_machine)[(i)]) -#define MFNTOPFN(i) (xen_machine_phys[i]) +#define PFNTOMFN(i) (xen_phys_machine[((xen_pfn_t)i)]) +#define MFNTOPFN(i) (xen_machine_phys[((xen_pfn_t)i)]) -#define VTOP(x) ((vm_paddr_t)((uintptr_t)x) - KERNBASE) -#define PTOV(x) ((vm_paddr_t)(x) + KERNBASE) +#define VTOP(x) ((uintptr_t)(((uint8_t *)(x)) - KERNBASE)) +#define PTOV(x) ((x) + KERNBASE) #define VTOPFN(x) (VTOP(x) >> PAGE_SHIFT) #define PFNTOV(x) PTOV((vm_paddr_t)(x) << PAGE_SHIFT) ==== //depot/projects/xen31/sys/i386/xen/locore.s#5 (text+ko) ==== @@ -132,11 +132,12 @@ .space 0x2000 /* space for tmpstk - temporary stack */ tmpstk: - .globl bootinfo + .globl bootinfo bootinfo: .space BOOTINFO_SIZE /* bootinfo that we can handle */ .globl KERNend KERNend: .long 0 /* phys addr end of kernel (just after bss) */ + .globl physfree physfree: .long 0 /* phys addr of next free page */ #ifdef SMP @@ -280,10 +281,17 @@ movl proc0kstack,%eax leal (KSTACK_PAGES*PAGE_SIZE-PCB_SIZE)(%eax),%esp xorl %ebp,%ebp /* mark end of frames */ +#ifdef PAE + movl IdlePDPT,%esi +#else movl IdlePTD,%esi +#endif movl %esi,(KSTACK_PAGES*PAGE_SIZE-PCB_SIZE+PCB_CR3)(%eax) + pushl physfree call init386 + addl $4, %esp call mi_startup + /* NOTREACHED */ int $3 /* ==== //depot/projects/xen31/sys/i386/xen/xen_machdep.c#4 (text+ko) ==== @@ -76,7 +76,7 @@ start_info_t *xen_start_info; shared_info_t *HYPERVISOR_shared_info; vm_paddr_t *xen_machine_phys = ((vm_paddr_t *)VADDR(1008, 0)); -vm_paddr_t *xen_phys_machine; +xen_pfn_t *xen_phys_machine; int preemptable, init_first; extern unsigned int avail_space; @@ -270,7 +270,6 @@ PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); } - void xen_machphys_update(unsigned long mfn, unsigned long pfn) { @@ -287,12 +286,22 @@ { SET_VCPU(); - XPQ_QUEUE[XPQ_IDX].ptr = (uint64_t)ptr; + XPQ_QUEUE[XPQ_IDX].ptr = ((uint64_t)ptr) | MMU_NORMAL_PT_UPDATE; XPQ_QUEUE[XPQ_IDX].val = (uint64_t)val; xen_increment_idx(); } void +xen_pgdpt_pin(vm_paddr_t ma) +{ + struct mmuext_op op; + op.cmd = MMUEXT_PIN_L3_TABLE; + op.arg1.mfn = ma >> PAGE_SHIFT; + xen_flush_queue(); + PANIC_IF(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); +} + +void xen_pgd_pin(vm_paddr_t ma) { struct mmuext_op op; @@ -635,7 +644,13 @@ } #endif -static vm_offset_t *pdir_shadow; + +#ifdef PAE +static vm_paddr_t *ptdir_shadow; +static vm_paddr_t *pdir_shadow[4]; +#else +static vm_paddr_t *pdir_shadow; +#endif #ifdef ADD_ISA_HOLE static void @@ -671,25 +686,37 @@ } #endif +extern unsigned long physfree; void initvalues(start_info_t *startinfo) { - int i; - unsigned int cur_space = avail_space; - vm_paddr_t pdir_shadow_ma, KPTphys, IdlePTDma; + int i, l3_pages, l2_pages, l1_pages; + vm_offset_t cur_space; physdev_op_t op; - - printk("initvalues(): wooh - availmem=%x,%x\n",avail_space, cur_space); + vm_paddr_t KPTphys, IdlePTDma; + vm_paddr_t console_page_ma, xen_store_ma; + vm_offset_t KPTphysoff, tmpva; + vm_paddr_t shinfo; +#ifdef PAE + vm_paddr_t IdlePDPTma, ptdir_shadow_ma, IdlePDPTnewma, IdlePTDnewma; + vm_paddr_t pdir_shadow_ma[4]; + pd_entry_t *IdlePDPTnew, *IdlePTDnew; +#else + vm_paddr_t pdir_shadow_ma; +#endif #ifdef WRITABLE_PAGETABLES printk("using writable pagetables\n"); HYPERVISOR_vm_assist(VMASST_CMD_enable, VMASST_TYPE_writable_pagetables); #endif - xen_start_info = startinfo; - xen_phys_machine = (vm_paddr_t *)startinfo->mfn_list; + xen_phys_machine = (xen_pfn_t *)startinfo->mfn_list; /* number of pages allocated after the pts + 1*/; + cur_space = xen_start_info->pt_base + + ((xen_start_info->nr_pt_frames) + 3 )*PAGE_SIZE; + printk("initvalues(): wooh - availmem=%x,%x\n", avail_space, cur_space); + printk("KERNBASE=%x,pt_base=%x, VTOPFN(base)=%x, nr_pt_frames=%x\n", KERNBASE,xen_start_info->pt_base, VTOPFN(xen_start_info->pt_base), xen_start_info->nr_pt_frames); xendebug_flags = 0; /* 0xffffffff; */ @@ -708,9 +735,22 @@ bzero((char *)cur_space, (cur_space + 0x3fffff) % 0x400000); */ +#ifdef PAE + IdlePDPT = (pd_entry_t *)startinfo->pt_base; + IdlePDPTma = xpmap_ptom(VTOP(startinfo->pt_base)); + IdlePTD = (pd_entry_t *)((uint8_t *)startinfo->pt_base + PAGE_SIZE); + IdlePTDma = xpmap_ptom(VTOP(IdlePTD)); + l3_pages = 1; +#else IdlePTD = (pd_entry_t *)startinfo->pt_base; IdlePTDma = xpmap_ptom(VTOP(startinfo->pt_base)); - KPTphys = xpmap_ptom(VTOP(startinfo->pt_base + PAGE_SIZE)); + l3_pages = 0; +#endif + l2_pages = 1; + l1_pages = 4; /* XXX not certain if this varies */ + KPTphysoff = (l2_pages + l3_pages)*PAGE_SIZE; + + KPTphys = xpmap_ptom(VTOP(startinfo->pt_base + KPTphysoff)); XENPRINTF("IdlePTD %p\n", IdlePTD); XENPRINTF("nr_pages: %ld shared_info: 0x%lx flags: 0x%lx pt_base: 0x%lx " "mod_start: 0x%lx mod_len: 0x%lx\n", @@ -722,6 +762,7 @@ xpmap_get_bootpte(0xc0100000)); #endif /* Map proc0's KSTACK */ + proc0kstack = cur_space; cur_space += (KSTACK_PAGES * PAGE_SIZE); printk("proc0kstack=%u\n", proc0kstack); @@ -738,33 +779,96 @@ vm86paddr = (vm_offset_t)cur_space; cur_space += (PAGE_SIZE * 3); +#ifdef PAE + for (i = 0; i < 4; i++) { + /* initialize page directory shadow page */ + pdir_shadow[i] = (vm_paddr_t *)cur_space; + cur_space += PAGE_SIZE; + bzero(pdir_shadow[i], PAGE_SIZE); + pdir_shadow_ma[i] = xpmap_ptom((vm_paddr_t)VTOP(pdir_shadow[i])); + } +#else /* initialize page directory shadow page */ - pdir_shadow = (vm_offset_t *)cur_space; cur_space += PAGE_SIZE; + pdir_shadow = (vm_paddr_t *)cur_space; cur_space += PAGE_SIZE; bzero(pdir_shadow, PAGE_SIZE); - pdir_shadow_ma = xpmap_ptom(VTOP(pdir_shadow)); - XENPRINTF("pdir_shadow=%x,pdir_shadow_ma=%x\n", pdir_shadow, pdir_shadow_ma); - PT_SET_MA(pdir_shadow, pdir_shadow_ma | PG_V | PG_A); + pdir_shadow_ma = xpmap_ptom((vm_paddr_t)VTOP(pdir_shadow)); +#endif + +#ifdef PAE + IdlePDPTnew = (pd_entry_t *)cur_space; cur_space += PAGE_SIZE; + bzero(IdlePDPTnew, PAGE_SIZE); + IdlePDPTnewma = xpmap_ptom(VTOP(IdlePDPTnew)); + + IdlePTDnew = (pd_entry_t *)cur_space; cur_space += PAGE_SIZE; + bzero(IdlePTDnew, PAGE_SIZE); + IdlePTDnewma = xpmap_ptom(VTOP(IdlePTDnew)); + memcpy(IdlePTDnew, IdlePTD, PAGE_SIZE/2); + + + /* initialize page directory page table shadow page */ + ptdir_shadow = (vm_paddr_t *)cur_space; cur_space += PAGE_SIZE; + bzero(ptdir_shadow, PAGE_SIZE); + ptdir_shadow_ma = xpmap_ptom(VTOP(ptdir_shadow)); + + + /* + * L3 + */ + IdlePDPTnew[2] = ptdir_shadow_ma | PG_V; + IdlePDPTnew[3] = IdlePTDnewma | PG_V; + /* + * L2 + */ + + for (i = 0; i < 4; i++) + ptdir_shadow[508 + i] = pdir_shadow_ma[i] | PG_V; + /* + * L1 - can't copy Xen's mappings + */ + for (i = 0; i < 256; i++) + pdir_shadow[3][i] = IdlePTDnew[i] & ~(PG_RW|PG_A); + + /* + * Map IdlePTD at PTD + */ + pdir_shadow[2][508] = IdlePTDnewma | PG_V; - /* setup shadow mapping first so vtomach will work */ + for (i = 0; i < 4; i++) + PT_SET_MA(pdir_shadow[i], pdir_shadow_ma[i] | PG_V); + PT_SET_MA(ptdir_shadow, ptdir_shadow_ma | PG_V); + PT_SET_MA(IdlePDPTnew, IdlePDPTnewma | PG_V); + PT_SET_MA(IdlePTDnew, IdlePTDnewma | PG_V); +#if 0 + xen_pgd_pin(ptdir_shadow_ma); + xen_pgd_pin(IdlePTDnewma); +#endif + xen_load_cr3(VTOP(IdlePDPTnew)); + IdlePTD = IdlePTDnew; + IdlePTDma = IdlePTDnewma; + IdlePDPT = IdlePDPTnew; + IdlePDPTma = IdlePDPTnewma; +#endif +#if 0 + /* setup shadow mapping first so vtomach will work */ xen_pt_pin(pdir_shadow_ma); - xen_queue_pt_update((vm_paddr_t)(IdlePTDma + PTDPTDI), +#endif +#ifndef PAE + xen_queue_pt_update(IdlePTDma + PTDPTDI*sizeof(vm_paddr_t), pdir_shadow_ma | PG_KERNEL); - xen_queue_pt_update(pdir_shadow_ma + PTDPTDI*sizeof(vm_paddr_t), - ((vm_paddr_t)IdlePTDma) | PG_V | PG_A); + xen_flush_queue(); +#endif +#if 0 xen_queue_pt_update(pdir_shadow_ma + (KPTDI + ISA_PDR_OFFSET)*sizeof(vm_paddr_t), KPTphys | PG_V | PG_A); xen_flush_queue(); +#endif + /* unmap remaining pages from initial 2/4MB chunk */ + for (tmpva = cur_space; (tmpva & PDRMASK) != 0; tmpva += PAGE_SIZE) + PT_SET_MA(tmpva, (vm_paddr_t)0); - /* unmap remaining pages from initial 4MB chunk */ - for (i = cur_space >> PAGE_SHIFT; i%400 != 0; i++) { - xen_queue_pt_update(KPTphys + i*sizeof(vm_paddr_t), 0); - } - xen_flush_queue(); - - /* allocate remainder of NKPT pages */ printk("#1\n"); - for (i = 0; i < NKPT-1; i++, cur_space += PAGE_SIZE) { + for (i = 0; i < NKPT-l1_pages; i++, cur_space += PAGE_SIZE) { /* KERNBASE left unmapped (+ 1) KERNLOAD already mapped (+1) == + 2 */ printk("#2: i=%i,offs=%u->%x\n", i, KPTDI + i + 1, xpmap_ptom(VTOP(cur_space)) | PG_KERNEL); @@ -772,31 +876,41 @@ xen_queue_pt_update((vm_paddr_t)(IdlePTDma + KPTDI + i + 1), xpmap_ptom(VTOP(cur_space)) | PG_KERNEL);*/ PT_UPDATES_FLUSH(); - xen_queue_pt_update(pdir_shadow_ma + (KPTDI + i + 1)*sizeof(vm_paddr_t), +#ifdef PAE + xen_queue_pt_update(pdir_shadow_ma[3] + (KPTDI + i + 1)*sizeof(vm_paddr_t), xpmap_ptom(VTOP(cur_space)) | PG_V | PG_A); +#else + xen_queue_pt_update(pdir_shadow_ma + (KPTDI + i + 1)*sizeof(vm_paddr_t), + xpmap_ptom(VTOP(cur_space)) | PG_V | PG_A); +#endif PT_UPDATES_FLUSH(); } printk("#3\n"); HYPERVISOR_shared_info = (shared_info_t *)cur_space; - PT_SET_MA(HYPERVISOR_shared_info, - xen_start_info->shared_info | PG_KERNEL); + + /* + * shared_info is an unsigned long so this will randomly break if + * it is allocated above 4GB - I guess people are used to that + * sort of thing with Xen ... sigh + */ + shinfo = xen_start_info->shared_info; + PT_SET_MA(HYPERVISOR_shared_info, shinfo | PG_KERNEL); cur_space += PAGE_SIZE; printk("#4\n"); xen_store = (struct ringbuf_head *)cur_space; - PT_SET_MA(xen_store, - (xen_start_info->store_mfn << PAGE_SHIFT)| PG_KERNEL); + xen_store_ma = (xen_start_info->store_mfn << PAGE_SHIFT); + PT_SET_MA(xen_store, xen_store_ma | PG_KERNEL); cur_space += PAGE_SIZE; console_page = (char *)cur_space; - PT_SET_MA(console_page, - (xen_start_info->console.domU.mfn << PAGE_SHIFT)| PG_KERNEL); + console_page_ma = (xen_start_info->console.domU.mfn << PAGE_SHIFT); + PT_SET_MA(console_page, console_page_ma | PG_KERNEL); cur_space += PAGE_SIZE; printk("#5\n"); - HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list = (unsigned long)xen_phys_machine; #if 0 && defined(SMP) for (i = 0; i < ncpus; i++) { @@ -816,25 +930,33 @@ PANIC_IF(HYPERVISOR_physdev_op(&op)); printk("#6\n"); - +#if 1 /* add page table for KERNBASE */ - xen_queue_pt_update((vm_paddr_t)(IdlePTDma + KPTDI), + xen_queue_pt_update(IdlePTDma + KPTDI*sizeof(vm_paddr_t), xpmap_ptom(VTOP(cur_space) | PG_KERNEL)); + xen_flush_queue(); +#ifdef PAE + xen_queue_pt_update(pdir_shadow_ma[3] + KPTDI*sizeof(vm_paddr_t), + xpmap_ptom(VTOP(cur_space) | PG_V | PG_A)); +#else xen_queue_pt_update(pdir_shadow_ma + KPTDI*sizeof(vm_paddr_t), xpmap_ptom(VTOP(cur_space) | PG_V | PG_A)); +#endif xen_flush_queue(); +#endif cur_space += PAGE_SIZE; printk("#6\n"); +#ifdef notyet if (xen_start_info->flags & SIF_INITDOMAIN) { /* Map first megabyte */ for (i = 0; i < (256 << PAGE_SHIFT); i += PAGE_SIZE) PT_SET_MA(KERNBASE + i, i | PG_KERNEL | PG_NC_PCD); xen_flush_queue(); } - +#endif printk("#7\n"); - + physfree = VTOP(cur_space); init_first = (cur_space >> PAGE_SHIFT); printk("#8, proc0kstack=%u\n", proc0kstack);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200712250627.lBP6RXH8008238>