Skip site navigation (1)Skip section navigation (2)
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>