aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-05 15:14:50 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-05 15:14:50 -0500
commit9b3499d752fc292f37503e5c3a5e5df4f7e76d42 (patch)
tree07f2c8c9d191be7b2b0ad836136be1ef753697fa
parentb21172cf6dc6e2af21346e774ea2e7c784de30bd (diff)
parenteda9cec4c9a12208a6f69fbe68f72a6311d50032 (diff)
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar: "Two fixes: - A PCID related revert that fixes power management and performance regressions. - The module loader robustization and sanity check commit is rather fresh, but it looked like a good idea to apply because of the hidden data corruption problem such invalid modules could cause" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/module: Detect and skip invalid relocations Revert "x86/mm: Stop calling leave_mm() in idle code"
-rw-r--r--arch/ia64/include/asm/acpi.h2
-rw-r--r--arch/x86/include/asm/acpi.h2
-rw-r--r--arch/x86/kernel/module.c13
-rw-r--r--arch/x86/mm/tlb.c17
-rw-r--r--drivers/acpi/processor_idle.c2
-rw-r--r--drivers/idle/intel_idle.c9
6 files changed, 38 insertions, 7 deletions
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h
index c86a947f5368..a3d0211970e9 100644
--- a/arch/ia64/include/asm/acpi.h
+++ b/arch/ia64/include/asm/acpi.h
@@ -112,6 +112,8 @@ static inline void arch_acpi_set_pdc_bits(u32 *buf)
112 buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP; 112 buf[2] |= ACPI_PDC_EST_CAPABILITY_SMP;
113} 113}
114 114
115#define acpi_unlazy_tlb(x)
116
115#ifdef CONFIG_ACPI_NUMA 117#ifdef CONFIG_ACPI_NUMA
116extern cpumask_t early_cpu_possible_map; 118extern cpumask_t early_cpu_possible_map;
117#define for_each_possible_early_cpu(cpu) \ 119#define for_each_possible_early_cpu(cpu) \
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h
index 72d867f6b518..8d0ec9df1cbe 100644
--- a/arch/x86/include/asm/acpi.h
+++ b/arch/x86/include/asm/acpi.h
@@ -150,6 +150,8 @@ static inline void disable_acpi(void) { }
150extern int x86_acpi_numa_init(void); 150extern int x86_acpi_numa_init(void);
151#endif /* CONFIG_ACPI_NUMA */ 151#endif /* CONFIG_ACPI_NUMA */
152 152
153#define acpi_unlazy_tlb(x) leave_mm(x)
154
153#ifdef CONFIG_ACPI_APEI 155#ifdef CONFIG_ACPI_APEI
154static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr) 156static inline pgprot_t arch_apei_get_mem_attribute(phys_addr_t addr)
155{ 157{
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 62e7d70aadd5..da0c160e5589 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -172,19 +172,27 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
172 case R_X86_64_NONE: 172 case R_X86_64_NONE:
173 break; 173 break;
174 case R_X86_64_64: 174 case R_X86_64_64:
175 if (*(u64 *)loc != 0)
176 goto invalid_relocation;
175 *(u64 *)loc = val; 177 *(u64 *)loc = val;
176 break; 178 break;
177 case R_X86_64_32: 179 case R_X86_64_32:
180 if (*(u32 *)loc != 0)
181 goto invalid_relocation;
178 *(u32 *)loc = val; 182 *(u32 *)loc = val;
179 if (val != *(u32 *)loc) 183 if (val != *(u32 *)loc)
180 goto overflow; 184 goto overflow;
181 break; 185 break;
182 case R_X86_64_32S: 186 case R_X86_64_32S:
187 if (*(s32 *)loc != 0)
188 goto invalid_relocation;
183 *(s32 *)loc = val; 189 *(s32 *)loc = val;
184 if ((s64)val != *(s32 *)loc) 190 if ((s64)val != *(s32 *)loc)
185 goto overflow; 191 goto overflow;
186 break; 192 break;
187 case R_X86_64_PC32: 193 case R_X86_64_PC32:
194 if (*(u32 *)loc != 0)
195 goto invalid_relocation;
188 val -= (u64)loc; 196 val -= (u64)loc;
189 *(u32 *)loc = val; 197 *(u32 *)loc = val;
190#if 0 198#if 0
@@ -200,6 +208,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
200 } 208 }
201 return 0; 209 return 0;
202 210
211invalid_relocation:
212 pr_err("x86/modules: Skipping invalid relocation target, existing value is nonzero for type %d, loc %p, val %Lx\n",
213 (int)ELF64_R_TYPE(rel[i].r_info), loc, val);
214 return -ENOEXEC;
215
203overflow: 216overflow:
204 pr_err("overflow in relocation type %d val %Lx\n", 217 pr_err("overflow in relocation type %d val %Lx\n",
205 (int)ELF64_R_TYPE(rel[i].r_info), val); 218 (int)ELF64_R_TYPE(rel[i].r_info), val);
diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c
index 0f3d0cea4d00..3118392cdf75 100644
--- a/arch/x86/mm/tlb.c
+++ b/arch/x86/mm/tlb.c
@@ -85,6 +85,7 @@ void leave_mm(int cpu)
85 85
86 switch_mm(NULL, &init_mm, NULL); 86 switch_mm(NULL, &init_mm, NULL);
87} 87}
88EXPORT_SYMBOL_GPL(leave_mm);
88 89
89void switch_mm(struct mm_struct *prev, struct mm_struct *next, 90void switch_mm(struct mm_struct *prev, struct mm_struct *next,
90 struct task_struct *tsk) 91 struct task_struct *tsk)
@@ -195,12 +196,22 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next,
195 this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id); 196 this_cpu_write(cpu_tlbstate.ctxs[new_asid].ctx_id, next->context.ctx_id);
196 this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen); 197 this_cpu_write(cpu_tlbstate.ctxs[new_asid].tlb_gen, next_tlb_gen);
197 write_cr3(build_cr3(next, new_asid)); 198 write_cr3(build_cr3(next, new_asid));
198 trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, 199
199 TLB_FLUSH_ALL); 200 /*
201 * NB: This gets called via leave_mm() in the idle path
202 * where RCU functions differently. Tracing normally
203 * uses RCU, so we need to use the _rcuidle variant.
204 *
205 * (There is no good reason for this. The idle code should
206 * be rearranged to call this before rcu_idle_enter().)
207 */
208 trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, TLB_FLUSH_ALL);
200 } else { 209 } else {
201 /* The new ASID is already up to date. */ 210 /* The new ASID is already up to date. */
202 write_cr3(build_cr3_noflush(next, new_asid)); 211 write_cr3(build_cr3_noflush(next, new_asid));
203 trace_tlb_flush(TLB_FLUSH_ON_TASK_SWITCH, 0); 212
213 /* See above wrt _rcuidle. */
214 trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0);
204 } 215 }
205 216
206 this_cpu_write(cpu_tlbstate.loaded_mm, next); 217 this_cpu_write(cpu_tlbstate.loaded_mm, next);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 2736e25e9dc6..d50a7b6ccddd 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -710,6 +710,8 @@ static DEFINE_RAW_SPINLOCK(c3_lock);
710static void acpi_idle_enter_bm(struct acpi_processor *pr, 710static void acpi_idle_enter_bm(struct acpi_processor *pr,
711 struct acpi_processor_cx *cx, bool timer_bc) 711 struct acpi_processor_cx *cx, bool timer_bc)
712{ 712{
713 acpi_unlazy_tlb(smp_processor_id());
714
713 /* 715 /*
714 * Must be done before busmaster disable as we might need to 716 * Must be done before busmaster disable as we might need to
715 * access HPET ! 717 * access HPET !
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c
index 5dc7ea4b6bc4..f0b06b14e782 100644
--- a/drivers/idle/intel_idle.c
+++ b/drivers/idle/intel_idle.c
@@ -913,15 +913,16 @@ static __cpuidle int intel_idle(struct cpuidle_device *dev,
913 struct cpuidle_state *state = &drv->states[index]; 913 struct cpuidle_state *state = &drv->states[index];
914 unsigned long eax = flg2MWAIT(state->flags); 914 unsigned long eax = flg2MWAIT(state->flags);
915 unsigned int cstate; 915 unsigned int cstate;
916 int cpu = smp_processor_id();
916 917
917 cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1; 918 cstate = (((eax) >> MWAIT_SUBSTATE_SIZE) & MWAIT_CSTATE_MASK) + 1;
918 919
919 /* 920 /*
920 * NB: if CPUIDLE_FLAG_TLB_FLUSHED is set, this idle transition 921 * leave_mm() to avoid costly and often unnecessary wakeups
921 * will probably flush the TLB. It's not guaranteed to flush 922 * for flushing the user TLB's associated with the active mm.
922 * the TLB, though, so it's not clear that we can do anything
923 * useful with this knowledge.
924 */ 923 */
924 if (state->flags & CPUIDLE_FLAG_TLB_FLUSHED)
925 leave_mm(cpu);
925 926
926 if (!(lapic_timer_reliable_states & (1 << (cstate)))) 927 if (!(lapic_timer_reliable_states & (1 << (cstate))))
927 tick_broadcast_enter(); 928 tick_broadcast_enter();