Skip to content

Commit cd30d26

Browse files
KAGA-KOKOsuryasaimadhu
authored andcommitted
x86/tlb: Move __flush_tlb_global() out of line
cpu_tlbstate is exported because various TLB-related functions need access to it, but cpu_tlbstate is sensitive information which should only be accessed by well-contained kernel functions and not be directly exposed to modules. As a second step, move __flush_tlb_global() out of line and hide the native function. The latter can be static when CONFIG_PARAVIRT is disabled. Consolidate the namespace while at it and remove the pointless extra wrapper in the paravirt code. No functional change. Signed-off-by: Thomas Gleixner <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Alexandre Chartre <[email protected]> Acked-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 2faf153 commit cd30d26

File tree

4 files changed

+44
-45
lines changed

4 files changed

+44
-45
lines changed

arch/x86/include/asm/paravirt.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ static inline void slow_down_io(void)
4848
}
4949

5050
void native_flush_tlb_local(void);
51+
void native_flush_tlb_global(void);
5152

5253
static inline void __flush_tlb_local(void)
5354
{

arch/x86/include/asm/tlbflush.h

Lines changed: 2 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,11 @@ static inline unsigned long build_cr3_noflush(pgd_t *pgd, u16 asid)
141141
}
142142

143143
void flush_tlb_local(void);
144+
void flush_tlb_global(void);
144145

145146
#ifdef CONFIG_PARAVIRT
146147
#include <asm/paravirt.h>
147148
#else
148-
#define __flush_tlb_global() __native_flush_tlb_global()
149149
#define __flush_tlb_one_user(addr) __native_flush_tlb_one_user(addr)
150150
#endif
151151

@@ -371,40 +371,6 @@ static inline void invalidate_user_asid(u16 asid)
371371
(unsigned long *)this_cpu_ptr(&cpu_tlbstate.user_pcid_flush_mask));
372372
}
373373

374-
/*
375-
* flush everything
376-
*/
377-
static inline void __native_flush_tlb_global(void)
378-
{
379-
unsigned long cr4, flags;
380-
381-
if (static_cpu_has(X86_FEATURE_INVPCID)) {
382-
/*
383-
* Using INVPCID is considerably faster than a pair of writes
384-
* to CR4 sandwiched inside an IRQ flag save/restore.
385-
*
386-
* Note, this works with CR4.PCIDE=0 or 1.
387-
*/
388-
invpcid_flush_all();
389-
return;
390-
}
391-
392-
/*
393-
* Read-modify-write to CR4 - protect it from preemption and
394-
* from interrupts. (Use the raw variant because this code can
395-
* be called from deep inside debugging code.)
396-
*/
397-
raw_local_irq_save(flags);
398-
399-
cr4 = this_cpu_read(cpu_tlbstate.cr4);
400-
/* toggle PGE */
401-
native_write_cr4(cr4 ^ X86_CR4_PGE);
402-
/* write old PGE again and flush TLBs */
403-
native_write_cr4(cr4);
404-
405-
raw_local_irq_restore(flags);
406-
}
407-
408374
/*
409375
* flush one page in the user mapping
410376
*/
@@ -439,7 +405,7 @@ static inline void __flush_tlb_all(void)
439405
VM_WARN_ON_ONCE(preemptible());
440406

441407
if (boot_cpu_has(X86_FEATURE_PGE)) {
442-
__flush_tlb_global();
408+
flush_tlb_global();
443409
} else {
444410
/*
445411
* !PGE -> !PCID (setup_pcid()), thus every flush is total.

arch/x86/kernel/paravirt.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -160,15 +160,6 @@ unsigned paravirt_patch_insns(void *insn_buff, unsigned len,
160160
return insn_len;
161161
}
162162

163-
/*
164-
* Global pages have to be flushed a bit differently. Not a real
165-
* performance problem because this does not happen often.
166-
*/
167-
static void native_flush_tlb_global(void)
168-
{
169-
__native_flush_tlb_global();
170-
}
171-
172163
static void native_flush_tlb_one_user(unsigned long addr)
173164
{
174165
__native_flush_tlb_one_user(addr);

arch/x86/mm/tlb.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#else
2424
# define STATIC_NOPV static
2525
# define __flush_tlb_local native_flush_tlb_local
26+
# define __flush_tlb_global native_flush_tlb_global
2627
#endif
2728

2829
/*
@@ -890,6 +891,46 @@ unsigned long __get_current_cr3_fast(void)
890891
}
891892
EXPORT_SYMBOL_GPL(__get_current_cr3_fast);
892893

894+
/*
895+
* Flush everything
896+
*/
897+
STATIC_NOPV void native_flush_tlb_global(void)
898+
{
899+
unsigned long cr4, flags;
900+
901+
if (static_cpu_has(X86_FEATURE_INVPCID)) {
902+
/*
903+
* Using INVPCID is considerably faster than a pair of writes
904+
* to CR4 sandwiched inside an IRQ flag save/restore.
905+
*
906+
* Note, this works with CR4.PCIDE=0 or 1.
907+
*/
908+
invpcid_flush_all();
909+
return;
910+
}
911+
912+
/*
913+
* Read-modify-write to CR4 - protect it from preemption and
914+
* from interrupts. (Use the raw variant because this code can
915+
* be called from deep inside debugging code.)
916+
*/
917+
raw_local_irq_save(flags);
918+
919+
cr4 = this_cpu_read(cpu_tlbstate.cr4);
920+
/* toggle PGE */
921+
native_write_cr4(cr4 ^ X86_CR4_PGE);
922+
/* write old PGE again and flush TLBs */
923+
native_write_cr4(cr4);
924+
925+
raw_local_irq_restore(flags);
926+
}
927+
928+
void flush_tlb_global(void)
929+
{
930+
__flush_tlb_global();
931+
}
932+
EXPORT_SYMBOL_GPL(flush_tlb_global);
933+
893934
/*
894935
* Flush the entire current user mapping
895936
*/

0 commit comments

Comments
 (0)