Linus,

Please pull the latest x86-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git 
x86-urgent-for-linus

   # HEAD: dc4fac84f8e66b147921ebdc385e767d5def7422 x86/mm: Switch from 
TASK_SIZE to TASK_SIZE_MAX in the page fault code

Misc fixes: EFI, entry code, pkeys and MPX fixes, TASK_SIZE cleanups and a tsc 
frequency table fix.

 Thanks,

        Ingo

------------------>
Andy Lutomirski (2):
      x86/fsgsbase/64: Use TASK_SIZE_MAX for FSBASE/GSBASE upper limits
      x86/mm: Switch from TASK_SIZE to TASK_SIZE_MAX in the page fault code

Dave Hansen (2):
      x86/cpufeature, x86/mm/pkeys: Fix broken compile-time disabling of pkeys
      x86/mm/mpx: Work around MPX erratum SKD046

Jeremy Compostella (1):
      x86/tsc: Add missing Cherrytrail frequency to the table

Josh Poimboeuf (1):
      x86/entry/64: Fix stack return address retrieval in thunk

Linus Torvalds (1):
      x86/efi: Fix 7-parameter efi_call()s


 arch/x86/entry/thunk_64.S                | 11 +++++-----
 arch/x86/include/asm/bugs.h              |  8 +++++++
 arch/x86/include/asm/cpufeature.h        | 12 +++++------
 arch/x86/include/asm/disabled-features.h |  6 +++---
 arch/x86/kernel/cpu/common.c             |  7 ++++++
 arch/x86/kernel/cpu/intel.c              | 37 ++++++++++++++++++++++++++++++++
 arch/x86/kernel/process_64.c             |  4 ++--
 arch/x86/kernel/ptrace.c                 |  4 ++--
 arch/x86/kernel/tsc_msr.c                |  3 +++
 arch/x86/mm/fault.c                      | 11 +++++++---
 arch/x86/platform/efi/efi_stub_64.S      |  9 ++++----
 11 files changed, 85 insertions(+), 27 deletions(-)

diff --git a/arch/x86/entry/thunk_64.S b/arch/x86/entry/thunk_64.S
index 98df1fa8825c..027aec4a74df 100644
--- a/arch/x86/entry/thunk_64.S
+++ b/arch/x86/entry/thunk_64.S
@@ -8,16 +8,15 @@
 #include <linux/linkage.h>
 #include "calling.h"
 #include <asm/asm.h>
-#include <asm/frame.h>
 
        /* rdi: arg1 ... normal C conventions. rax is saved/restored. */
        .macro THUNK name, func, put_ret_addr_in_rdi=0
        .globl \name
        .type \name, @function
 \name:
-       FRAME_BEGIN
+       pushq %rbp
+       movq %rsp, %rbp
 
-       /* this one pushes 9 elems, the next one would be %rIP */
        pushq %rdi
        pushq %rsi
        pushq %rdx
@@ -29,8 +28,8 @@
        pushq %r11
 
        .if \put_ret_addr_in_rdi
-       /* 9*8(%rsp) is return addr on stack */
-       movq 9*8(%rsp), %rdi
+       /* 8(%rbp) is return addr on stack */
+       movq 8(%rbp), %rdi
        .endif
 
        call \func
@@ -65,7 +64,7 @@
        popq %rdx
        popq %rsi
        popq %rdi
-       FRAME_END
+       popq %rbp
        ret
        _ASM_NOKPROBE(restore)
 #endif
diff --git a/arch/x86/include/asm/bugs.h b/arch/x86/include/asm/bugs.h
index 08abf639075f..5490bbaf71d5 100644
--- a/arch/x86/include/asm/bugs.h
+++ b/arch/x86/include/asm/bugs.h
@@ -1,8 +1,16 @@
 #ifndef _ASM_X86_BUGS_H
 #define _ASM_X86_BUGS_H
 
+#include <asm/processor.h>
+
 extern void check_bugs(void);
 
+#if defined(CONFIG_CPU_SUP_INTEL)
+void check_mpx_erratum(struct cpuinfo_x86 *c);
+#else
+static inline void check_mpx_erratum(struct cpuinfo_x86 *c) {}
+#endif
+
 #if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
 int ppro_with_ram_bug(void);
 #else
