diff options
author | kib <kib@FreeBSD.org> | 2015-05-15 07:57:47 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2015-05-15 07:57:47 +0000 |
commit | 7531e6e70ecfbbf822fff6ef7e6165cac9d7e5fd (patch) | |
tree | 49b020becb8633d9642c881f9b4aac02dfb8049f /sys/amd64/amd64/pmap.c | |
parent | bcfe60fa4dccf431f2783503aea046470ccc3844 (diff) | |
download | FreeBSD-src-7531e6e70ecfbbf822fff6ef7e6165cac9d7e5fd.zip FreeBSD-src-7531e6e70ecfbbf822fff6ef7e6165cac9d7e5fd.tar.gz |
Implement the support for PCID in UP kernels.
Requested by: alc
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 3 weeks
Diffstat (limited to 'sys/amd64/amd64/pmap.c')
-rw-r--r-- | sys/amd64/amd64/pmap.c | 96 |
1 files changed, 55 insertions, 41 deletions
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 92dd475..2829d07 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -909,11 +909,7 @@ pmap_bootstrap(vm_paddr_t *firstaddr) * pc_pcid_next and pc_pcid_gen are initialized by AP * during pcpu setup. */ -#ifdef SMP load_cr4(rcr4() | CR4_PCIDE); -#else - pmap_pcid_enabled = 0; -#endif } else { pmap_pcid_enabled = 0; } @@ -1559,61 +1555,79 @@ pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) #else /* !SMP */ /* * Normal, non-SMP, invalidation functions. - * We inline these within pmap.c for speed. */ -PMAP_INLINE void +void pmap_invalidate_page(pmap_t pmap, vm_offset_t va) { - switch (pmap->pm_type) { - case PT_X86: - if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active)) - invlpg(va); - break; - case PT_RVI: - case PT_EPT: + if (pmap->pm_type == PT_RVI || pmap->pm_type == PT_EPT) { pmap->pm_eptgen++; - break; - default: - panic("pmap_invalidate_page: unknown type: %d", pmap->pm_type); + return; } + KASSERT(pmap->pm_type == PT_X86, + ("pmap_invalidate_range: unknown type %d", pmap->pm_type)); + + if (pmap == kernel_pmap || pmap == PCPU_GET(curpmap)) + invlpg(va); + else if (pmap_pcid_enabled) + pmap->pm_pcids[0].pm_gen = 0; } -PMAP_INLINE void +void pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva) { vm_offset_t addr; - switch (pmap->pm_type) { - case PT_X86: - if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active)) - for (addr = sva; addr < eva; addr += PAGE_SIZE) - invlpg(addr); - break; - case PT_RVI: - case PT_EPT: + if (pmap->pm_type == PT_RVI || pmap->pm_type == PT_EPT) { pmap->pm_eptgen++; - break; - default: - panic("pmap_invalidate_range: unknown type: %d", pmap->pm_type); + return; + } + KASSERT(pmap->pm_type == PT_X86, + ("pmap_invalidate_range: unknown type %d", pmap->pm_type)); + + if (pmap == kernel_pmap || pmap == PCPU_GET(curpmap)) { + for (addr = sva; addr < eva; addr += PAGE_SIZE) + invlpg(addr); + } else if (pmap_pcid_enabled) { + pmap->pm_pcids[0].pm_gen = 0; } } -PMAP_INLINE void +void pmap_invalidate_all(pmap_t pmap) { + struct invpcid_descr d; - switch (pmap->pm_type) { - case PT_X86: - if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active)) - invltlb(); - break; - case PT_RVI: - case PT_EPT: + if (pmap->pm_type == PT_RVI || pmap->pm_type == PT_EPT) { pmap->pm_eptgen++; - break; - default: - panic("pmap_invalidate_all: unknown type %d", pmap->pm_type); + return; + } + KASSERT(pmap->pm_type == PT_X86, + ("pmap_invalidate_all: unknown type %d", pmap->pm_type)); + + if (pmap == kernel_pmap) { + if (pmap_pcid_enabled && invpcid_works) { + bzero(&d, sizeof(d)); + invpcid(&d, INVPCID_CTXGLOB); + } else { + invltlb_globpcid(); + } + } else if (pmap == PCPU_GET(curpmap)) { + if (pmap_pcid_enabled) { + if (invpcid_works) { + d.pcid = pmap->pm_pcids[0].pm_pcid; + d.pad = 0; + d.addr = 0; + invpcid(&d, INVPCID_CTX); + } else { + load_cr3(pmap->pm_cr3 | pmap->pm_pcids[0]. + pm_pcid); + } + } else { + invltlb(); + } + } else if (pmap_pcid_enabled) { + pmap->pm_pcids[0].pm_gen = 0; } } @@ -1629,10 +1643,10 @@ pmap_update_pde(pmap_t pmap, vm_offset_t va, pd_entry_t *pde, pd_entry_t newpde) { pmap_update_pde_store(pmap, pde, newpde); - if (pmap == kernel_pmap || !CPU_EMPTY(&pmap->pm_active)) + if (pmap == kernel_pmap || pmap == PCPU_GET(curpmap)) pmap_update_pde_invalidate(pmap, va, newpde); else - CPU_ZERO(&pmap->pm_save); + pmap->pm_pcids[0].pm_gen = 0; } #endif /* !SMP */ |