diff options
Diffstat (limited to 'arch/x86/kernel')
-rw-r--r-- | arch/x86/kernel/alternative.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/apic/apic.c | 7 | ||||
-rw-r--r-- | arch/x86/kernel/apic/io_apic.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/apic/vector.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel.c | 5 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_bts.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/irq_32.c | 19 | ||||
-rw-r--r-- | arch/x86/kernel/irq_64.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/ldt.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/pci-dma.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 17 | ||||
-rw-r--r-- | arch/x86/kernel/vm86_32.c | 27 |
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 | ||
339 | static void __init_or_module optimize_nops(struct alt_instr *a, u8 *instr) | 339 | static 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 * | |||
2316 | intel_get_event_constraints(struct cpu_hw_events *cpuc, int idx, | 2316 | intel_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 | ||
71 | static inline int | 71 | static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc) |
72 | execute_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 | ||
151 | bool handle_irq(struct irq_desc *desc, struct pt_regs *regs) | 150 | bool 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 | ||
132 | bool arch_dma_alloc_attrs(struct device **dev, gfp_t *gfp) | 132 | bool 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 | ||
25 | unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ | 26 | unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */ |
26 | EXPORT_SYMBOL(cpu_khz); | 27 | EXPORT_SYMBOL(cpu_khz); |
@@ -1013,15 +1014,17 @@ EXPORT_SYMBOL_GPL(mark_tsc_unstable); | |||
1013 | 1014 | ||
1014 | static void __init check_system_tsc_reliable(void) | 1015 | static 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; |