PERFORCE change 131566 for review
Kip Macy
kmacy at FreeBSD.org
Mon Dec 24 22:27:35 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=131566
Change 131566 by kmacy at 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);
More information about the p4-projects
mailing list