diff --git a/arch/x86/include/asm/cpufeature.h 
b/arch/x86/include/asm/cpufeature.h
index 25ebb54905e0..483fb547e3c0 100644
--- a/arch/x86/include/asm/cpufeature.h
+++ b/arch/x86/include/asm/cpufeature.h
@@ -64,9 +64,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
           (((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) ||   \
           (((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) ||   \
           (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) ||   \
-          (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK14)) ||   \
-          (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK15)) ||   \
-          (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK16)) )
+          (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK14)) ||   \
+          (((bit)>>5)==15 && (1UL<<((bit)&31) & REQUIRED_MASK15)) ||   \
+          (((bit)>>5)==16 && (1UL<<((bit)&31) & REQUIRED_MASK16)) )
 
 #define DISABLED_MASK_BIT_SET(bit)                                     \
         ( (((bit)>>5)==0  && (1UL<<((bit)&31) & DISABLED_MASK0 )) ||   \
@@ -83,9 +83,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
           (((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) ||   \
           (((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) ||   \
           (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) ||   \
-          (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK14)) ||   \
-          (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK15)) ||   \
-          (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK16)) )
+          (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK14)) ||   \
+          (((bit)>>5)==15 && (1UL<<((bit)&31) & DISABLED_MASK15)) ||   \
+          (((bit)>>5)==16 && (1UL<<((bit)&31) & DISABLED_MASK16)) )
 
 #define cpu_has(c, bit)                                                        
\
        (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :  \
diff --git a/arch/x86/include/asm/disabled-features.h 
b/arch/x86/include/asm/disabled-features.h
index 39343be7d4f4..911e9358ceb1 100644
--- a/arch/x86/include/asm/disabled-features.h
+++ b/arch/x86/include/asm/disabled-features.h
@@ -29,11 +29,11 @@
 #endif /* CONFIG_X86_64 */
 
 #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
-# define DISABLE_PKU           (1<<(X86_FEATURE_PKU))
-# define DISABLE_OSPKE         (1<<(X86_FEATURE_OSPKE))
-#else
 # define DISABLE_PKU           0
 # define DISABLE_OSPKE         0
+#else
+# define DISABLE_PKU           (1<<(X86_FEATURE_PKU & 31))
+# define DISABLE_OSPKE         (1<<(X86_FEATURE_OSPKE & 31))
 #endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
 
 /*
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 6ef6ed9ccca6..0fe6953f421c 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -37,6 +37,7 @@
 #include <asm/mtrr.h>
 #include <linux/numa.h>
 #include <asm/asm.h>
+#include <asm/bugs.h>
 #include <asm/cpu.h>
 #include <asm/mce.h>
 #include <asm/msr.h>
@@ -270,6 +271,8 @@ static inline void squash_the_stupid_serial_number(struct 
cpuinfo_x86 *c)
 static __init int setup_disable_smep(char *arg)
 {
        setup_clear_cpu_cap(X86_FEATURE_SMEP);
+       /* Check for things that depend on SMEP being enabled: */
+       check_mpx_erratum(&boot_cpu_data);
        return 1;
 }
 __setup("nosmep", setup_disable_smep);
@@ -310,6 +313,10 @@ static bool pku_disabled;
 
 static __always_inline void setup_pku(struct cpuinfo_x86 *c)
 {
+       /* check the boot processor, plus compile options for PKU: */
+       if (!cpu_feature_enabled(X86_FEATURE_PKU))
+               return;
+       /* checks the actual processor's cpuid bits: */
        if (!cpu_has(c, X86_FEATURE_PKU))
                return;
        if (pku_disabled)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 8dae51fd3db1..6e2ffbebbcdb 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -25,6 +25,41 @@
 #include <asm/apic.h>
 #endif
 
+/*
+ * Just in case our CPU detection goes bad, or you have a weird system,
+ * allow a way to override the automatic disabling of MPX.
+ */
+static int forcempx;
+
+static int __init forcempx_setup(char *__unused)
+{
+       forcempx = 1;
+
+       return 1;
+}
+__setup("intel-skd-046-workaround=disable", forcempx_setup);
+
+void check_mpx_erratum(struct cpuinfo_x86 *c)
+{
+       if (forcempx)
+               return;
+       /*
+        * Turn off the MPX feature on CPUs where SMEP is not
+        * available or disabled.
+        *
+        * Works around Intel Erratum SKD046: "Branch Instructions
+        * May Initialize MPX Bound Registers Incorrectly".
+        *
+        * This might falsely disable MPX on systems without
+        * SMEP, like Atom processors without SMEP.  But there
+        * is no such hardware known at the moment.
+        */
+       if (cpu_has(c, X86_FEATURE_MPX) && !cpu_has(c, X86_FEATURE_SMEP)) {
+               setup_clear_cpu_cap(X86_FEATURE_MPX);
+               pr_warn("x86/mpx: Disabling MPX since SMEP not present\n");
+       }
+}
+
 static void early_init_intel(struct cpuinfo_x86 *c)
 {
        u64 misc_enable;
@@ -173,6 +208,8 @@ static void early_init_intel(struct cpuinfo_x86 *c)
                if (edx & (1U << 28))
                        c->x86_coreid_bits = get_count_order((ebx >> 16) & 
0xff);
        }
+
+       check_mpx_erratum(c);
 }
 
 #ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 6b16c36f0939..6e789ca1f841 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -532,7 +532,7 @@ long do_arch_prctl(struct task_struct *task, int code, 
