Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thoma Gleixner: "Another round of fixes for x86: - Move the initialization of the microcode driver to late_initcall to make sure everything that init function needs is available. - Make sure that lockdep knows about interrupts being off in the entry code before calling into c-code. - Undo the cpu hotplug init delay regression. - Use the proper conditionals in the mpx instruction decoder. - Fixup restart_syscall for x32 tasks. - Fix the hugepage regression on PAE kernels which was introduced with the latest PAT changes" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/signal: Fix restart_syscall number for x32 tasks x86/mpx: Fix instruction decoder condition x86/mm: Fix regression with huge pages on PAE x86 smpboot: Re-enable init_udelay=0 by default on modern CPUs x86/entry/64: Fix irqflag tracing wrt context tracking x86/microcode: Initialize the driver late when facilities are up
This commit is contained in:
commit
69d2ca6002
12 changed files with 55 additions and 37 deletions
|
@ -23,7 +23,6 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/edd.h>
|
#include <linux/edd.h>
|
||||||
#include <asm/boot.h>
|
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
#include "bitops.h"
|
#include "bitops.h"
|
||||||
#include "ctype.h"
|
#include "ctype.h"
|
||||||
|
|
|
@ -19,6 +19,8 @@
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vesa.h"
|
#include "vesa.h"
|
||||||
|
|
||||||
|
#include <uapi/asm/boot.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Common variables
|
* Common variables
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
* Select video mode
|
* Select video mode
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <uapi/asm/boot.h>
|
||||||
|
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "vesa.h"
|
#include "vesa.h"
|
||||||
|
|
|
@ -509,6 +509,17 @@ END(irq_entries_start)
|
||||||
* tracking that we're in kernel mode.
|
* tracking that we're in kernel mode.
|
||||||
*/
|
*/
|
||||||
SWAPGS
|
SWAPGS
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We need to tell lockdep that IRQs are off. We can't do this until
|
||||||
|
* we fix gsbase, and we should do it before enter_from_user_mode
|
||||||
|
* (which can take locks). Since TRACE_IRQS_OFF idempotent,
|
||||||
|
* the simplest way to handle it is to just call it twice if
|
||||||
|
* we enter from user mode. There's no reason to optimize this since
|
||||||
|
* TRACE_IRQS_OFF is a no-op if lockdep is off.
|
||||||
|
*/
|
||||||
|
TRACE_IRQS_OFF
|
||||||
|
|
||||||
#ifdef CONFIG_CONTEXT_TRACKING
|
#ifdef CONFIG_CONTEXT_TRACKING
|
||||||
call enter_from_user_mode
|
call enter_from_user_mode
|
||||||
#endif
|
#endif
|
||||||
|
@ -1049,12 +1060,18 @@ ENTRY(error_entry)
|
||||||
SWAPGS
|
SWAPGS
|
||||||
|
|
||||||
.Lerror_entry_from_usermode_after_swapgs:
|
.Lerror_entry_from_usermode_after_swapgs:
|
||||||
|
/*
|
||||||
|
* We need to tell lockdep that IRQs are off. We can't do this until
|
||||||
|
* we fix gsbase, and we should do it before enter_from_user_mode
|
||||||
|
* (which can take locks).
|
||||||
|
*/
|
||||||
|
TRACE_IRQS_OFF
|
||||||
#ifdef CONFIG_CONTEXT_TRACKING
|
#ifdef CONFIG_CONTEXT_TRACKING
|
||||||
call enter_from_user_mode
|
call enter_from_user_mode
|
||||||
#endif
|
#endif
|
||||||
|
ret
|
||||||
|
|
||||||
.Lerror_entry_done:
|
.Lerror_entry_done:
|
||||||
|
|
||||||
TRACE_IRQS_OFF
|
TRACE_IRQS_OFF
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
|
@ -9,20 +9,22 @@
|
||||||
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
|
||||||
#define PAGE_MASK (~(PAGE_SIZE-1))
|
#define PAGE_MASK (~(PAGE_SIZE-1))
|
||||||
|
|
||||||
#define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1))
|
|
||||||
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
|
|
||||||
|
|
||||||
/* Cast PAGE_MASK to a signed type so that it is sign-extended if
|
|
||||||
virtual addresses are 32-bits but physical addresses are larger
|
|
||||||
(ie, 32-bit PAE). */
|
|
||||||
#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
|
|
||||||
|
|
||||||
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
|
#define PMD_PAGE_SIZE (_AC(1, UL) << PMD_SHIFT)
|
||||||
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
|
#define PMD_PAGE_MASK (~(PMD_PAGE_SIZE-1))
|
||||||
|
|
||||||
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
|
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
|
||||||
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
|
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
|
||||||
|
|
||||||
|
#define __PHYSICAL_MASK ((phys_addr_t)((1ULL << __PHYSICAL_MASK_SHIFT) - 1))
|
||||||
|
#define __VIRTUAL_MASK ((1UL << __VIRTUAL_MASK_SHIFT) - 1)
|
||||||
|
|
||||||
|
/* Cast *PAGE_MASK to a signed type so that it is sign-extended if
|
||||||
|
virtual addresses are 32-bits but physical addresses are larger
|
||||||
|
(ie, 32-bit PAE). */
|
||||||
|
#define PHYSICAL_PAGE_MASK (((signed long)PAGE_MASK) & __PHYSICAL_MASK)
|
||||||
|
#define PHYSICAL_PMD_PAGE_MASK (((signed long)PMD_PAGE_MASK) & __PHYSICAL_MASK)
|
||||||
|
#define PHYSICAL_PUD_PAGE_MASK (((signed long)PUD_PAGE_MASK) & __PHYSICAL_MASK)
|
||||||
|
|
||||||
#define HPAGE_SHIFT PMD_SHIFT
|
#define HPAGE_SHIFT PMD_SHIFT
|
||||||
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
|
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
|
||||||
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
|
||||||
|
|
|
@ -279,17 +279,14 @@ static inline pmdval_t native_pmd_val(pmd_t pmd)
|
||||||
static inline pudval_t pud_pfn_mask(pud_t pud)
|
static inline pudval_t pud_pfn_mask(pud_t pud)
|
||||||
{
|
{
|
||||||
if (native_pud_val(pud) & _PAGE_PSE)
|
if (native_pud_val(pud) & _PAGE_PSE)
|
||||||
return PUD_PAGE_MASK & PHYSICAL_PAGE_MASK;
|
return PHYSICAL_PUD_PAGE_MASK;
|
||||||
else
|
else
|
||||||
return PTE_PFN_MASK;
|
return PTE_PFN_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pudval_t pud_flags_mask(pud_t pud)
|
static inline pudval_t pud_flags_mask(pud_t pud)
|
||||||
{
|
{
|
||||||
if (native_pud_val(pud) & _PAGE_PSE)
|
return ~pud_pfn_mask(pud);
|
||||||
return ~(PUD_PAGE_MASK & (pudval_t)PHYSICAL_PAGE_MASK);
|
|
||||||
else
|
|
||||||
return ~PTE_PFN_MASK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pudval_t pud_flags(pud_t pud)
|
static inline pudval_t pud_flags(pud_t pud)
|
||||||
|
@ -300,17 +297,14 @@ static inline pudval_t pud_flags(pud_t pud)
|
||||||
static inline pmdval_t pmd_pfn_mask(pmd_t pmd)
|
static inline pmdval_t pmd_pfn_mask(pmd_t pmd)
|
||||||
{
|
{
|
||||||
if (native_pmd_val(pmd) & _PAGE_PSE)
|
if (native_pmd_val(pmd) & _PAGE_PSE)
|
||||||
return PMD_PAGE_MASK & PHYSICAL_PAGE_MASK;
|
return PHYSICAL_PMD_PAGE_MASK;
|
||||||
else
|
else
|
||||||
return PTE_PFN_MASK;
|
return PTE_PFN_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pmdval_t pmd_flags_mask(pmd_t pmd)
|
static inline pmdval_t pmd_flags_mask(pmd_t pmd)
|
||||||
{
|
{
|
||||||
if (native_pmd_val(pmd) & _PAGE_PSE)
|
return ~pmd_pfn_mask(pmd);
|
||||||
return ~(PMD_PAGE_MASK & (pmdval_t)PHYSICAL_PAGE_MASK);
|
|
||||||
else
|
|
||||||
return ~PTE_PFN_MASK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline pmdval_t pmd_flags(pmd_t pmd)
|
static inline pmdval_t pmd_flags(pmd_t pmd)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef _ASM_X86_PLATFORM_H
|
#ifndef _ASM_X86_PLATFORM_H
|
||||||
#define _ASM_X86_PLATFORM_H
|
#define _ASM_X86_PLATFORM_H
|
||||||
|
|
||||||
#include <asm/pgtable_types.h>
|
|
||||||
#include <asm/bootparam.h>
|
#include <asm/bootparam.h>
|
||||||
|
|
||||||
struct mpc_bus;
|
struct mpc_bus;
|
||||||
|
|
|
@ -698,3 +698,4 @@ int __init microcode_init(void)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
late_initcall(microcode_init);
|
||||||
|
|
|
@ -1250,8 +1250,6 @@ void __init setup_arch(char **cmdline_p)
|
||||||
if (efi_enabled(EFI_BOOT))
|
if (efi_enabled(EFI_BOOT))
|
||||||
efi_apply_memmap_quirks();
|
efi_apply_memmap_quirks();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
microcode_init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
#ifdef CONFIG_X86_32
|
||||||
|
|
|
@ -690,12 +690,15 @@ handle_signal(struct ksignal *ksig, struct pt_regs *regs)
|
||||||
signal_setup_done(failed, ksig, stepping);
|
signal_setup_done(failed, ksig, stepping);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
|
||||||
#define NR_restart_syscall __NR_restart_syscall
|
{
|
||||||
#else /* !CONFIG_X86_32 */
|
#if defined(CONFIG_X86_32) || !defined(CONFIG_X86_64)
|
||||||
#define NR_restart_syscall \
|
return __NR_restart_syscall;
|
||||||
test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
|
#else /* !CONFIG_X86_32 && CONFIG_X86_64 */
|
||||||
#endif /* CONFIG_X86_32 */
|
return test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall :
|
||||||
|
__NR_restart_syscall | (regs->orig_ax & __X32_SYSCALL_BIT);
|
||||||
|
#endif /* CONFIG_X86_32 || !CONFIG_X86_64 */
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that 'init' is a special process: it doesn't get signals it doesn't
|
* Note that 'init' is a special process: it doesn't get signals it doesn't
|
||||||
|
@ -724,7 +727,7 @@ void do_signal(struct pt_regs *regs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case -ERESTART_RESTARTBLOCK:
|
case -ERESTART_RESTARTBLOCK:
|
||||||
regs->ax = NR_restart_syscall;
|
regs->ax = get_nr_restart_syscall(regs);
|
||||||
regs->ip -= 2;
|
regs->ip -= 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -509,7 +509,7 @@ void __inquire_remote_apic(int apicid)
|
||||||
*/
|
*/
|
||||||
#define UDELAY_10MS_DEFAULT 10000
|
#define UDELAY_10MS_DEFAULT 10000
|
||||||
|
|
||||||
static unsigned int init_udelay = INT_MAX;
|
static unsigned int init_udelay = UINT_MAX;
|
||||||
|
|
||||||
static int __init cpu_init_udelay(char *str)
|
static int __init cpu_init_udelay(char *str)
|
||||||
{
|
{
|
||||||
|
@ -522,14 +522,15 @@ early_param("cpu_init_udelay", cpu_init_udelay);
|
||||||
static void __init smp_quirk_init_udelay(void)
|
static void __init smp_quirk_init_udelay(void)
|
||||||
{
|
{
|
||||||
/* if cmdline changed it from default, leave it alone */
|
/* if cmdline changed it from default, leave it alone */
|
||||||
if (init_udelay != INT_MAX)
|
if (init_udelay != UINT_MAX)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* if modern processor, use no delay */
|
/* if modern processor, use no delay */
|
||||||
if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) ||
|
if (((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 == 6)) ||
|
||||||
((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF)))
|
((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) && (boot_cpu_data.x86 >= 0xF))) {
|
||||||
init_udelay = 0;
|
init_udelay = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
/* else, use legacy delay */
|
/* else, use legacy delay */
|
||||||
init_udelay = UDELAY_10MS_DEFAULT;
|
init_udelay = UDELAY_10MS_DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,19 +101,19 @@ static int get_reg_offset(struct insn *insn, struct pt_regs *regs,
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REG_TYPE_RM:
|
case REG_TYPE_RM:
|
||||||
regno = X86_MODRM_RM(insn->modrm.value);
|
regno = X86_MODRM_RM(insn->modrm.value);
|
||||||
if (X86_REX_B(insn->rex_prefix.value) == 1)
|
if (X86_REX_B(insn->rex_prefix.value))
|
||||||
regno += 8;
|
regno += 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REG_TYPE_INDEX:
|
case REG_TYPE_INDEX:
|
||||||
regno = X86_SIB_INDEX(insn->sib.value);
|
regno = X86_SIB_INDEX(insn->sib.value);
|
||||||
if (X86_REX_X(insn->rex_prefix.value) == 1)
|
if (X86_REX_X(insn->rex_prefix.value))
|
||||||
regno += 8;
|
regno += 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REG_TYPE_BASE:
|
case REG_TYPE_BASE:
|
||||||
regno = X86_SIB_BASE(insn->sib.value);
|
regno = X86_SIB_BASE(insn->sib.value);
|
||||||
if (X86_REX_B(insn->rex_prefix.value) == 1)
|
if (X86_REX_B(insn->rex_prefix.value))
|
||||||
regno += 8;
|
regno += 8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue