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: |
