diff options
-rw-r--r-- | arch/x86/Kconfig | 6 | ||||
-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/irq.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/tls.c | 25 | ||||
-rw-r--r-- | arch/x86/kernel/tsc.c | 2 | ||||
-rw-r--r-- | arch/x86/mm/init.c | 4 | ||||
-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 | ||||
-rw-r--r-- | drivers/acpi/pci_irq.c | 1 | ||||
-rw-r--r-- | kernel/sys.c | 4 |
16 files changed, 106 insertions, 77 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ba397bde7948..0dc9d0144a27 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -857,7 +857,7 @@ source "kernel/Kconfig.preempt" | |||
857 | 857 | ||
858 | config X86_UP_APIC | 858 | config X86_UP_APIC |
859 | bool "Local APIC support on uniprocessors" | 859 | bool "Local APIC support on uniprocessors" |
860 | depends on X86_32 && !SMP && !X86_32_NON_STANDARD && !PCI_MSI | 860 | depends on X86_32 && !SMP && !X86_32_NON_STANDARD |
861 | ---help--- | 861 | ---help--- |
862 | A local APIC (Advanced Programmable Interrupt Controller) is an | 862 | A local APIC (Advanced Programmable Interrupt Controller) is an |
863 | integrated interrupt controller in the CPU. If you have a single-CPU | 863 | integrated interrupt controller in the CPU. If you have a single-CPU |
@@ -868,6 +868,10 @@ config X86_UP_APIC | |||
868 | performance counters), and the NMI watchdog which detects hard | 868 | performance counters), and the NMI watchdog which detects hard |
869 | lockups. | 869 | lockups. |
870 | 870 | ||
871 | config X86_UP_APIC_MSI | ||
872 | def_bool y | ||
873 | select X86_UP_APIC if X86_32 && !SMP && !X86_32_NON_STANDARD && PCI_MSI | ||
874 | |||
871 | config X86_UP_IOAPIC | 875 | config X86_UP_IOAPIC |
872 | bool "IO-APIC support on uniprocessors" | 876 | bool "IO-APIC support on uniprocessors" |
873 | depends on X86_UP_APIC | 877 | depends on X86_UP_APIC |
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/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/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/kernel/tsc.c b/arch/x86/kernel/tsc.c index b7e50bba3bbb..505449700e0c 100644 --- a/arch/x86/kernel/tsc.c +++ b/arch/x86/kernel/tsc.c | |||
@@ -617,7 +617,7 @@ static unsigned long quick_pit_calibrate(void) | |||
617 | goto success; | 617 | goto success; |
618 | } | 618 | } |
619 | } | 619 | } |
620 | pr_err("Fast TSC calibration failed\n"); | 620 | pr_info("Fast TSC calibration failed\n"); |
621 | return 0; | 621 | return 0; |
622 | 622 | ||
623 | success: | 623 | success: |
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 08a7d313538a..079c3b6a3ff1 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c | |||
@@ -43,7 +43,7 @@ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { | |||
43 | [_PAGE_CACHE_MODE_WT] = _PAGE_PCD, | 43 | [_PAGE_CACHE_MODE_WT] = _PAGE_PCD, |
44 | [_PAGE_CACHE_MODE_WP] = _PAGE_PCD, | 44 | [_PAGE_CACHE_MODE_WP] = _PAGE_PCD, |
45 | }; | 45 | }; |
46 | EXPORT_SYMBOL_GPL(__cachemode2pte_tbl); | 46 | EXPORT_SYMBOL(__cachemode2pte_tbl); |
47 | uint8_t __pte2cachemode_tbl[8] = { | 47 | uint8_t __pte2cachemode_tbl[8] = { |
48 | [__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB, | 48 | [__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB, |
49 | [__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC, | 49 | [__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC, |
@@ -54,7 +54,7 @@ uint8_t __pte2cachemode_tbl[8] = { | |||
54 | [__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, | 54 | [__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, |
55 | [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, | 55 | [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, |
56 | }; | 56 | }; |
57 | EXPORT_SYMBOL_GPL(__pte2cachemode_tbl); | 57 | EXPORT_SYMBOL(__pte2cachemode_tbl); |
58 | 58 | ||
59 | static unsigned long __initdata pgt_buf_start; | 59 | static unsigned long __initdata pgt_buf_start; |
60 | static unsigned long __initdata pgt_buf_end; | 60 | static unsigned long __initdata pgt_buf_end; |
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; |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 5277a0ee5704..b1def411c0b8 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -512,7 +512,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) | |||
512 | dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); | 512 | dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); |
513 | if (gsi >= 0) { | 513 | if (gsi >= 0) { |
514 | acpi_unregister_gsi(gsi); | 514 | acpi_unregister_gsi(gsi); |
515 | dev->irq = 0; | ||
516 | dev->irq_managed = 0; | 515 | dev->irq_managed = 0; |
517 | } | 516 | } |
518 | } | 517 | } |
diff --git a/kernel/sys.c b/kernel/sys.c index a8c9f5a7dda6..ea9c88109894 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -2210,9 +2210,13 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
2210 | up_write(&me->mm->mmap_sem); | 2210 | up_write(&me->mm->mmap_sem); |
2211 | break; | 2211 | break; |
2212 | case PR_MPX_ENABLE_MANAGEMENT: | 2212 | case PR_MPX_ENABLE_MANAGEMENT: |
2213 | if (arg2 || arg3 || arg4 || arg5) | ||
2214 | return -EINVAL; | ||
2213 | error = MPX_ENABLE_MANAGEMENT(me); | 2215 | error = MPX_ENABLE_MANAGEMENT(me); |
2214 | break; | 2216 | break; |
2215 | case PR_MPX_DISABLE_MANAGEMENT: | 2217 | case PR_MPX_DISABLE_MANAGEMENT: |
2218 | if (arg2 || arg3 || arg4 || arg5) | ||
2219 | return -EINVAL; | ||
2216 | error = MPX_DISABLE_MANAGEMENT(me); | 2220 | error = MPX_DISABLE_MANAGEMENT(me); |
2217 | break; | 2221 | break; |
2218 | default: | 2222 | default: |