diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-31 16:03:05 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-12-31 16:03:05 -0500 |
| commit | 52c90f2d32bfa7d6eccd66a56c44ace1f78fbadd (patch) | |
| tree | b6e54081e8da0b050bd06cf51a311f6e11bd0c0a | |
| parent | cea92e843e40452c08ba313abc39f59efbb4c29c (diff) | |
| parent | 7f414195b0c3612acd12b4611a5fe75995cf10c7 (diff) | |
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
| -rw-r--r-- | arch/x86/include/asm/tlbflush.h | 14 | ||||
| -rw-r--r-- | arch/x86/kernel/ldt.c | 9 | ||||
| -rw-r--r-- | arch/x86/kernel/smpboot.c | 9 |
3 files changed, 16 insertions, 16 deletions
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h index f68f9c836cca..4a08dd2ab32a 100644 --- a/arch/x86/include/asm/tlbflush.h +++ b/arch/x86/include/asm/tlbflush.h | |||
| @@ -348,15 +348,17 @@ static inline void invalidate_user_asid(u16 asid) | |||
| 348 | */ | 348 | */ |
| 349 | static inline void __native_flush_tlb(void) | 349 | static inline void __native_flush_tlb(void) |
| 350 | { | 350 | { |
| 351 | invalidate_user_asid(this_cpu_read(cpu_tlbstate.loaded_mm_asid)); | ||
| 352 | /* | 351 | /* |
| 353 | * If current->mm == NULL then we borrow a mm which may change | 352 | * Preemption or interrupts must be disabled to protect the access |
| 354 | * during a task switch and therefore we must not be preempted | 353 | * to the per CPU variable and to prevent being preempted between |
| 355 | * while we write CR3 back: | 354 | * read_cr3() and write_cr3(). |
| 356 | */ | 355 | */ |
| 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 */ | ||
| 358 | native_write_cr3(__native_read_cr3()); | 361 | native_write_cr3(__native_read_cr3()); |
| 359 | preempt_enable(); | ||
| 360 | } | 362 | } |
| 361 | 363 | ||
| 362 | /* | 364 | /* |
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c index 579cc4a66fdf..26d713ecad34 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c | |||
| @@ -421,7 +421,14 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) | |||
| 421 | */ | 421 | */ |
| 422 | error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0); | 422 | error = map_ldt_struct(mm, new_ldt, old_ldt ? !old_ldt->slot : 0); |
| 423 | if (error) { | 423 | 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); | ||
| 425 | goto out_unlock; | 432 | goto out_unlock; |
| 426 | } | 433 | } |
| 427 | 434 | ||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index c5970efa8557..ed556d50d7ed 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -126,14 +126,10 @@ static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) | |||
| 126 | spin_lock_irqsave(&rtc_lock, flags); | 126 | spin_lock_irqsave(&rtc_lock, flags); |
| 127 | CMOS_WRITE(0xa, 0xf); | 127 | CMOS_WRITE(0xa, 0xf); |
| 128 | spin_unlock_irqrestore(&rtc_lock, flags); | 128 | spin_unlock_irqrestore(&rtc_lock, flags); |
| 129 | local_flush_tlb(); | ||
| 130 | pr_debug("1.\n"); | ||
| 131 | *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) = | 129 | *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_HIGH)) = |
| 132 | start_eip >> 4; | 130 | start_eip >> 4; |
| 133 | pr_debug("2.\n"); | ||
| 134 | *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = | 131 | *((volatile unsigned short *)phys_to_virt(TRAMPOLINE_PHYS_LOW)) = |
| 135 | start_eip & 0xf; | 132 | start_eip & 0xf; |
| 136 | pr_debug("3.\n"); | ||
| 137 | } | 133 | } |
| 138 | 134 | ||
| 139 | static inline void smpboot_restore_warm_reset_vector(void) | 135 | static inline void smpboot_restore_warm_reset_vector(void) |
| @@ -141,11 +137,6 @@ static inline void smpboot_restore_warm_reset_vector(void) | |||
| 141 | unsigned long flags; | 137 | unsigned long flags; |
| 142 | 138 | ||
| 143 | /* | 139 | /* |
| 144 | * Install writable page 0 entry to set BIOS data area. | ||
| 145 | */ | ||
| 146 | local_flush_tlb(); | ||
| 147 | |||
| 148 | /* | ||
| 149 | * Paranoid: Set warm reset code and vector here back | 140 | * Paranoid: Set warm reset code and vector here back |
| 150 | * to default values. | 141 | * to default values. |
| 151 | */ | 142 | */ |
