summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoralc <alc@FreeBSD.org>2009-03-22 04:32:05 +0000
committeralc <alc@FreeBSD.org>2009-03-22 04:32:05 +0000
commit4a181a2befa386930e514801b20de7d173c3f4a7 (patch)
treeffb4e8dd98dc70dda007fd627c03d29e93e3f6e6
parent6de8f91b8f4d63f6eebea9660b1aaa3ed0dbb4fb (diff)
downloadFreeBSD-src-4a181a2befa386930e514801b20de7d173c3f4a7.zip
FreeBSD-src-4a181a2befa386930e514801b20de7d173c3f4a7.tar.gz
In general, the kernel virtual address of the pml4 page table page that is
stored in the pmap is from the direct map region. The two exceptions have been the kernel pmap and the swapper's pmap. These pmaps have used a kernel virtual address established by pmap_bootstrap() for their shared pml4 page table page. However, there is no reason not to use the direct map for these pmaps as well.
-rw-r--r--sys/amd64/amd64/pmap.c6
-rw-r--r--sys/amd64/amd64/vm_machdep.c4
-rw-r--r--sys/amd64/include/pmap.h4
3 files changed, 10 insertions, 4 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 7760ab0..883b7ed 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -542,7 +542,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr)
* Initialize the kernel pmap (which is statically allocated).
*/
PMAP_LOCK_INIT(kernel_pmap);
- kernel_pmap->pm_pml4 = (pdp_entry_t *) (KERNBASE + KPML4phys);
+ kernel_pmap->pm_pml4 = (pdp_entry_t *)PHYS_TO_DMAP(KPML4phys);
kernel_pmap->pm_root = NULL;
kernel_pmap->pm_active = -1; /* don't allow deactivation */
TAILQ_INIT(&kernel_pmap->pm_pvchunk);
@@ -1351,7 +1351,7 @@ pmap_pinit0(pmap_t pmap)
{
PMAP_LOCK_INIT(pmap);
- pmap->pm_pml4 = (pml4_entry_t *)(KERNBASE + KPML4phys);
+ pmap->pm_pml4 = (pml4_entry_t *)PHYS_TO_DMAP(KPML4phys);
pmap->pm_root = NULL;
pmap->pm_active = 0;
TAILQ_INIT(&pmap->pm_pvchunk);
@@ -4695,7 +4695,7 @@ if (oldpmap) /* XXX FIXME */
oldpmap->pm_active &= ~PCPU_GET(cpumask);
pmap->pm_active |= PCPU_GET(cpumask);
#endif
- cr3 = vtophys(pmap->pm_pml4);
+ cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4);
td->td_pcb->pcb_cr3 = cr3;
load_cr3(cr3);
critical_exit();
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 947890b..f0003ee 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -103,6 +103,7 @@ cpu_fork(td1, p2, td2, flags)
register struct proc *p1;
struct pcb *pcb2;
struct mdproc *mdp2;
+ pmap_t pmap2;
p1 = td1->td_proc;
if ((flags & RFPROC) == 0)
@@ -150,7 +151,8 @@ cpu_fork(td1, p2, td2, flags)
* Set registers for trampoline to user mode. Leave space for the
* return address on stack. These are the kernel mode register values.
*/
- pcb2->pcb_cr3 = vtophys(vmspace_pmap(p2->p_vmspace)->pm_pml4);
+ pmap2 = vmspace_pmap(p2->p_vmspace);
+ pcb2->pcb_cr3 = DMAP_TO_PHYS((vm_offset_t)pmap2->pm_pml4);
pcb2->pcb_r12 = (register_t)fork_return; /* fork_trampoline argument */
pcb2->pcb_rbp = 0;
pcb2->pcb_rsp = (register_t)td2->td_frame - sizeof(void *);
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 36d3667..b3f7d77 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -243,6 +243,10 @@ struct md_page {
TAILQ_HEAD(,pv_entry) pv_list;
};
+/*
+ * The kernel virtual address (KVA) of the level 4 page table page is always
+ * within the direct map (DMAP) region.
+ */
struct pmap {
struct mtx pm_mtx;
pml4_entry_t *pm_pml4; /* KVA of level 4 page table */
OpenPOWER on IntegriCloud