From 5e73d5fc48f6c48d9a638404bfea3e7040601f8e Mon Sep 17 00:00:00 2001 From: Aggelos Economopoulos Date: Mon, 20 May 2013 20:56:07 +0200 Subject: [PATCH] kernel -- x86_64: Do not set reserved bits in CR3. The x86-64 platform code was setting PG_V, PG_U, and PG_RW bits in the CR3 register. While the bits were supposed to cleared, Intel and AMD hardware were ignoring them. Other x86-64 implementations, in particular the software emulator in Linux's KVM, do check that these reserved bits are zero. Fixes issue running DragonFly x86_64 on KVM hosts without two-dimensional (nested) paging. Tested on a variety of real hardware (AMD FX(tm)-8150, c2q 6600, others) and VM configurations (KVM on Intel/AMD hosts, Xen). Committing-on-behalf-of: Venkatesh Srinivas Reported-by: aggelos@, c.turner1, others. Testing-by: aggelos@, swildner@, mneumann@, ftigeot@, profmakx@, Enjolras Bug: 2561 --- sys/platform/pc64/x86_64/pmap.c | 1 - sys/platform/pc64/x86_64/vm_machdep.c | 1 - 2 files changed, 2 deletions(-) diff --git a/sys/platform/pc64/x86_64/pmap.c b/sys/platform/pc64/x86_64/pmap.c index 9746be4cf9..ee6d0b2594 100644 --- a/sys/platform/pc64/x86_64/pmap.c +++ b/sys/platform/pc64/x86_64/pmap.c @@ -4522,7 +4522,6 @@ pmap_setlwpvm(struct lwp *lp, struct vmspace *newvm) tlb_flush_count++; #endif curthread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pml4); - curthread->td_pcb->pcb_cr3 |= PG_RW | PG_U | PG_V; load_cr3(curthread->td_pcb->pcb_cr3); pmap = vmspace_pmap(oldvm); atomic_clear_cpumask(&pmap->pm_active, mycpu->gd_cpumask); diff --git a/sys/platform/pc64/x86_64/vm_machdep.c b/sys/platform/pc64/x86_64/vm_machdep.c index 5fb3e64cfb..c68b5aa878 100644 --- a/sys/platform/pc64/x86_64/vm_machdep.c +++ b/sys/platform/pc64/x86_64/vm_machdep.c @@ -140,7 +140,6 @@ cpu_fork(struct lwp *lp1, struct lwp *lp2, int flags) * return address on stack. These are the kernel mode register values. */ pcb2->pcb_cr3 = vtophys(vmspace_pmap(lp2->lwp_proc->p_vmspace)->pm_pml4); - pcb2->pcb_cr3 |= PG_RW | PG_U | PG_V; pcb2->pcb_rbx = (unsigned long)fork_return; /* fork_trampoline argument */ pcb2->pcb_rbp = 0; pcb2->pcb_rsp = (unsigned long)lp2->lwp_md.md_regs - sizeof(void *); -- 2.41.0