Commit 52c90f2d authored by Linus Torvalds's avatar Linus Torvalds

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
parents cea92e84 7f414195
...@@ -348,15 +348,17 @@ static inline void invalidate_user_asid(u16 asid) ...@@ -348,15 +348,17 @@ static inline void invalidate_user_asid(u16 asid)
*/ */
static inline void __native_flush_tlb(void) static inline void __native_flush_tlb(void)
{ {
invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
/* /*
* If current->mm == NULL then we borrow a mm which may change * Preemption or interrupts must be disabled to protect the access
* during a task switch and therefore we must not be preempted * to the per CPU variable and to prevent being preempted between
* while we write CR3 back: * read_cr3() and write_cr3().
*/ */
preempt_disable(); WARN_ON_ONCE(preemptible());
invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid));
/* If current->mm == NULL then the read_cr3() "borrows" an mm */
native_write_cr3(__native_read_cr3()); native_write_cr3(__native_read_cr3());
preempt_enable();
} }
/* /*
......
...@@ -421,7 +421,14 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) ...@@ -421,7 +421,14 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode)
*/ */
error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0); error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0);
if (error) { if (error) {
free_ldt_struct(old_ldt); /*
* This only can fail for the first LDT setup. If an LDT is
* already installed then the PTE page is already
* populated. Mop up a half populated page table.
*/
if (!WARN_ON_ONCE(old_ldt))
free_ldt_pgtables(mm);
free_ldt_struct(new_ldt);
goto out_unlock; goto out_unlock;
} }
......
...@@ -126,25 +126,16 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) ...@@ -126,25 +126,16 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip)
spin_lock_irqsave(&rtc_lock, flags); spin_lock_irqsave(&rtc_lock, flags);
CMOS_WRITE(0xa, 0xf); CMOS_WRITE(0xa, 0xf);
spin_unlock_irqrestore(&rtc_lock, flags); spin_unlock_irqrestore(&rtc_lock, flags);
local_flush_tlb();
pr_debug("1.\n");
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) = *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) =
start_eip >> 4; start_eip >> 4;
pr_debug("2.\n");
*((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) =
start_eip & 0xf; start_eip & 0xf;
pr_debug("3.\n");
} }
static inline void smpboot_restore_warm_reset_vector(void) static inline void smpboot_restore_warm_reset_vector(void)
{ {
unsigned long flags; unsigned long flags;
/*
* Install writable page 0 entry to set BIOS data area.
*/
local_flush_tlb();
/* /*
* Paranoid: Set warm reset code and vector here back * Paranoid: Set warm reset code and vector here back
* to default values. * to default values.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment