diff options
author | Ingo Molnar <mingo@kernel.org> | 2015-01-28 09:30:32 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2015-01-28 09:30:32 -0500 |
commit | 41ca5d4e9be11ea6ae040b51d9628a189fd82896 (patch) | |
tree | f9c35cc37b9622f6cccd91b94548f44b9a534029 /arch/x86 | |
parent | 0fcedc8631ec28ca25d3c0b116e8fa0c19dd5f6d (diff) | |
parent | 3669ef9fa7d35f573ec9c0e0341b29251c2734a7 (diff) |
Merge commit 3669ef9fa7d3 ("x86, tls: Interpret an all-zero struct user_desc as 'no segment'") into x86/asm
Pick up the latestest asm fixes before advancing it any further.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/boot/compressed/misc.c | 9 | ||||
-rw-r--r-- | arch/x86/include/asm/acpi.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/desc.h | 20 | ||||
-rw-r--r-- | arch/x86/include/asm/mmu_context.h | 20 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/boot.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/mshyperv.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_ds.c | 4 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/perf_event_intel_rapl.c | 44 | ||||
-rw-r--r-- | arch/x86/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/kprobes/core.c | 20 | ||||
-rw-r--r-- | arch/x86/kernel/tls.c | 25 | ||||
-rw-r--r-- | arch/x86/mm/mpx.c | 6 | ||||
-rw-r--r-- | arch/x86/mm/pat.c | 7 | ||||
-rw-r--r-- | arch/x86/pci/xen.c | 49 |
14 files changed, 143 insertions, 91 deletions
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index dcc1c536cc21..a950864a64da 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -373,6 +373,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, | |||
373 | unsigned long output_len, | 373 | unsigned long output_len, |
374 | unsigned long run_size) | 374 | unsigned long run_size) |
375 | { | 375 | { |
376 | unsigned char *output_orig = output; | ||
377 | |||
376 | real_mode = rmode; | 378 | real_mode = rmode; |
377 | 379 | ||
378 | sanitize_boot_params(real_mode); | 380 | sanitize_boot_params(real_mode); |
@@ -421,7 +423,12 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, | |||
421 | debug_putstr("\nDecompressing Linux... "); | 423 | debug_putstr("\nDecompressing Linux... "); |
422 | decompress(input_data, input_len, NULL, NULL, output, NULL, error); | 424 | decompress(input_data, input_len, NULL, NULL, output, NULL, error); |
423 | parse_elf(output); | 425 | parse_elf(output); |
424 | handle_relocations(output, output_len); | 426 | /* |
427 | * 32-bit always performs relocations. 64-bit relocations are only | ||
428 | * needed if kASLR has chosen a different load address. | ||
429 | */ | ||
430 | if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig) | ||
431 | handle_relocations(output, output_len); | ||
425 | debug_putstr("done.\nBooting the kernel.\n"); | 432 | debug_putstr("done.\nBooting the kernel.\n"); |
426 | return output; | 433 | return output; |
427 | } | 434 | } |
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 0ab4f9fd2687..3a45668f6dc3 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
@@ -50,6 +50,7 @@ void acpi_pic_sci_set_trigger(unsigned int, u16); | |||
50 | 50 | ||
51 | extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, | 51 | extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, |
52 | int trigger, int polarity); | 52 | int trigger, int polarity); |
53 | extern void (*__acpi_unregister_gsi)(u32 gsi); | ||
53 | 54 | ||
54 | static inline void disable_acpi(void) | 55 | static inline void disable_acpi(void) |
55 | { | 56 | { |
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h index 50d033a8947d..a94b82e8f156 100644 --- a/arch/x86/include/asm/desc.h +++ b/arch/x86/include/asm/desc.h | |||
@@ -251,7 +251,8 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) | |||
251 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; | 251 | gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; |
252 | } | 252 | } |
253 | 253 | ||
254 | #define _LDT_empty(info) \ | 254 | /* This intentionally ignores lm, since 32-bit apps don't have that field. */ |
255 | #define LDT_empty(info) \ | ||
255 | ((info)->base_addr == 0 && \ | 256 | ((info)->base_addr == 0 && \ |
256 | (info)->limit == 0 && \ | 257 | (info)->limit == 0 && \ |
257 | (info)->contents == 0 && \ | 258 | (info)->contents == 0 && \ |
@@ -261,11 +262,18 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) | |||
261 | (info)->seg_not_present == 1 && \ | 262 | (info)->seg_not_present == 1 && \ |
262 | (info)->useable == 0) | 263 | (info)->useable == 0) |
263 | 264 | ||
264 | #ifdef CONFIG_X86_64 | 265 | /* Lots of programs expect an all-zero user_desc to mean "no segment at all". */ |
265 | #define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) | 266 | static inline bool LDT_zero(const struct user_desc *info) |
266 | #else | 267 | { |
267 | #define LDT_empty(info) (_LDT_empty(info)) | 268 | return (info->base_addr == 0 && |
268 | #endif | 269 | info->limit == 0 && |
270 | info->contents == 0 && | ||
271 | info->read_exec_only == 0 && | ||
272 | info->seg_32bit == 0 && | ||
273 | info->limit_in_pages == 0 && | ||
274 | info->seg_not_present == 0 && | ||
275 | info->useable == 0); | ||
276 | } | ||
269 | 277 | ||
270 | static inline void clear_LDT(void) | 278 | static inline void clear_LDT(void) |
271 | { | 279 | { |
diff --git a/arch/x86/include/asm/mmu_context.h b/arch/x86/include/asm/mmu_context.h index 40269a2bf6f9..4b75d591eb5e 100644 --- a/arch/x86/include/asm/mmu_context.h +++ b/arch/x86/include/asm/mmu_context.h | |||
@@ -130,7 +130,25 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, | |||
130 | static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, | 130 | static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, |
131 | unsigned long start, unsigned long end) | 131 | unsigned long start, unsigned long end) |
132 | { | 132 | { |
133 | mpx_notify_unmap(mm, vma, start, end); | 133 | /* |
134 | * mpx_notify_unmap() goes and reads a rarely-hot | ||
135 | * cacheline in the mm_struct. That can be expensive | ||
136 | * enough to be seen in profiles. | ||
137 | * | ||
138 | * The mpx_notify_unmap() call and its contents have been | ||
139 | * observed to affect munmap() performance on hardware | ||
140 | * where MPX is not present. | ||
141 | * | ||
142 | * The unlikely() optimizes for the fast case: no MPX | ||
143 | * in the CPU, or no MPX use in the process. Even if | ||
144 | * we get this wrong (in the unlikely event that MPX | ||
145 | * is widely enabled on some system) the overhead of | ||
146 | * MPX itself (reading bounds tables) is expected to | ||
147 | * overwhelm the overhead of getting this unlikely() | ||
148 | * consistently wrong. | ||
149 | */ | ||
150 | if (unlikely(cpu_feature_enabled(X86_FEATURE_MPX))) | ||
151 | mpx_notify_unmap(mm, vma, start, end); | ||
134 | } | 152 | } |
135 | 153 | ||
136 | #endif /* _ASM_X86_MMU_CONTEXT_H */ | 154 | #endif /* _ASM_X86_MMU_CONTEXT_H */ |
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index d1626364a28a..b9e30daa0881 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c | |||
@@ -611,20 +611,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) | |||
611 | 611 | ||
612 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) | 612 | int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) |
613 | { | 613 | { |
614 | int irq; | 614 | int rc, irq, trigger, polarity; |
615 | 615 | ||
616 | if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { | 616 | rc = acpi_get_override_irq(gsi, &trigger, &polarity); |
617 | *irqp = gsi; | 617 | if (rc == 0) { |
618 | } else { | 618 | trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; |
619 | mutex_lock(&acpi_ioapic_lock); | 619 | polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; |
620 | irq = mp_map_gsi_to_irq(gsi, | 620 | irq = acpi_register_gsi(NULL, gsi, trigger, polarity); |
621 | IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); | 621 | if (irq >= 0) { |
622 | mutex_unlock(&acpi_ioapic_lock); | 622 | *irqp = irq; |
623 | if (irq < 0) | 623 | return 0; |
624 | return -1; | 624 | } |
625 | *irqp = irq; | ||
626 | } | 625 | } |
627 | return 0; | 626 | |
627 | return -1; | ||
628 | } | 628 | } |
629 | EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); | 629 | EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); |
630 | 630 | ||
diff --git a/arch/x86/kernel/cpu/mshyperv.c b/arch/x86/kernel/cpu/mshyperv.c index a450373e8e91..939155ffdece 100644 --- a/arch/x86/kernel/cpu/mshyperv.c +++ b/arch/x86/kernel/cpu/mshyperv.c | |||
@@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = { | |||
107 | .rating = 400, /* use this when running on Hyperv*/ | 107 | .rating = 400, /* use this when running on Hyperv*/ |
108 | .read = read_hv_clock, | 108 | .read = read_hv_clock, |
109 | .mask = CLOCKSOURCE_MASK(64), | 109 | .mask = CLOCKSOURCE_MASK(64), |
110 | .flags = CLOCK_SOURCE_IS_CONTINUOUS, | ||
110 | }; | 111 | }; |
111 | 112 | ||
112 | static void __init ms_hyperv_init_platform(void) | 113 | static void __init ms_hyperv_init_platform(void) |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 3c895d480cd7..073983398364 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -568,8 +568,8 @@ struct event_constraint intel_atom_pebs_event_constraints[] = { | |||
568 | }; | 568 | }; |
569 | 569 | ||
570 | struct event_constraint intel_slm_pebs_event_constraints[] = { | 570 | struct event_constraint intel_slm_pebs_event_constraints[] = { |
571 | /* UOPS_RETIRED.ALL, inv=1, cmask=16 (cycles:p). */ | 571 | /* INST_RETIRED.ANY_P, inv=1, cmask=16 (cycles:p). */ |
572 | INTEL_FLAGS_EVENT_CONSTRAINT(0x108001c2, 0xf), | 572 | INTEL_FLAGS_EVENT_CONSTRAINT(0x108000c0, 0x1), |
573 | /* Allow all events as PEBS with no flags */ | 573 | /* Allow all events as PEBS with no flags */ |
574 | INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), | 574 | INTEL_ALL_EVENT_CONSTRAINT(0, 0x1), |
575 | EVENT_CONSTRAINT_END | 575 | EVENT_CONSTRAINT_END |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c index 673f930c700f..6e434f8e5fc8 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c +++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c | |||
@@ -103,6 +103,13 @@ static struct kobj_attribute format_attr_##_var = \ | |||
103 | 103 | ||
104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ | 104 | #define RAPL_CNTR_WIDTH 32 /* 32-bit rapl counters */ |
105 | 105 | ||
106 | #define RAPL_EVENT_ATTR_STR(_name, v, str) \ | ||
107 | static struct perf_pmu_events_attr event_attr_##v = { \ | ||
108 | .attr = __ATTR(_name, 0444, rapl_sysfs_show, NULL), \ | ||
109 | .id = 0, \ | ||
110 | .event_str = str, \ | ||
111 | }; | ||
112 | |||
106 | struct rapl_pmu { | 113 | struct rapl_pmu { |
107 | spinlock_t lock; | 114 | spinlock_t lock; |
108 | int hw_unit; /* 1/2^hw_unit Joule */ | 115 | int hw_unit; /* 1/2^hw_unit Joule */ |
@@ -379,23 +386,36 @@ static struct attribute_group rapl_pmu_attr_group = { | |||
379 | .attrs = rapl_pmu_attrs, | 386 | .attrs = rapl_pmu_attrs, |
380 | }; | 387 | }; |
381 | 388 | ||
382 | EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | 389 | static ssize_t rapl_sysfs_show(struct device *dev, |
383 | EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | 390 | struct device_attribute *attr, |
384 | EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | 391 | char *page) |
385 | EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | 392 | { |
393 | struct perf_pmu_events_attr *pmu_attr = \ | ||
394 | container_of(attr, struct perf_pmu_events_attr, attr); | ||
395 | |||
396 | if (pmu_attr->event_str) | ||
397 | return sprintf(page, "%s", pmu_attr->event_str); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | RAPL_EVENT_ATTR_STR(energy-cores, rapl_cores, "event=0x01"); | ||
403 | RAPL_EVENT_ATTR_STR(energy-pkg , rapl_pkg, "event=0x02"); | ||
404 | RAPL_EVENT_ATTR_STR(energy-ram , rapl_ram, "event=0x03"); | ||
405 | RAPL_EVENT_ATTR_STR(energy-gpu , rapl_gpu, "event=0x04"); | ||
386 | 406 | ||
387 | EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); | 407 | RAPL_EVENT_ATTR_STR(energy-cores.unit, rapl_cores_unit, "Joules"); |
388 | EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); | 408 | RAPL_EVENT_ATTR_STR(energy-pkg.unit , rapl_pkg_unit, "Joules"); |
389 | EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); | 409 | RAPL_EVENT_ATTR_STR(energy-ram.unit , rapl_ram_unit, "Joules"); |
390 | EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); | 410 | RAPL_EVENT_ATTR_STR(energy-gpu.unit , rapl_gpu_unit, "Joules"); |
391 | 411 | ||
392 | /* | 412 | /* |
393 | * we compute in 0.23 nJ increments regardless of MSR | 413 | * we compute in 0.23 nJ increments regardless of MSR |
394 | */ | 414 | */ |
395 | EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); | 415 | RAPL_EVENT_ATTR_STR(energy-cores.scale, rapl_cores_scale, "2.3283064365386962890625e-10"); |
396 | EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); | 416 | RAPL_EVENT_ATTR_STR(energy-pkg.scale, rapl_pkg_scale, "2.3283064365386962890625e-10"); |
397 | EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); | 417 | RAPL_EVENT_ATTR_STR(energy-ram.scale, rapl_ram_scale, "2.3283064365386962890625e-10"); |
398 | EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); | 418 | RAPL_EVENT_ATTR_STR(energy-gpu.scale, rapl_gpu_scale, "2.3283064365386962890625e-10"); |
399 | 419 | ||
400 | static struct attribute *rapl_events_srv_attr[] = { | 420 | static struct attribute *rapl_events_srv_attr[] = { |
401 | EVENT_PTR(rapl_cores), | 421 | EVENT_PTR(rapl_cores), |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 6307a0f0cf17..705ef8d48e2d 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -127,7 +127,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) | |||
127 | seq_puts(p, " Machine check polls\n"); | 127 | seq_puts(p, " Machine check polls\n"); |
128 | #endif | 128 | #endif |
129 | #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) | 129 | #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) |
130 | seq_printf(p, "%*s: ", prec, "THR"); | 130 | seq_printf(p, "%*s: ", prec, "HYP"); |
131 | for_each_online_cpu(j) | 131 | for_each_online_cpu(j) |
132 | seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); | 132 | seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); |
133 | seq_puts(p, " Hypervisor callback interrupts\n"); | 133 | seq_puts(p, " Hypervisor callback interrupts\n"); |
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c index f7e3cd50ece0..98f654d466e5 100644 --- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c | |||
@@ -1020,6 +1020,15 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
1020 | regs->flags &= ~X86_EFLAGS_IF; | 1020 | regs->flags &= ~X86_EFLAGS_IF; |
1021 | trace_hardirqs_off(); | 1021 | trace_hardirqs_off(); |
1022 | regs->ip = (unsigned long)(jp->entry); | 1022 | regs->ip = (unsigned long)(jp->entry); |
1023 | |||
1024 | /* | ||
1025 | * jprobes use jprobe_return() which skips the normal return | ||
1026 | * path of the function, and this messes up the accounting of the | ||
1027 | * function graph tracer to get messed up. | ||
1028 | * | ||
1029 | * Pause function graph tracing while performing the jprobe function. | ||
1030 | */ | ||
1031 | pause_graph_tracing(); | ||
1023 | return 1; | 1032 | return 1; |
1024 | } | 1033 | } |
1025 | NOKPROBE_SYMBOL(setjmp_pre_handler); | 1034 | NOKPROBE_SYMBOL(setjmp_pre_handler); |
@@ -1048,24 +1057,25 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
1048 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 1057 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
1049 | u8 *addr = (u8 *) (regs->ip - 1); | 1058 | u8 *addr = (u8 *) (regs->ip - 1); |
1050 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 1059 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
1060 | void *saved_sp = kcb->jprobe_saved_sp; | ||
1051 | 1061 | ||
1052 | if ((addr > (u8 *) jprobe_return) && | 1062 | if ((addr > (u8 *) jprobe_return) && |
1053 | (addr < (u8 *) jprobe_return_end)) { | 1063 | (addr < (u8 *) jprobe_return_end)) { |
1054 | if (stack_addr(regs) != kcb->jprobe_saved_sp) { | 1064 | if (stack_addr(regs) != saved_sp) { |
1055 | struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; | 1065 | struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; |
1056 | printk(KERN_ERR | 1066 | printk(KERN_ERR |
1057 | "current sp %p does not match saved sp %p\n", | 1067 | "current sp %p does not match saved sp %p\n", |
1058 | stack_addr(regs), kcb->jprobe_saved_sp); | 1068 | stack_addr(regs), saved_sp); |
1059 | printk(KERN_ERR "Saved registers for jprobe %p\n", jp); | 1069 | printk(KERN_ERR "Saved registers for jprobe %p\n", jp); |
1060 | show_regs(saved_regs); | 1070 | show_regs(saved_regs); |
1061 | printk(KERN_ERR "Current registers\n"); | 1071 | printk(KERN_ERR "Current registers\n"); |
1062 | show_regs(regs); | 1072 | show_regs(regs); |
1063 | BUG(); | 1073 | BUG(); |
1064 | } | 1074 | } |
1075 | /* It's OK to start function graph tracing again */ | ||
1076 | unpause_graph_tracing(); | ||
1065 | *regs = kcb->jprobe_saved_regs; | 1077 | *regs = kcb->jprobe_saved_regs; |
1066 | memcpy((kprobe_opcode_t *)(kcb->jprobe_saved_sp), | 1078 | memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp)); |
1067 | kcb->jprobes_stack, | ||
1068 | MIN_STACK_SIZE(kcb->jprobe_saved_sp)); | ||
1069 | preempt_enable_no_resched(); | 1079 | preempt_enable_no_resched(); |
1070 | return 1; | 1080 | return 1; |
1071 | } | 1081 | } |
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c index 4e942f31b1a7..7fc5e843f247 100644 --- a/arch/x86/kernel/tls.c +++ b/arch/x86/kernel/tls.c | |||
@@ -29,7 +29,28 @@ static int get_free_idx(void) | |||
29 | 29 | ||
30 | static bool tls_desc_okay(const struct user_desc *info) | 30 | static bool tls_desc_okay(const struct user_desc *info) |
31 | { | 31 | { |
32 | if (LDT_empty(info)) | 32 | /* |
33 | * For historical reasons (i.e. no one ever documented how any | ||
34 | * of the segmentation APIs work), user programs can and do | ||
35 | * assume that a struct user_desc that's all zeros except for | ||
36 | * entry_number means "no segment at all". This never actually | ||
37 | * worked. In fact, up to Linux 3.19, a struct user_desc like | ||
38 | * this would create a 16-bit read-write segment with base and | ||
39 | * limit both equal to zero. | ||
40 | * | ||
41 | * That was close enough to "no segment at all" until we | ||
42 | * hardened this function to disallow 16-bit TLS segments. Fix | ||
43 | * it up by interpreting these zeroed segments the way that they | ||
44 | * were almost certainly intended to be interpreted. | ||
45 | * | ||
46 | * The correct way to ask for "no segment at all" is to specify | ||
47 | * a user_desc that satisfies LDT_empty. To keep everything | ||
48 | * working, we accept both. | ||
49 | * | ||
50 | * Note that there's a similar kludge in modify_ldt -- look at | ||
51 | * the distinction between modes 1 and 0x11. | ||
52 | */ | ||
53 | if (LDT_empty(info) || LDT_zero(info)) | ||
33 | return true; | 54 | return true; |
34 | 55 | ||
35 | /* | 56 | /* |
@@ -71,7 +92,7 @@ static void set_tls_desc(struct task_struct *p, int idx, | |||
71 | cpu = get_cpu(); | 92 | cpu = get_cpu(); |
72 | 93 | ||
73 | while (n-- > 0) { | 94 | while (n-- > 0) { |
74 | if (LDT_empty(info)) | 95 | if (LDT_empty(info) || LDT_zero(info)) |
75 | desc->a = desc->b = 0; | 96 | desc->a = desc->b = 0; |
76 | else | 97 | else |
77 | fill_ldt(desc, info); | 98 | fill_ldt(desc, info); |
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c index 67ebf5751222..c439ec478216 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c | |||
@@ -349,6 +349,12 @@ static __user void *task_get_bounds_dir(struct task_struct *tsk) | |||
349 | return MPX_INVALID_BOUNDS_DIR; | 349 | return MPX_INVALID_BOUNDS_DIR; |
350 | 350 | ||
351 | /* | 351 | /* |
352 | * 32-bit binaries on 64-bit kernels are currently | ||
353 | * unsupported. | ||
354 | */ | ||
355 | if (IS_ENABLED(CONFIG_X86_64) && test_thread_flag(TIF_IA32)) | ||
356 | return MPX_INVALID_BOUNDS_DIR; | ||
357 | /* | ||
352 | * The bounds directory pointer is stored in a register | 358 | * The bounds directory pointer is stored in a register |
353 | * only accessible if we first do an xsave. | 359 | * only accessible if we first do an xsave. |
354 | */ | 360 | */ |
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c index edf299c8ff6c..7ac68698406c 100644 --- a/arch/x86/mm/pat.c +++ b/arch/x86/mm/pat.c | |||
@@ -234,8 +234,13 @@ void pat_init(void) | |||
234 | PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC); | 234 | PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC); |
235 | 235 | ||
236 | /* Boot CPU check */ | 236 | /* Boot CPU check */ |
237 | if (!boot_pat_state) | 237 | if (!boot_pat_state) { |
238 | rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); | 238 | rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); |
239 | if (!boot_pat_state) { | ||
240 | pat_disable("PAT read returns always zero, disabled."); | ||
241 | return; | ||
242 | } | ||
243 | } | ||
239 | 244 | ||
240 | wrmsrl(MSR_IA32_CR_PAT, pat); | 245 | wrmsrl(MSR_IA32_CR_PAT, pat); |
241 | 246 | ||
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index c489ef2c1a39..9098d880c476 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -458,6 +458,7 @@ int __init pci_xen_hvm_init(void) | |||
458 | * just how GSIs get registered. | 458 | * just how GSIs get registered. |
459 | */ | 459 | */ |
460 | __acpi_register_gsi = acpi_register_gsi_xen_hvm; | 460 | __acpi_register_gsi = acpi_register_gsi_xen_hvm; |
461 | __acpi_unregister_gsi = NULL; | ||
461 | #endif | 462 | #endif |
462 | 463 | ||
463 | #ifdef CONFIG_PCI_MSI | 464 | #ifdef CONFIG_PCI_MSI |
@@ -471,52 +472,6 @@ int __init pci_xen_hvm_init(void) | |||
471 | } | 472 | } |
472 | 473 | ||
473 | #ifdef CONFIG_XEN_DOM0 | 474 | #ifdef CONFIG_XEN_DOM0 |
474 | static __init void xen_setup_acpi_sci(void) | ||
475 | { | ||
476 | int rc; | ||
477 | int trigger, polarity; | ||
478 | int gsi = acpi_sci_override_gsi; | ||
479 | int irq = -1; | ||
480 | int gsi_override = -1; | ||
481 | |||
482 | if (!gsi) | ||
483 | return; | ||
484 | |||
485 | rc = acpi_get_override_irq(gsi, &trigger, &polarity); | ||
486 | if (rc) { | ||
487 | printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi" | ||
488 | " sci, rc=%d\n", rc); | ||
489 | return; | ||
490 | } | ||
491 | trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE; | ||
492 | polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH; | ||
493 | |||
494 | printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " | ||
495 | "polarity=%d\n", gsi, trigger, polarity); | ||
496 | |||
497 | /* Before we bind the GSI to a Linux IRQ, check whether | ||
498 | * we need to override it with bus_irq (IRQ) value. Usually for | ||
499 | * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: | ||
500 | * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) | ||
501 | * but there are oddballs where the IRQ != GSI: | ||
502 | * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) | ||
503 | * which ends up being: gsi_to_irq[9] == 20 | ||
504 | * (which is what acpi_gsi_to_irq ends up calling when starting the | ||
505 | * the ACPI interpreter and keels over since IRQ 9 has not been | ||
506 | * setup as we had setup IRQ 20 for it). | ||
507 | */ | ||
508 | if (acpi_gsi_to_irq(gsi, &irq) == 0) { | ||
509 | /* Use the provided value if it's valid. */ | ||
510 | if (irq >= 0) | ||
511 | gsi_override = irq; | ||
512 | } | ||
513 | |||
514 | gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); | ||
515 | printk(KERN_INFO "xen: acpi sci %d\n", gsi); | ||
516 | |||
517 | return; | ||
518 | } | ||
519 | |||
520 | int __init pci_xen_initial_domain(void) | 475 | int __init pci_xen_initial_domain(void) |
521 | { | 476 | { |
522 | int irq; | 477 | int irq; |
@@ -527,8 +482,8 @@ int __init pci_xen_initial_domain(void) | |||
527 | x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; | 482 | x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; |
528 | pci_msi_ignore_mask = 1; | 483 | pci_msi_ignore_mask = 1; |
529 | #endif | 484 | #endif |
530 | xen_setup_acpi_sci(); | ||
531 | __acpi_register_gsi = acpi_register_gsi_xen; | 485 | __acpi_register_gsi = acpi_register_gsi_xen; |
486 | __acpi_unregister_gsi = NULL; | ||
532 | /* Pre-allocate legacy irqs */ | 487 | /* Pre-allocate legacy irqs */ |
533 | for (irq = 0; irq < nr_legacy_irqs(); irq++) { | 488 | for (irq = 0; irq < nr_legacy_irqs(); irq++) { |
534 | int trigger, polarity; | 489 | int trigger, polarity; |