Skip to content

Commit 52c90f2

Browse files
committed
Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 page table isolation fixes from Thomas Gleixner: "Four patches addressing the PTI fallout as discussed and debugged yesterday: - Remove stale and pointless TLB flush invocations from the hotplug code - Remove stale preempt_disable/enable from __native_flush_tlb() - Plug the memory leak in the write_ldt() error path" * 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/ldt: Make LDT pgtable free conditional x86/ldt: Plug memory leak in error path x86/mm: Remove preempt_disable/enable() from __native_flush_tlb() x86/smpboot: Remove stale TLB flush invocations
2 parents cea92e8 + 7f41419 commit 52c90f2

File tree

3 files changed

+16
-16
lines changed

3 files changed

+16
-16
lines changed

arch/x86/include/asm/tlbflush.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -348,15 +348,17 @@ static inline void invalidate_user_asid(u16 asid)
348348
*/
349349
static inline void __native_flush_tlb(void)
350350
{
351-
invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
352351
/*
353-
* If current->mm == NULL then we borrow a mm which may change
354-
* during a task switch and therefore we must not be preempted
355-
* while we write CR3 back:
352+
* Preemption or interrupts must be disabled to protect the access
353+
* to the per CPU variable and to prevent being preempted between
354+
* read_cr3() and write_cr3().
356355
*/
357-
preempt_disable();
356+
WARN_ON_ONCE(preemptible());
357+
358+
invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
359+
360+
/* If current->mm == NULL then the read_cr3() "borrows" an mm */
358361
native_write_cr3(__native_read_cr3());
359-
preempt_enable();
360362
}
361363

362364
/*

arch/x86/kernel/ldt.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,14 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
421421
*/
422422
error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0);
423423
if (error) {
424-
free_ldt_struct(old_ldt);
424+
/*
425+
* This only can fail for the first LDT setup. If an LDT is
426+
* already installed then the PTE page is already
427+
* populated. Mop up a half populated page table.
428+
*/
429+
if (!WARN_ON_ONCE(old_ldt))
430+
free_ldt_pgtables(mm);
431+
free_ldt_struct(new_ldt);
425432
goto out_unlock;
426433
}
427434

arch/x86/kernel/smpboot.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,25 +126,16 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
126126
spin_lock_irqsave(&rtc_lock, flags);
127127
CMOS_WRITE(0xa, 0xf);
128128
spin_unlock_irqrestore(&rtc_lock, flags);
129-
local_flush_tlb();
130-
pr_debug("1.\n");
131129
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
132130
start_eip >> 4;
133-
pr_debug("2.\n");
134131
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
135132
start_eip & 0xf;
136-
pr_debug("3.\n");
137133
}
138134

139135
static inline void smpboot_restore_warm_reset_vector(void)
140136
{
141137
unsigned long flags;
142138

143-
/*
144-
* Install writable page 0 entry to set BIOS data area.
145-
*/
146-
local_flush_tlb();
147-
148139
/*
149140
* Paranoid: Set warm reset code and vector here back
150141
* to default values.

0 commit comments

Comments
 (0)