unsigned long addr)
 
        switch (code) {
        case ARCH_SET_GS:
-               if (addr >= TASK_SIZE_OF(task))
+               if (addr >= TASK_SIZE_MAX)
                        return -EPERM;
                cpu = get_cpu();
                task->thread.gsindex = 0;
@@ -546,7 +546,7 @@ long do_arch_prctl(struct task_struct *task, int code, 
unsigned long addr)
        case ARCH_SET_FS:
                /* Not strictly needed for fs, but do it for symmetry
                   with gs */
-               if (addr >= TASK_SIZE_OF(task))
+               if (addr >= TASK_SIZE_MAX)
                        return -EPERM;
                cpu = get_cpu();
                task->thread.fsindex = 0;
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index e60ef918f53d..600edd225e81 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -392,7 +392,7 @@ static int putreg(struct task_struct *child,
 
 #ifdef CONFIG_X86_64
        case offsetof(struct user_regs_struct,fs_base):
-               if (value >= TASK_SIZE_OF(child))
+               if (value >= TASK_SIZE_MAX)
                        return -EIO;
                /*
                 * When changing the segment base, use do_arch_prctl
@@ -406,7 +406,7 @@ static int putreg(struct task_struct *child,
                /*
                 * Exactly the same here as the %fs handling above.
                 */
-               if (value >= TASK_SIZE_OF(child))
+               if (value >= TASK_SIZE_MAX)
                        return -EIO;
                if (child->thread.gsbase != value)
                        return do_arch_prctl(child, ARCH_SET_GS, value);
diff --git a/arch/x86/kernel/tsc_msr.c b/arch/x86/kernel/tsc_msr.c
index 6aa0f4d9eea6..9911a0620f9a 100644
--- a/arch/x86/kernel/tsc_msr.c
+++ b/arch/x86/kernel/tsc_msr.c
@@ -23,6 +23,7 @@
 #include <asm/param.h>
 
 /* CPU reference clock frequency: in KHz */
+#define FREQ_80                80000
 #define FREQ_83                83200
 #define FREQ_100       99840
 #define FREQ_133       133200
@@ -56,6 +57,8 @@ static struct freq_desc freq_desc_tables[] = {
        { 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } },
        /* ANN */
        { 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } },
+       /* AIRMONT */
+       { 6, 0x4c, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, FREQ_80, 0, 0, 0 
} },
 };
 
 static int match_cpu(u8 family, u8 model)
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 5ce1ed02f7e8..7d1fa7cd2374 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -292,7 +292,7 @@ void vmalloc_sync_all(void)
                return;
 
        for (address = VMALLOC_START & PMD_MASK;
-            address >= TASK_SIZE && address < FIXADDR_TOP;
+            address >= TASK_SIZE_MAX && address < FIXADDR_TOP;
             address += PMD_SIZE) {
                struct page *page;
 
@@ -854,8 +854,13 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long 
error_code,
                                return;
                }
 #endif
-               /* Kernel addresses are always protection faults: */
-               if (address >= TASK_SIZE)
+
+               /*
+                * To avoid leaking information about the kernel page table
+                * layout, pretend that user-mode accesses to kernel addresses
+                * are always protection faults.
+                */
+               if (address >= TASK_SIZE_MAX)
                        error_code |= PF_PROT;
 
                if (likely(show_unhandled_signals))
diff --git a/arch/x86/platform/efi/efi_stub_64.S 
b/arch/x86/platform/efi/efi_stub_64.S
index 92723aeae0f9..cd95075944ab 100644
--- a/arch/x86/platform/efi/efi_stub_64.S
+++ b/arch/x86/platform/efi/efi_stub_64.S
@@ -11,7 +11,6 @@
 #include <asm/msr.h>
 #include <asm/processor-flags.h>
 #include <asm/page_types.h>
-#include <asm/frame.h>
 
 #define SAVE_XMM                       \
        mov %rsp, %rax;                 \
@@ -40,10 +39,10 @@
        mov (%rsp), %rsp
 
 ENTRY(efi_call)
-       FRAME_BEGIN
+       pushq %rbp
+       movq %rsp, %rbp
        SAVE_XMM
-       mov (%rsp), %rax
-       mov 8(%rax), %rax
+       mov 16(%rbp), %rax
        subq $48, %rsp
        mov %r9, 32(%rsp)
        mov %rax, 40(%rsp)
@@ -53,6 +52,6 @@ ENTRY(efi_call)
        call *%rdi
        addq $48, %rsp
        RESTORE_XMM
-       FRAME_END
+       popq %rbp
        ret
 ENDPROC(efi_call)

Reply via email to