提交 14746306 编写于 作者: L Linus Torvalds

Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 fixes from Thomas Gleixner:
 "Hopefully the last round of fixes for 3.19

   - regression fix for the LDT changes
   - regression fix for XEN interrupt handling caused by the APIC
     changes
   - regression fixes for the PAT changes
   - last minute fixes for new the MPX support
   - regression fix for 32bit UP
   - fix for a long standing relocation issue on 64bit tagged for stable
   - functional fix for the Hyper-V clocksource tagged for stable
   - downgrade of a pr_err which tends to confuse users

  Looks a bit on the large side, but almost half of it are valuable
  comments"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/tsc: Change Fast TSC calibration failed from error to info
  x86/apic: Re-enable PCI_MSI support for non-SMP X86_32
  x86, mm: Change cachemode exports to non-gpl
  x86, tls: Interpret an all-zero struct user_desc as "no segment"
  x86, tls, ldt: Stop checking lm in LDT_empty
  x86, mpx: Strictly enforce empty prctl() args
  x86, mpx: Fix potential performance issue on unmaps
  x86, mpx: Explicitly disable 32-bit MPX support on 64-bit kernels
  x86, hyperv: Mark the Hyper-V clocksource as being continuous
  x86: Don't rely on VMWare emulating PAT MSR correctly
  x86, irq: Properly tag virtualization entry in /proc/interrupts
  x86, boot: Skip relocs when load address unchanged
  x86/xen: Override ACPI IRQ management callback __acpi_unregister_gsi
  ACPI: pci: Do not clear pci_dev->irq in acpi_pci_irq_disable()
  x86/xen: Treat SCI interrupt as normal GSI interrupt
