Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Nov 2010 05:46:36 +0000 (UTC)
From:      Alan Cox <alc@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r215373 - in stable/8/sys/i386: i386 include
Message-ID:  <201011160546.oAG5kaS7041154@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: alc
Date: Tue Nov 16 05:46:35 2010
New Revision: 215373
URL: http://svn.freebsd.org/changeset/base/215373

Log:
  MFC r213455
    Initialize KPTmap in locore so that vm86.c can call vtophys() (or really
    pmap_kextract()) before pmap_bootstrap() is called.
  
    Document the set of pmap functions that may be called before
    pmap_bootstrap() is called.

Modified:
  stable/8/sys/i386/i386/locore.s
  stable/8/sys/i386/i386/pmap.c
  stable/8/sys/i386/include/pmap.h
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/i386/i386/locore.s
==============================================================================
--- stable/8/sys/i386/i386/locore.s	Tue Nov 16 05:06:20 2010	(r215372)
+++ stable/8/sys/i386/i386/locore.s	Tue Nov 16 05:46:35 2010	(r215373)
@@ -104,6 +104,9 @@ IdlePTD:	.long	0		/* phys addr of kernel
 IdlePDPT:	.long	0		/* phys addr of kernel PDPT */
 #endif
 
+	.globl	KPTmap
+KPTmap:		.long	0		/* address of kernel page tables */
+
 	.globl	KPTphys
 KPTphys:	.long	0		/* phys addr of kernel page tables */
 
@@ -717,6 +720,8 @@ no_kernend:
 /* Allocate Kernel Page Tables */
 	ALLOCPAGES(NKPT)
 	movl	%esi,R(KPTphys)
+	addl	$(KERNBASE-(KPTDI<<(PDRSHIFT-PAGE_SHIFT+PTESHIFT))),%esi
+	movl	%esi,R(KPTmap)
 
 /* Allocate Page Table Directory */
 #ifdef PAE
@@ -780,6 +785,11 @@ no_kernend:
 	shrl	$PAGE_SHIFT,%ecx
 	fillkptphys($PG_RW)
 
+/* Map page table pages. */
+	movl	R(KPTphys),%eax
+	movl	$NKPT,%ecx
+	fillkptphys($PG_RW)
+
 /* Map page directory. */
 #ifdef PAE
 	movl	R(IdlePDPT), %eax

Modified: stable/8/sys/i386/i386/pmap.c
==============================================================================
--- stable/8/sys/i386/i386/pmap.c	Tue Nov 16 05:06:20 2010	(r215372)
+++ stable/8/sys/i386/i386/pmap.c	Tue Nov 16 05:46:35 2010	(r215373)
@@ -243,7 +243,7 @@ struct sysmaps {
 	caddr_t	CADDR2;
 };
 static struct sysmaps sysmaps_pcpu[MAXCPU];
-pt_entry_t *CMAP1 = 0, *KPTmap;
+pt_entry_t *CMAP1 = 0;
 static pt_entry_t *CMAP3;
 static pd_entry_t *KPTD;
 caddr_t CADDR1 = 0, ptvmmap = 0;
@@ -375,12 +375,11 @@ pmap_bootstrap(vm_paddr_t firstaddr)
 	int i;
 
 	/*
-	 * XXX The calculation of virtual_avail is wrong. It's NKPT*PAGE_SIZE too
-	 * large. It should instead be correctly calculated in locore.s and
-	 * not based on 'first' (which is a physical address, not a virtual
-	 * address, for the start of unused physical memory). The kernel
-	 * page tables are NOT double mapped and thus should not be included
-	 * in this calculation.
+	 * Initialize the first available kernel virtual address.  However,
+	 * using "firstaddr" may waste a few pages of the kernel virtual
+	 * address space, because locore may not have mapped every physical
+	 * page that it allocated.  Preferably, locore would provide a first
+	 * unused virtual address in addition to "firstaddr".
 	 */
 	virtual_avail = (vm_offset_t) KERNBASE + firstaddr;
 	virtual_avail = pmap_kmem_choose(virtual_avail);
