Skip to content

Commit 47061a2

Browse files
amlutoIngo Molnar
authored andcommitted
x86/mm: Factor out CR3-building code
Current, the code that assembles a value to load into CR3 is open-coded everywhere. Factor it out into helpers build_cr3() and build_cr3_noflush(). This makes one semantic change: __get_current_cr3_fast() was wrong on SME systems. No one noticed because the only caller is in the VMX code, and there are no CPUs with both SME and VMX. Signed-off-by: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Tom Lendacky <[email protected]> Link: http://lkml.kernel.org/r/ce350cf11e93e2842d14d0b95b0199c7d881f527.1505663533.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]>
1 parent 0666f56 commit 47061a2

File tree

2 files changed

+16
-10
lines changed

2 files changed

+16
-10
lines changed

arch/x86/include/asm/mmu_context.h

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,15 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
286286
return __pkru_allows_pkey(vma_pkey(vma), write);
287287
}
288288

289+
static inline unsigned long build_cr3(struct mm_struct *mm, u16 asid)
290+
{
291+
return __sme_pa(mm->pgd) | asid;
292+
}
293+
294+
static inline unsigned long build_cr3_noflush(struct mm_struct *mm, u16 asid)
295+
{
296+
return __sme_pa(mm->pgd) | asid | CR3_NOFLUSH;
297+
}
289298

290299
/*
291300
* This can be used from process context to figure out what the value of
@@ -296,10 +305,8 @@ static inline bool arch_vma_access_permitted(struct vm_area_struct *vma,
296305
*/
297306
static inline unsigned long __get_current_cr3_fast(void)
298307
{
299-
unsigned long cr3 = __pa(this_cpu_read(cpu_tlbstate.loaded_mm)->pgd);
300-
301-
if (static_cpu_has(X86_FEATURE_PCID))
302-
cr3 |= this_cpu_read(cpu_tlbstate.loaded_mm_asid);
308+
unsigned long cr3 = build_cr3(this_cpu_read(cpu_tlbstate.loaded_mm),
309+
this_cpu_read(cpu_tlbstate.loaded_mm_asid));
303310

304311
/* For now, be very restrictive about when this can be called. */
305312
VM_WARN_ON(in_nmi() || preemptible());

arch/x86/mm/tlb.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
126126
* isn't free.
127127
*/
128128
#ifdef CONFIG_DEBUG_VM
129-
if (WARN_ON_ONCE(__read_cr3() !=
130-
(__sme_pa(real_prev->pgd) | prev_asid))) {
129+
if (WARN_ON_ONCE(__read_cr3() != build_cr3(real_prev, prev_asid))) {
131130
/*
132131
* If we were to BUG here, we'd be very likely to kill
133132
* the system so hard that we don't see the call trace.
@@ -172,7 +171,7 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
172171
*/
173172
this_cpu_write(cpu_tlbstate.ctxs[prev_asid].tlb_gen,
174173
next_tlb_gen);
175-
write_cr3(__sme_pa(next->pgd) | prev_asid);
174+
write_cr3(build_cr3(next, prev_asid));
176175
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH,
177176
TLB_FLUSH_ALL);
178177
}
@@ -216,12 +215,12 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
216215
if (need_flush) {
217216
this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
218217
this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
219-
write_cr3(__sme_pa(next->pgd) | new_asid);
218+
write_cr3(build_cr3(next, new_asid));
220219
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH,
221220
TLB_FLUSH_ALL);
222221
} else {
223222
/* The new ASID is already up to date. */
224-
write_cr3(__sme_pa(next->pgd) | new_asid | CR3_NOFLUSH);
223+
write_cr3(build_cr3_noflush(next, new_asid));
225224
trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, 0);
226225
}
227226

@@ -265,7 +264,7 @@ void initialize_tlbstate_and_flush(void)
265264
!(cr4_read_shadow() & X86_CR4_PCIDE));
266265

267266
/* Force ASID 0 and force a TLB flush. */
268-
write_cr3(cr3 & ~CR3_PCID_MASK);
267+
write_cr3(build_cr3(mm, 0));
269268

270269
/* Reinitialize tlbstate. */
271270
this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0);

0 commit comments

Comments
 (0)