...@@ -857,7 +857,7 @@ source "kernel/Kconfig.preempt" ...@@ -857,7 +857,7 @@ source "kernel/Kconfig.preempt"
config X86_UP_APIC config X86_UP_APIC
bool "Local APIC support on uniprocessors" bool "Local APIC support on uniprocessors"
depends on X86_32 && !SMP && !X86_32_NON_STANDARD && !PCI_MSI depends on X86_32 && !SMP && !X86_32_NON_STANDARD
---help--- ---help---
A local APIC (Advanced Programmable Interrupt Controller) is an A local APIC (Advanced Programmable Interrupt Controller) is an
integrated interrupt controller in the CPU. If you have a single-CPU integrated interrupt controller in the CPU. If you have a single-CPU
...@@ -868,6 +868,10 @@ config X86_UP_APIC ...@@ -868,6 +868,10 @@ config X86_UP_APIC
performance counters), and the NMI watchdog which detects hard performance counters), and the NMI watchdog which detects hard
lockups. lockups.
config X86_UP_APIC_MSI
def_bool y
select X86_UP_APIC if X86_32 && !SMP && !X86_32_NON_STANDARD && PCI_MSI
config X86_UP_IOAPIC config X86_UP_IOAPIC
bool "IO-APIC support on uniprocessors" bool "IO-APIC support on uniprocessors"
depends on X86_UP_APIC depends on X86_UP_APIC
......
...@@ -373,6 +373,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, ...@@ -373,6 +373,8 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
unsigned long output_len, unsigned long output_len,
unsigned long run_size) unsigned long run_size)
{ {
unsigned char *output_orig = output;
real_mode = rmode; real_mode = rmode;
sanitize_boot_params(real_mode); sanitize_boot_params(real_mode);
...@@ -421,7 +423,12 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, ...@@ -421,7 +423,12 @@ asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap,
debug_putstr("\nDecompressing Linux... "); debug_putstr("\nDecompressing Linux... ");
decompress(input_data, input_len, NULL, NULL, output, NULL, error); decompress(input_data, input_len, NULL, NULL, output, NULL, error);
parse_elf(output); parse_elf(output);
handle_relocations(output, output_len); /*
* 32-bit always performs relocations. 64-bit relocations are only
* needed if kASLR has chosen a different load address.
*/
if (!IS_ENABLED(CONFIG_X86_64) || output != output_orig)
handle_relocations(output, output_len);
debug_putstr("done.\nBooting the kernel.\n"); debug_putstr("done.\nBooting the kernel.\n");
return output; return output;
} }
...@@ -50,6 +50,7 @@ void acpi_pic_sci_set_trigger(unsigned int, u16); ...@@ -50,6 +50,7 @@ void acpi_pic_sci_set_trigger(unsigned int, u16);
extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi,
int trigger, int polarity); int trigger, int polarity);
extern void (*__acpi_unregister_gsi)(u32 gsi);
static inline void disable_acpi(void) static inline void disable_acpi(void)
{ {
......
...@@ -251,7 +251,8 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) ...@@ -251,7 +251,8 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i]; gdt[GDT_ENTRY_TLS_MIN + i] = t->tls_array[i];
} }
#define _LDT_empty(info) \ /* This intentionally ignores lm, since 32-bit apps don't have that field. */
#define LDT_empty(info) \
((info)->base_addr == 0 && \ ((info)->base_addr == 0 && \
(info)->limit == 0 && \ (info)->limit == 0 && \
(info)->contents == 0 && \ (info)->contents == 0 && \
...@@ -261,11 +262,18 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu) ...@@ -261,11 +262,18 @@ static inline void native_load_tls(struct thread_struct *t, unsigned int cpu)
(info)->seg_not_present == 1 && \ (info)->seg_not_present == 1 && \
(info)->useable == 0) (info)->useable == 0)
#ifdef CONFIG_X86_64 /* Lots of programs expect an all-zero user_desc to mean "no segment at all". */
#define LDT_empty(info) (_LDT_empty(info) && ((info)->lm == 0)) static inline bool LDT_zero(const struct user_desc *info)
#else {
#define LDT_empty(info) (_LDT_empty(info)) return (info->base_addr == 0 &&
#endif info->limit == 0 &&
info->contents == 0 &&
info->read_exec_only == 0 &&
info->seg_32bit == 0 &&
info->limit_in_pages == 0 &&
info->seg_not_present == 0 &&
info->useable == 0);
}
static inline void clear_LDT(void) static inline void clear_LDT(void)
{ {
......
...@@ -130,7 +130,25 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm, ...@@ -130,7 +130,25 @@ static inline void arch_bprm_mm_init(struct mm_struct *mm,
static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma, static inline void arch_unmap(struct mm_struct *mm, struct vm_area_struct *vma,
unsigned long start, unsigned long end) unsigned long start, unsigned long end)
{ {
mpx_notify_unmap(mm, vma, start, end); /*
* mpx_notify_unmap() goes and reads a rarely-hot
* cacheline in the mm_struct. That can be expensive
* enough to be seen in profiles.
*
* The mpx_notify_unmap() call and its contents have been
* observed to affect munmap() performance on hardware
* where MPX is not present.
*
* The unlikely() optimizes for the fast case: no MPX
* in the CPU, or no MPX use in the process. Even if
* we get this wrong (in the unlikely event that MPX
* is widely enabled on some system) the overhead of
* MPX itself (reading bounds tables) is expected to
* overwhelm the overhead of getting this unlikely()
* consistently wrong.
*/
if (unlikely(cpu_feature_enabled(X86_FEATURE_MPX)))
mpx_notify_unmap(mm, vma, start, end);
} }
#endif /* _ASM_X86_MMU_CONTEXT_H */ #endif /* _ASM_X86_MMU_CONTEXT_H */
...@@ -611,20 +611,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger) ...@@ -611,20 +611,20 @@ void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger)
int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp) int acpi_gsi_to_irq(u32 gsi, unsigned int *irqp)
{ {
int irq; int rc, irq, trigger, polarity;
if (acpi_irq_model == ACPI_IRQ_MODEL_PIC) { rc = acpi_get_override_irq(gsi, &trigger, &polarity);
*irqp = gsi; if (rc == 0) {
} else { trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
mutex_lock(&acpi_ioapic_lock); polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
irq = mp_map_gsi_to_irq(gsi, irq = acpi_register_gsi(NULL, gsi, trigger, polarity);
IOAPIC_MAP_ALLOC | IOAPIC_MAP_CHECK); if (irq >= 0) {
mutex_unlock(&acpi_ioapic_lock); *irqp = irq;
if (irq < 0) return 0;
return -1; }
*irqp = irq;
} }
return 0;
return -1;
} }
EXPORT_SYMBOL_GPL(acpi_gsi_to_irq); EXPORT_SYMBOL_GPL(acpi_gsi_to_irq);
......
...@@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = { ...@@ -107,6 +107,7 @@ static struct clocksource hyperv_cs = {
.rating = 400, /* use this when running on Hyperv*/ .rating = 400, /* use this when running on Hyperv*/
.read = read_hv_clock, .read = read_hv_clock,
.mask = CLOCKSOURCE_MASK(64), .mask = CLOCKSOURCE_MASK(64),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
}; };
static void __init ms_hyperv_init_platform(void) static void __init ms_hyperv_init_platform(void)
......
...@@ -127,7 +127,7 @@ int arch_show_interrupts(struct seq_file *p, int prec) ...@@ -127,7 +127,7 @@ int arch_show_interrupts(struct seq_file *p, int prec)
seq_puts(p, " Machine check polls\n"); seq_puts(p, " Machine check polls\n");
#endif #endif
#if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN) #if IS_ENABLED(CONFIG_HYPERV) || defined(CONFIG_XEN)
seq_printf(p, "%*s: ", prec, "THR"); seq_printf(p, "%*s: ", prec, "HYP");
for_each_online_cpu(j) for_each_online_cpu(j)
seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count); seq_printf(p, "%10u ", irq_stats(j)->irq_hv_callback_count);
seq_puts(p, " Hypervisor callback interrupts\n"); seq_puts(p, " Hypervisor callback interrupts\n");
......
...@@ -29,7 +29,28 @@ static int get_free_idx(void) ...@@ -29,7 +29,28 @@ static int get_free_idx(void)
static bool tls_desc_okay(const struct user_desc *info) static bool tls_desc_okay(const struct user_desc *info)
{ {
if (LDT_empty(info)) /*
* For historical reasons (i.e. no one ever documented how any
* of the segmentation APIs work), user programs can and do
* assume that a struct user_desc that's all zeros except for
* entry_number means "no segment at all". This never actually
* worked. In fact, up to Linux 3.19, a struct user_desc like
* this would create a 16-bit read-write segment with base and
* limit both equal to zero.
*
* That was close enough to "no segment at all" until we
* hardened this function to disallow 16-bit TLS segments. Fix
* it up by interpreting these zeroed segments the way that they
* were almost certainly intended to be interpreted.
*
* The correct way to ask for "no segment at all" is to specify
* a user_desc that satisfies LDT_empty. To keep everything
* working, we accept both.
*
* Note that there's a similar kludge in modify_ldt -- look at
* the distinction between modes 1 and 0x11.
*/
if (LDT_empty(info) || LDT_zero(info))
return true; return true;
/* /*
...@@ -71,7 +92,7 @@ static void set_tls_desc(struct task_struct *p, int idx, ...@@ -71,7 +92,7 @@ static void set_tls_desc(struct task_struct *p, int idx,
cpu = get_cpu(); cpu = get_cpu();
while (n-- > 0) { while (n-- > 0) {
if (LDT_empty(info)) if (LDT_empty(info) || LDT_zero(info))
desc->a = desc->b = 0; desc->a = desc->b = 0;
else else
fill_ldt(desc, info); fill_ldt(desc, info);
......
...@@ -617,7 +617,7 @@ static unsigned long quick_pit_calibrate(void) ...@@ -617,7 +617,7 @@ static unsigned long quick_pit_calibrate(void)
goto success; goto success;
} }
} }
pr_err("Fast TSC calibration failed\n"); pr_info("Fast TSC calibration failed\n");
return 0; return 0;
success: success:
......
...@@ -43,7 +43,7 @@ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { ...@@ -43,7 +43,7 @@ uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = {
[_PAGE_CACHE_MODE_WT] = _PAGE_PCD, [_PAGE_CACHE_MODE_WT] = _PAGE_PCD,
[_PAGE_CACHE_MODE_WP] = _PAGE_PCD, [_PAGE_CACHE_MODE_WP] = _PAGE_PCD,
}; };
EXPORT_SYMBOL_GPL(__cachemode2pte_tbl); EXPORT_SYMBOL(__cachemode2pte_tbl);
uint8_t __pte2cachemode_tbl[8] = { uint8_t __pte2cachemode_tbl[8] = {
[__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB, [__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB,
[__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC, [__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC,
...@@ -54,7 +54,7 @@ uint8_t __pte2cachemode_tbl[8] = { ...@@ -54,7 +54,7 @@ uint8_t __pte2cachemode_tbl[8] = {
[__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, [__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS,
[__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, [__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC,
}; };
EXPORT_SYMBOL_GPL(__pte2cachemode_tbl); EXPORT_SYMBOL(__pte2cachemode_tbl);
static unsigned long __initdata pgt_buf_start; static unsigned long __initdata pgt_buf_start;
static unsigned long __initdata pgt_buf_end; static unsigned long __initdata pgt_buf_end;
......
...@@ -348,6 +348,12 @@ static __user void *task_get_bounds_dir(struct task_struct *tsk) ...@@ -348,6 +348,12 @@ static __user void *task_get_bounds_dir(struct task_struct *tsk)
if (!cpu_feature_enabled(X86_FEATURE_MPX)) if (!cpu_feature_enabled(X86_FEATURE_MPX))
return MPX_INVALID_BOUNDS_DIR; return MPX_INVALID_BOUNDS_DIR;
/*
* 32-bit binaries on 64-bit kernels are currently
* unsupported.
*/
if (IS_ENABLED(CONFIG_X86_64) && test_thread_flag(TIF_IA32))
return MPX_INVALID_BOUNDS_DIR;
/* /*
* The bounds directory pointer is stored in a register * The bounds directory pointer is stored in a register
* only accessible if we first do an xsave. * only accessible if we first do an xsave.
......
...@@ -234,8 +234,13 @@ void pat_init(void) ...@@ -234,8 +234,13 @@ void pat_init(void)
PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC); PAT(4, WB) | PAT(5, WC) | PAT(6, UC_MINUS) | PAT(7, UC);
/* Boot CPU check */ /* Boot CPU check */
if (!boot_pat_state) if (!boot_pat_state) {
rdmsrl(MSR_IA32_CR_PAT, boot_pat_state); rdmsrl(MSR_IA32_CR_PAT, boot_pat_state);
if (!boot_pat_state) {
pat_disable("PAT read returns always zero, disabled.");
return;
}
}
wrmsrl(MSR_IA32_CR_PAT, pat); wrmsrl(MSR_IA32_CR_PAT, pat);
......
...@@ -458,6 +458,7 @@ int __init pci_xen_hvm_init(void) ...@@ -458,6 +458,7 @@ int __init pci_xen_hvm_init(void)
* just how GSIs get registered. * just how GSIs get registered.
*/ */
__acpi_register_gsi = acpi_register_gsi_xen_hvm; __acpi_register_gsi = acpi_register_gsi_xen_hvm;
__acpi_unregister_gsi = NULL;
#endif #endif
#ifdef CONFIG_PCI_MSI #ifdef CONFIG_PCI_MSI
...@@ -471,52 +472,6 @@ int __init pci_xen_hvm_init(void) ...@@ -471,52 +472,6 @@ int __init pci_xen_hvm_init(void)
} }
#ifdef CONFIG_XEN_DOM0 #ifdef CONFIG_XEN_DOM0
static __init void xen_setup_acpi_sci(void)
{
int rc;
int trigger, polarity;
int gsi = acpi_sci_override_gsi;
int irq = -1;
int gsi_override = -1;
if (!gsi)
return;
rc = acpi_get_override_irq(gsi, &trigger, &polarity);
if (rc) {
printk(KERN_WARNING "xen: acpi_get_override_irq failed for acpi"
" sci, rc=%d\n", rc);
return;
}
trigger = trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE;
polarity = polarity ? ACPI_ACTIVE_LOW : ACPI_ACTIVE_HIGH;
printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d "
"polarity=%d\n", gsi, trigger, polarity);
/* Before we bind the GSI to a Linux IRQ, check whether
* we need to override it with bus_irq (IRQ) value. Usually for
* IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so:
* ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level)
* but there are oddballs where the IRQ != GSI:
* ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level)
* which ends up being: gsi_to_irq[9] == 20
* (which is what acpi_gsi_to_irq ends up calling when starting the
* the ACPI interpreter and keels over since IRQ 9 has not been
* setup as we had setup IRQ 20 for it).
*/
if (acpi_gsi_to_irq(gsi, &irq) == 0) {
/* Use the provided value if it's valid. */
if (irq >= 0)
gsi_override = irq;
}
gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity);
printk(KERN_INFO "xen: acpi sci %d\n", gsi);
return;
}
int __init pci_xen_initial_domain(void) int __init pci_xen_initial_domain(void)
{ {
int irq; int irq;
...@@ -527,8 +482,8 @@ int __init pci_xen_initial_domain(void) ...@@ -527,8 +482,8 @@ int __init pci_xen_initial_domain(void)
x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs; x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
pci_msi_ignore_mask = 1; pci_msi_ignore_mask = 1;
#endif #endif
xen_setup_acpi_sci();
__acpi_register_gsi = acpi_register_gsi_xen; __acpi_register_gsi = acpi_register_gsi_xen;
__acpi_unregister_gsi = NULL;
/* Pre-allocate legacy irqs */ /* Pre-allocate legacy irqs */
for (irq = 0; irq < nr_legacy_irqs(); irq++) { for (irq = 0; irq < nr_legacy_irqs(); irq++) {
int trigger, polarity; int trigger, polarity;
......
...@@ -512,7 +512,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) ...@@ -512,7 +512,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
if (gsi >= 0) { if (gsi >= 0) {
acpi_unregister_gsi(gsi); acpi_unregister_gsi(gsi);
dev->irq = 0;
dev->irq_managed = 0; dev->irq_managed = 0;
} }
} }
...@@ -2210,9 +2210,13 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, ...@@ -2210,9 +2210,13 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
up_write(&me->mm->mmap_sem); up_write(&me->mm->mmap_sem);
break; break;
case PR_MPX_ENABLE_MANAGEMENT: case PR_MPX_ENABLE_MANAGEMENT:
if (arg2 || arg3 || arg4 || arg5)
return -EINVAL;
error = MPX_ENABLE_MANAGEMENT(me); error = MPX_ENABLE_MANAGEMENT(me);
break; break;
case PR_MPX_DISABLE_MANAGEMENT: case PR_MPX_DISABLE_MANAGEMENT:
if (arg2 || arg3 || arg4 || arg5)
return -EINVAL;
error = MPX_DISABLE_MANAGEMENT(me); error = MPX_DISABLE_MANAGEMENT(me);
break; break;
default: default:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册