@@ -452,6 +451,10 @@ pmap_bootstrap(vm_paddr_t firstaddr)
 
 	/*
 	 * KPTmap is used by pmap_kextract().
+	 *
+	 * KPTmap is first initialized by locore.  However, that initial
+	 * KPTmap can only support NKPT page table pages.  Here, a larger
+	 * KPTmap is created that can support KVA_PAGES page table pages.
 	 */
 	SYSMAP(pt_entry_t *, KPTD, KPTmap, KVA_PAGES)
 
@@ -1364,6 +1367,8 @@ pmap_extract_and_hold(pmap_t pmap, vm_of
 /*
  * Add a wired page to the kva.
  * Note: not SMP coherent.
+ *
+ * This function may be used before pmap_bootstrap() is called.
  */
 PMAP_INLINE void 
 pmap_kenter(vm_offset_t va, vm_paddr_t pa)
@@ -1386,6 +1391,8 @@ pmap_kenter_attr(vm_offset_t va, vm_padd
 /*
  * Remove a page from the kernel pagetables.
  * Note: not SMP coherent.
+ *
+ * This function may be used before pmap_bootstrap() is called.
  */
 PMAP_INLINE void
 pmap_kremove(vm_offset_t va)

Modified: stable/8/sys/i386/include/pmap.h
==============================================================================
--- stable/8/sys/i386/include/pmap.h	Tue Nov 16 05:06:20 2010	(r215372)
+++ stable/8/sys/i386/include/pmap.h	Tue Nov 16 05:46:35 2010	(r215373)
@@ -191,12 +191,21 @@ extern pdpt_entry_t *IdlePDPT;
 extern pd_entry_t *IdlePTD;	/* physical address of "Idle" state directory */
 
 /*
- * virtual address to page table entry and
- * to physical address.
- * Note: these work recursively, thus vtopte of a pte will give
- * the corresponding pde that in turn maps it.
+ * Translate a virtual address to the kernel virtual address of its page table
+ * entry (PTE).  This can be used recursively.  If the address of a PTE as
+ * previously returned by this macro is itself given as the argument, then the
+ * address of the page directory entry (PDE) that maps the PTE will be
+ * returned.
+ *
+ * This macro may be used before pmap_bootstrap() is called.
  */
 #define	vtopte(va)	(PTmap + i386_btop(va))
+
+/*
+ * Translate a virtual address to its physical address.
+ *
+ * This macro may be used before pmap_bootstrap() is called.
+ */
 #define	vtophys(va)	pmap_kextract((vm_offset_t)(va))
 
 #ifdef XEN
@@ -272,14 +281,18 @@ pte_load_store_ma(pt_entry_t *ptep, pt_e
  * table pages, and not user page table pages, and (2) it provides access to
  * a kernel page table page after the corresponding virtual addresses have
  * been promoted to a 2/4MB page mapping.
+ *
+ * KPTmap is first initialized by locore to support just NPKT page table
+ * pages.  Later, it is reinitialized by pmap_bootstrap() to allow for
+ * expansion of the kernel page table.
  */
 extern pt_entry_t *KPTmap;
 
 /*
- *	Routine:	pmap_kextract
- *	Function:
- *		Extract the physical page address associated
- *		kernel virtual address.
+ * Extract from the kernel page table the physical address that is mapped by
+ * the given virtual address "va".
+ *
+ * This function may be used before pmap_bootstrap() is called.
  */
 static __inline vm_paddr_t
 pmap_kextract(vm_offset_t va)
@@ -483,6 +496,11 @@ extern vm_offset_t virtual_end;
 #define	pmap_page_get_memattr(m)	((vm_memattr_t)(m)->md.pat_mode)
 #define	pmap_unmapbios(va, sz)	pmap_unmapdev((va), (sz))
 
+/*
+ * Only the following functions or macros may be used before pmap_bootstrap()
+ * is called: pmap_kenter(), pmap_kextract(), pmap_kremove(), vtophys(), and
+ * vtopte().
+ */
 void	pmap_bootstrap(vm_paddr_t);
 int	pmap_cache_bits(int mode, boolean_t is_pde);
 int	pmap_change_attr(vm_offset_t, vm_size_t, int);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011160546.oAG5kaS7041154>