diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-30 09:54:00 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2023-08-30 09:54:00 -0700 |
commit | 9855922705630a63a6f27621fab1a248dfb5bfc0 (patch) | |
tree | 7c8e04a25fe56e1019ccf7d90e9042a276a9f9c7 /arch/x86/mm | |
parent | ca96b162bfd21a5d55e3cd6099e4ee357a0eeb68 (diff) | |
parent | 54e3d9434ef61b97fd3263c141b928dc5635e50d (diff) |
Merge tag 'x86_mm_for_6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 mm updates from Dave Hansen:
"A pair of small x86/mm updates. The INVPCID one is purely a cleanup.
The PAT one fixes a real issue, albeit a relatively obscure one
(graphics device passthrough under Xen). The fix also makes the code
much more readable.
Summary:
- Remove unnecessary "INVPCID single" feature tracking
- Include PAT in page protection modify mask"
* tag 'x86_mm_for_6.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/mm: Remove "INVPCID single" feature tracking
x86/mm: Fix PAT bit missing from page protection modify mask
Diffstat (limited to 'arch/x86/mm')
-rw-r--r-- | arch/x86/mm/init.c | 9 | ||||
-rw-r--r-- | arch/x86/mm/tlb.c | 19 |
2 files changed, 13 insertions, 15 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index ffa25e962343..679893ea5e68 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -306,15 +306,6 @@ static void setup_pcid(void) * start_secondary(). */ cr4_set_bits(X86_CR4_PCIDE); - - /* - * INVPCID's single-context modes (2/3) only work if we set - * X86_CR4_PCIDE, *and* we INVPCID support. It's unusable - * on systems that have X86_CR4_PCIDE clear, or that have - * no INVPCID support at all. - */ - if (boot_cpu_has(X86_FEATURE_INVPCID)) - setup_force_cpu_cap(X86_FEATURE_INVPCID_SINGLE); } else { /* * flush_tlb_all(), as currently implemented, won't work if diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 2d253919b3e8..453ea95b667d 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -1142,21 +1142,28 @@ void flush_tlb_one_kernel(unsigned long addr) */ STATIC_NOPV void native_flush_tlb_one_user(unsigned long addr) { - u32 loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid); + u32 loaded_mm_asid; + bool cpu_pcide; + /* Flush 'addr' from the kernel PCID: */ asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); + /* If PTI is off there is no user PCID and nothing to flush. */ if (!static_cpu_has(X86_FEATURE_PTI)) return; + loaded_mm_asid = this_cpu_read(cpu_tlbstate.loaded_mm_asid); + cpu_pcide = this_cpu_read(cpu_tlbstate.cr4) & X86_CR4_PCIDE; + /* - * Some platforms #GP if we call invpcid(type=1/2) before CR4.PCIDE=1. - * Just use invalidate_user_asid() in case we are called early. + * invpcid_flush_one(pcid>0) will #GP if CR4.PCIDE==0. Check + * 'cpu_pcide' to ensure that *this* CPU will not trigger those + * #GP's even if called before CR4.PCIDE has been initialized. */ - if (!this_cpu_has(X86_FEATURE_INVPCID_SINGLE)) - invalidate_user_asid(loaded_mm_asid); - else + if (boot_cpu_has(X86_FEATURE_INVPCID) && cpu_pcide) invpcid_flush_one(user_pcid(loaded_mm_asid), addr); + else + invalidate_user_asid(loaded_mm_asid); } void flush_tlb_one_user(unsigned long addr) |