Does anyone try kib's Sandy Bridge PCID patch (pcid.2.patch)?
Paul Ambrose
ambrosehua at gmail.com
Mon Jan 30 02:38:35 UTC 2012
I have two boxes, one is AMD Athlon 610e 2.4G with FreeBSD-current
patched with pcid.2.patch? It works well without other issue and it
seem the pcid patch
does not affect other part of the kernel. The other one is Sandy
Bridge i5-2300 with FreeBSD 9 release patched with pcid.1.patch( the
pcid.2.patch seems
dependent on AVX and XSAVE stuffs which is available on -current). But
it hangs up just in a few minutes. I doubt the nvidia-driver which is
not recompiled with
patched kernel is the root, I will check this out later, but does
anyone meet similar problem?
I have two question about the pcid.2.patch
1.
iff --git a/sys/amd64/amd64/apic_vector.S b/sys/amd64/amd64/apic_vector.S
index 96c778d..5b7b759 100644
--- a/sys/amd64/amd64/apic_vector.S
+++ b/sys/amd64/amd64/apic_vector.S
@@ -149,17 +149,40 @@ IDTVEC(invltlb)
#endif
pushq %rax
+ pushq %rdx
- movq %cr3, %rax /* invalidate the TLB */
- movq %rax, %cr3
-
+ cmpl $0,pmap_pcid_enabled
+ je 1f
+
+ cmpq $0,smp_tlb_invpcid
+ je 1f
+
+ /*
+ * For PCID-enabled pmap, set bit 63 of loaded %cr3 to zero.
+ */
+ movq %cr3,%rax
+ movq $pcid_cr3,%rdx
+ cmpq %rax,%rdx
+ je 1f
+ movq %rdx,%cr3
+ btsq $63, %rax //set bit 63. not flush
the tlb when recovering
+ jmp 2f
+
+ /*
+ * Invalidate the TLB.
+ */
+1:
+ movq %cr3,%rax
+2:
// if pcid is available, can we recover the old pcid with 63
bit set?
+ movq %rax,%cr3
movq lapic, %rax
movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
2. amd64/amd64/pmap.c
@@ -5098,15 +5168,20 @@ pmap_activate(struct thread *td)
critical_enter();
pmap = vmspace_pmap(td->td_proc->p_vmspace);
oldpmap = PCPU_GET(curpmap);
+ CPU_ZERO(&pmap->pm_save);
cpuid = PCPU_GET(cpuid);
#ifdef SMP
CPU_CLR_ATOMIC(cpuid, &oldpmap->pm_active);
CPU_SET_ATOMIC(cpuid, &pmap->pm_active);
+ CPU_SET_ATOMIC(cpuid, &pmap->pm_save);
#else
CPU_CLR(cpuid, &oldpmap->pm_active);
CPU_SET(cpuid, &pmap->pm_active);
+ CPU_SET(cpuid, &pmap->pm_active); // this should
be pm_save not pm_active
#endif
cr3 = DMAP_TO_PHYS((vm_offset_t)pmap->pm_pml4);
+ if (pmap->pm_pcid != -1)
+ cr3 |= pmap->pm_pcid;
td->td_pcb->pcb_cr3 = cr3;
load_cr3(cr3);
PCPU_SET(curpmap, pmap);
More information about the freebsd-current
mailing list