aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r--arch/x86/kernel/alternative.c5
-rw-r--r--arch/x86/kernel/apic/apic.c7
-rw-r--r--arch/x86/kernel/apic/io_apic.c5
-rw-r--r--arch/x86/kernel/apic/vector.c4
-rw-r--r--arch/x86/kernel/cpu/common.c4
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c5
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_bts.c1
-rw-r--r--arch/x86/kernel/irq_32.c19
-rw-r--r--arch/x86/kernel/irq_64.c2
-rw-r--r--arch/x86/kernel/ldt.c4
-rw-r--r--arch/x86/kernel/pci-dma.c2
-rw-r--r--arch/x86/kernel/tsc.c17
-rw-r--r--arch/x86/kernel/vm86_32.c27
13 files changed, 71 insertions, 31 deletions
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
index c42827eb86cf..25f909362b7a 100644
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -338,10 +338,15 @@ done:
338 338
339static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr) 339static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr)
340{ 340{
341 unsigned long flags;
342
341 if (instr[0] != 0x90) 343 if (instr[0] != 0x90)
342 return; 344 return;
343 345
346 local_irq_save(flags);
344 add_nops(instr + (a->instrlen - a->padlen), a->padlen); 347 add_nops(instr + (a->instrlen - a->padlen), a->padlen);
348 sync_core();
349 local_irq_restore(flags);
345 350
346 DUMP_BYTES(instr, a->instrlen, "%p: [%d:%d) optimized NOPs: ", 351 DUMP_BYTES(instr, a->instrlen, "%p: [%d:%d) optimized NOPs: ",
347 instr, a->instrlen - a->padlen, a->padlen); 352 instr, a->instrlen - a->padlen, a->padlen);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 3ca3e46aa405..24e94ce454e2 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -336,6 +336,13 @@ static void __setup_APIC_LVTT(unsigned int clocks, int oneshot, int irqen)
336 apic_write(APIC_LVTT, lvtt_value); 336 apic_write(APIC_LVTT, lvtt_value);
337 337
338 if (lvtt_value & APIC_LVT_TIMER_TSCDEADLINE) { 338 if (lvtt_value & APIC_LVT_TIMER_TSCDEADLINE) {
339 /*
340 * See Intel SDM: TSC-Deadline Mode chapter. In xAPIC mode,
341 * writing to the APIC LVTT and TSC_DEADLINE MSR isn't serialized.
342 * According to Intel, MFENCE can do the serialization here.
343 */
344 asm volatile("mfence" : : : "memory");
345
339 printk_once(KERN_DEBUG "TSC deadline timer enabled\n"); 346 printk_once(KERN_DEBUG "TSC deadline timer enabled\n");
340 return; 347 return;
341 } 348 }
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 38a76f826530..5c60bb162622 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -2522,6 +2522,7 @@ void __init setup_ioapic_dest(void)
2522 int pin, ioapic, irq, irq_entry; 2522 int pin, ioapic, irq, irq_entry;
2523 const struct cpumask *mask; 2523 const struct cpumask *mask;
2524 struct irq_data *idata; 2524 struct irq_data *idata;
2525 struct irq_chip *chip;
2525 2526
2526 if (skip_ioapic_setup == 1) 2527 if (skip_ioapic_setup == 1)
2527 return; 2528 return;
@@ -2545,9 +2546,9 @@ void __init setup_ioapic_dest(void)
2545 else 2546 else
2546 mask = apic->target_cpus(); 2547 mask = apic->target_cpus();
2547 2548
2548 irq_set_affinity(irq, mask); 2549 chip = irq_data_get_irq_chip(idata);
2550 chip->irq_set_affinity(idata, mask, false);
2549 } 2551 }
2550
2551} 2552}
2552#endif 2553#endif
2553 2554
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 1bbd0fe2c806..836d11b92811 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -489,10 +489,8 @@ static int apic_set_affinity(struct irq_data *irq_data,
489 489
490 err = assign_irq_vector(irq, data, dest); 490 err = assign_irq_vector(irq, data, dest);
491 if (err) { 491 if (err) {
492 struct irq_data *top = irq_get_irq_data(irq);
493
494 if (assign_irq_vector(irq, data, 492 if (assign_irq_vector(irq, data,
495 irq_data_get_affinity_mask(top))) 493 irq_data_get_affinity_mask(irq_data)))
496 pr_err("Failed to recover vector for irq %d\n", irq); 494 pr_err("Failed to recover vector for irq %d\n", irq);
497 return err; 495 return err;
498 } 496 }
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 07ce52c22ec8..de22ea7ff82f 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1110,10 +1110,10 @@ void print_cpu_info(struct cpuinfo_x86 *c)
1110 else 1110 else
1111 printk(KERN_CONT "%d86", c->x86); 1111 printk(KERN_CONT "%d86", c->x86);
1112 1112
1113 printk(KERN_CONT " (fam: %02x, model: %02x", c->x86, c->x86_model); 1113 printk(KERN_CONT " (family: 0x%x, model: 0x%x", c->x86, c->x86_model);
1114 1114
1115 if (c->x86_mask || c->cpuid_level >= 0) 1115 if (c->x86_mask || c->cpuid_level >= 0)
1116 printk(KERN_CONT ", stepping: %02x)\n", c->x86_mask); 1116 printk(KERN_CONT ", stepping: 0x%x)\n", c->x86_mask);
1117 else 1117 else
1118 printk(KERN_CONT ")\n"); 1118 printk(KERN_CONT ")\n");
1119 1119
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index cd9b6d0b10bf..3fefebfbdf4b 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -2316,9 +2316,12 @@ static struct event_constraint *
2316intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx, 2316intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx,
2317 struct perf_event *event) 2317 struct perf_event *event)
2318{ 2318{
2319 struct event_constraint *c1 = cpuc->event_constraint[idx]; 2319 struct event_constraint *c1 = NULL;
2320 struct event_constraint *c2; 2320 struct event_constraint *c2;
2321 2321
2322 if (idx >= 0) /* fake does < 0 */
2323 c1 = cpuc->event_constraint[idx];
2324
2322 /* 2325 /*
2323 * first time only 2326 * first time only
2324 * - static constraint: no change across incremental scheduling calls 2327 * - static constraint: no change across incremental scheduling calls
diff --git a/arch/x86/kernel/cpu/perf_event_intel_bts.c b/arch/x86/kernel/cpu/perf_event_intel_bts.c
index 54690e885759..d1c0f254afbe 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_bts.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_bts.c
@@ -222,6 +222,7 @@ static void __bts_event_start(struct perf_event *event)
222 if (!buf || bts_buffer_is_full(buf, bts)) 222 if (!buf || bts_buffer_is_full(buf, bts))
223 return; 223 return;
224 224
225 event->hw.itrace_started = 1;
225 event->hw.state = 0; 226 event->hw.state = 0;
226 227
227 if (!buf->snapshot) 228 if (!buf->snapshot)
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index c80cf6699678..38da8f29a9c8 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -68,11 +68,10 @@ static inline void *current_stack(void)
68 return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1)); 68 return (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1));
69} 69}
70 70
71static inline int 71static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
72execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq)
73{ 72{
74 struct irq_stack *curstk, *irqstk; 73 struct irq_stack *curstk, *irqstk;
75 u32 *isp, *prev_esp, arg1, arg2; 74 u32 *isp, *prev_esp, arg1;
76 75
77 curstk = (struct irq_stack *) current_stack(); 76 curstk = (struct irq_stack *) current_stack();
78 irqstk = __this_cpu_read(hardirq_stack); 77 irqstk = __this_cpu_read(hardirq_stack);
@@ -98,8 +97,8 @@ execute_on_irq_stack(int overflow, struct irq_desc *desc, int irq)
98 asm volatile("xchgl %%ebx,%%esp \n" 97 asm volatile("xchgl %%ebx,%%esp \n"
99 "call *%%edi \n" 98 "call *%%edi \n"
100 "movl %%ebx,%%esp \n" 99 "movl %%ebx,%%esp \n"
101 : "=a" (arg1), "=d" (arg2), "=b" (isp) 100 : "=a" (arg1), "=b" (isp)
102 : "0" (irq), "1" (desc), "2" (isp), 101 : "0" (desc), "1" (isp),
103 "D" (desc->handle_irq) 102 "D" (desc->handle_irq)
104 : "memory", "cc", "ecx"); 103 : "memory", "cc", "ecx");
105 return 1; 104 return 1;
@@ -150,19 +149,15 @@ void do_softirq_own_stack(void)
150 149
151bool handle_irq(struct irq_desc *desc, struct pt_regs *regs) 150bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
152{ 151{
153 unsigned int irq; 152 int overflow = check_stack_overflow();
154 int overflow;
155
156 overflow = check_stack_overflow();
157 153
158 if (IS_ERR_OR_NULL(desc)) 154 if (IS_ERR_OR_NULL(desc))
159 return false; 155 return false;
160 156
161 irq = irq_desc_get_irq(desc); 157 if (user_mode(regs) || !execute_on_irq_stack(overflow, desc)) {
162 if (user_mode(regs) || !execute_on_irq_stack(overflow, desc, irq)) {
163 if (unlikely(overflow)) 158 if (unlikely(overflow))
164 print_stack_overflow(); 159 print_stack_overflow();
165 generic_handle_irq_desc(irq, desc); 160 generic_handle_irq_desc(desc);
166 } 161 }
167 162
168 return true; 163 return true;
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index ff16ccb918f2..c767cf2bc80a 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -75,6 +75,6 @@ bool handle_irq(struct irq_desc *desc, struct pt_regs *regs)
75 if (unlikely(IS_ERR_OR_NULL(desc))) 75 if (unlikely(IS_ERR_OR_NULL(desc)))
76 return false; 76 return false;
77 77
78 generic_handle_irq_desc(irq_desc_get_irq(desc), desc); 78 generic_handle_irq_desc(desc);
79 return true; 79 return true;
80} 80}
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
index 2bcc0525f1c1..6acc9dd91f36 100644
--- a/arch/x86/kernel/ldt.c
+++ b/arch/x86/kernel/ldt.c
@@ -58,7 +58,7 @@ static struct ldt_struct *alloc_ldt_struct(int size)
58 if (alloc_size > PAGE_SIZE) 58 if (alloc_size > PAGE_SIZE)
59 new_ldt->entries = vzalloc(alloc_size); 59 new_ldt->entries = vzalloc(alloc_size);
60 else 60 else
61 new_ldt->entries = kzalloc(PAGE_SIZE, GFP_KERNEL); 61 new_ldt->entries = (void *)get_zeroed_page(GFP_KERNEL);
62 62
63 if (!new_ldt->entries) { 63 if (!new_ldt->entries) {
64 kfree(new_ldt); 64 kfree(new_ldt);
@@ -95,7 +95,7 @@ static void free_ldt_struct(struct ldt_struct *ldt)
95 if (ldt->size * LDT_ENTRY_SIZE > PAGE_SIZE) 95 if (ldt->size * LDT_ENTRY_SIZE > PAGE_SIZE)
96 vfree(ldt->entries); 96 vfree(ldt->entries);
97 else 97 else
98 kfree(ldt->entries); 98 free_page((unsigned long)ldt->entries);
99 kfree(ldt); 99 kfree(ldt);
100} 100}
101 101
diff --git a/arch/x86/kernel/pci-dma.c b/arch/x86/kernel/pci-dma.c
index 84b8ef82a159..1b55de1267cf 100644
--- a/arch/x86/kernel/pci-dma.c
+++ b/arch/x86/kernel/pci-dma.c
@@ -131,8 +131,8 @@ void dma_generic_free_coherent(struct device *dev, size_t size, void *vaddr,
131 131
132bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp) 132bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp)
133{ 133{
134 *gfp = dma_alloc_coherent_gfp_flags(*dev, *gfp);
135 *gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32); 134 *gfp &= ~(__GFP_DMA | __GFP_HIGHMEM | __GFP_DMA32);
135 *gfp = dma_alloc_coherent_gfp_flags(*dev, *gfp);
136 136
137 if (!*dev) 137 if (!*dev)
138 *dev = &x86_dma_fallback_dev; 138 *dev = &x86_dma_fallback_dev;
diff --git a/arch/x86/kernel/tsc.c b/arch/x86/kernel/tsc.c
index c8d52cb4cb6e..c3f7602cd038 100644
--- a/arch/x86/kernel/tsc.c
+++ b/arch/x86/kernel/tsc.c
@@ -21,6 +21,7 @@
21#include <asm/hypervisor.h> 21#include <asm/hypervisor.h>
22#include <asm/nmi.h> 22#include <asm/nmi.h>
23#include <asm/x86_init.h> 23#include <asm/x86_init.h>
24#include <asm/geode.h>
24 25
25unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ 26unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */
26EXPORT_SYMBOL(cpu_khz); 27EXPORT_SYMBOL(cpu_khz);
@@ -1013,15 +1014,17 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable);
1013 1014
1014static void __init check_system_tsc_reliable(void) 1015static void __init check_system_tsc_reliable(void)
1015{ 1016{
1016#ifdef CONFIG_MGEODE_LX 1017#if defined(CONFIG_MGEODEGX1) || defined(CONFIG_MGEODE_LX) || defined(CONFIG_X86_GENERIC)
1017 /* RTSC counts during suspend */ 1018 if (is_geode_lx()) {
1019 /* RTSC counts during suspend */
1018#define RTSC_SUSP 0x100 1020#define RTSC_SUSP 0x100
1019 unsigned long res_low, res_high; 1021 unsigned long res_low, res_high;
1020 1022
1021 rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); 1023 rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high);
1022 /* Geode_LX - the OLPC CPU has a very reliable TSC */ 1024 /* Geode_LX - the OLPC CPU has a very reliable TSC */
1023 if (res_low & RTSC_SUSP) 1025 if (res_low & RTSC_SUSP)
1024 tsc_clocksource_reliable = 1; 1026 tsc_clocksource_reliable = 1;
1027 }
1025#endif 1028#endif
1026 if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE)) 1029 if (boot_cpu_has(X86_FEATURE_TSC_RELIABLE))
1027 tsc_clocksource_reliable = 1; 1030 tsc_clocksource_reliable = 1;
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index abd8b856bd2b..524619351961 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -45,6 +45,7 @@
45#include <linux/audit.h> 45#include <linux/audit.h>
46#include <linux/stddef.h> 46#include <linux/stddef.h>
47#include <linux/slab.h> 47#include <linux/slab.h>
48#include <linux/security.h>
48 49
49#include <asm/uaccess.h> 50#include <asm/uaccess.h>
50#include <asm/io.h> 51#include <asm/io.h>
@@ -232,6 +233,32 @@ static long do_sys_vm86(struct vm86plus_struct __user *user_vm86, bool plus)
232 struct pt_regs *regs = current_pt_regs(); 233 struct pt_regs *regs = current_pt_regs();
233 unsigned long err = 0; 234 unsigned long err = 0;
234 235
236 err = security_mmap_addr(0);
237 if (err) {
238 /*
239 * vm86 cannot virtualize the address space, so vm86 users
240 * need to manage the low 1MB themselves using mmap. Given
241 * that BIOS places important data in the first page, vm86
242 * is essentially useless if mmap_min_addr != 0. DOSEMU,
243 * for example, won't even bother trying to use vm86 if it
244 * can't map a page at virtual address 0.
245 *
246 * To reduce the available kernel attack surface, simply
247 * disallow vm86(old) for users who cannot mmap at va 0.
248 *
249 * The implementation of security_mmap_addr will allow
250 * suitably privileged users to map va 0 even if
251 * vm.mmap_min_addr is set above 0, and we want this
252 * behavior for vm86 as well, as it ensures that legacy
253 * tools like vbetool will not fail just because of
254 * vm.mmap_min_addr.
255 */
256 pr_info_once("Denied a call to vm86(old) from %s[%d] (uid: %d). Set the vm.mmap_min_addr sysctl to 0 and/or adjust LSM mmap_min_addr policy to enable vm86 if you are using a vm86-based DOS emulator.\n",
257 current->comm, task_pid_nr(current),
258 from_kuid_munged(&init_user_ns, current_uid()));
259 return -EPERM;
260 }
261
235 if (!vm86) { 262 if (!vm86) {
236 if (!(vm86 = kzalloc(sizeof(*vm86), GFP_KERNEL))) 263 if (!(vm86 = kzalloc(sizeof(*vm86), GFP_KERNEL)))
237 return -ENOMEM; 264 return -ENOMEM;