提交 2f7c3a18 编写于 作者: 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 Ingo Molnar:
 "Misc fixes: EFI, entry code, pkeys and MPX fixes, TASK_SIZE cleanups
  and a tsc frequency table fix"

* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/mm: Switch from TASK_SIZE to TASK_SIZE_MAX in the page fault code
  x86/fsgsbase/64: Use TASK_SIZE_MAX for FSBASE/GSBASE upper limits
  x86/mm/mpx: Work around MPX erratum SKD046
  x86/entry/64: Fix stack return address retrieval in thunk
  x86/efi: Fix 7-parameter efi_call()s
  x86/cpufeature, x86/mm/pkeys: Fix broken compile-time disabling of pkeys
  x86/tsc: Add missing Cherrytrail frequency to the table
...@@ -8,16 +8,15 @@ ...@@ -8,16 +8,15 @@
#include <linux/linkage.h> #include <linux/linkage.h>
#include "calling.h" #include "calling.h"
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/frame.h>
/* rdi: arg1 ... normal C conventions. rax is saved/restored. */ /* rdi: arg1 ... normal C conventions. rax is saved/restored. */
.macro THUNK name, func, put_ret_addr_in_rdi=0 .macro THUNK name, func, put_ret_addr_in_rdi=0
.globl \name .globl \name
.type \name, @function .type \name, @function
\name: \name:
FRAME_BEGIN pushq %rbp
movq %rsp, %rbp
/* this one pushes 9 elems, the next one would be %rIP */
pushq %rdi pushq %rdi
pushq %rsi pushq %rsi
pushq %rdx pushq %rdx
...@@ -29,8 +28,8 @@ ...@@ -29,8 +28,8 @@
pushq %r11 pushq %r11
.if \put_ret_addr_in_rdi .if \put_ret_addr_in_rdi
/* 9*8(%rsp) is return addr on stack */ /* 8(%rbp) is return addr on stack */
movq 9*8(%rsp), %rdi movq 8(%rbp), %rdi
.endif .endif
call \func call \func
...@@ -65,7 +64,7 @@ restore: ...@@ -65,7 +64,7 @@ restore:
popq %rdx popq %rdx
popq %rsi popq %rsi
popq %rdi popq %rdi
FRAME_END popq %rbp
ret ret
_ASM_NOKPROBE(restore) _ASM_NOKPROBE(restore)
#endif #endif
#ifndef _ASM_X86_BUGS_H #ifndef _ASM_X86_BUGS_H
#define _ASM_X86_BUGS_H #define _ASM_X86_BUGS_H
#include <asm/processor.h>
extern void check_bugs(void); 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) #if defined(CONFIG_CPU_SUP_INTEL) && defined(CONFIG_X86_32)
int ppro_with_ram_bug(void); int ppro_with_ram_bug(void);
#else #else
......
...@@ -64,9 +64,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; ...@@ -64,9 +64,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
(((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \ (((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) || \
(((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \ (((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) || \
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \ (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) || \
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \ (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK14)) || \
(((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \ (((bit)>>5)==15 && (1UL<<((bit)&31) & REQUIRED_MASK15)) || \
(((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK16)) ) (((bit)>>5)==16 && (1UL<<((bit)&31) & REQUIRED_MASK16)) )
#define DISABLED_MASK_BIT_SET(bit) \ #define DISABLED_MASK_BIT_SET(bit) \
( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \ ( (((bit)>>5)==0 && (1UL<<((bit)&31) & DISABLED_MASK0 )) || \
...@@ -83,9 +83,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32]; ...@@ -83,9 +83,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
(((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \ (((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) || \
(((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \ (((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) || \
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \ (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) || \
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \ (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK14)) || \
(((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \ (((bit)>>5)==15 && (1UL<<((bit)&31) & DISABLED_MASK15)) || \
(((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK16)) ) (((bit)>>5)==16 && (1UL<<((bit)&31) & DISABLED_MASK16)) )
#define cpu_has(c, bit) \ #define cpu_has(c, bit) \
(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \ (__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 : \
......
...@@ -29,11 +29,11 @@ ...@@ -29,11 +29,11 @@
#endif /* CONFIG_X86_64 */ #endif /* CONFIG_X86_64 */
#ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS #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_PKU 0
# define DISABLE_OSPKE 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 */ #endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
/* /*
......
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <asm/mtrr.h> #include <asm/mtrr.h>
#include <linux/numa.h> #include <linux/numa.h>
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/bugs.h>
#include <asm/cpu.h> #include <asm/cpu.h>
#include <asm/mce.h> #include <asm/mce.h>
#include <asm/msr.h> #include <asm/msr.h>
...@@ -270,6 +271,8 @@ static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c) ...@@ -270,6 +271,8 @@ static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
static __init int setup_disable_smep(char *arg) static __init int setup_disable_smep(char *arg)
{ {
setup_clear_cpu_cap(X86_FEATURE_SMEP); setup_clear_cpu_cap(X86_FEATURE_SMEP);
/* Check for things that depend on SMEP being enabled: */
check_mpx_erratum(&boot_cpu_data);
return 1; return 1;
} }
__setup("nosmep", setup_disable_smep); __setup("nosmep", setup_disable_smep);
...@@ -310,6 +313,10 @@ static bool pku_disabled; ...@@ -310,6 +313,10 @@ static bool pku_disabled;
static __always_inline void setup_pku(struct cpuinfo_x86 *c) 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)) if (!cpu_has(c, X86_FEATURE_PKU))
return; return;
if (pku_disabled) if (pku_disabled)
......
...@@ -25,6 +25,41 @@ ...@@ -25,6 +25,41 @@
#include <asm/apic.h> #include <asm/apic.h>
#endif #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) static void early_init_intel(struct cpuinfo_x86 *c)
{ {
u64 misc_enable; u64 misc_enable;
...@@ -173,6 +208,8 @@ static void early_init_intel(struct cpuinfo_x86 *c) ...@@ -173,6 +208,8 @@ static void early_init_intel(struct cpuinfo_x86 *c)
if (edx & (1U << 28)) if (edx & (1U << 28))
c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff); c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff);
} }
check_mpx_erratum(c);
} }
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
......
...@@ -532,7 +532,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) ...@@ -532,7 +532,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
switch (code) { switch (code) {
case ARCH_SET_GS: case ARCH_SET_GS:
if (addr >= TASK_SIZE_OF(task)) if (addr >= TASK_SIZE_MAX)
return -EPERM; return -EPERM;
cpu = get_cpu(); cpu = get_cpu();
task->thread.gsindex = 0; task->thread.gsindex = 0;
...@@ -546,7 +546,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) ...@@ -546,7 +546,7 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr)
case ARCH_SET_FS: case ARCH_SET_FS:
/* Not strictly needed for fs, but do it for symmetry /* Not strictly needed for fs, but do it for symmetry
with gs */ with gs */
if (addr >= TASK_SIZE_OF(task)) if (addr >= TASK_SIZE_MAX)
return -EPERM; return -EPERM;
cpu = get_cpu(); cpu = get_cpu();
task->thread.fsindex = 0; task->thread.fsindex = 0;
......
...@@ -392,7 +392,7 @@ static int putreg(struct task_struct *child, ...@@ -392,7 +392,7 @@ static int putreg(struct task_struct *child,
#ifdef CONFIG_X86_64 #ifdef CONFIG_X86_64
case offsetof(struct user_regs_struct,fs_base): case offsetof(struct user_regs_struct,fs_base):
if (value >= TASK_SIZE_OF(child)) if (value >= TASK_SIZE_MAX)
return -EIO; return -EIO;
/* /*
* When changing the segment base, use do_arch_prctl * When changing the segment base, use do_arch_prctl
...@@ -406,7 +406,7 @@ static int putreg(struct task_struct *child, ...@@ -406,7 +406,7 @@ static int putreg(struct task_struct *child,
/* /*
* Exactly the same here as the %fs handling above. * Exactly the same here as the %fs handling above.
*/ */
if (value >= TASK_SIZE_OF(child)) if (value >= TASK_SIZE_MAX)
return -EIO; return -EIO;
if (child->thread.gsbase != value) if (child->thread.gsbase != value)
return do_arch_prctl(child, ARCH_SET_GS, value); return do_arch_prctl(child, ARCH_SET_GS, value);
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <asm/param.h> #include <asm/param.h>
/* CPU reference clock frequency: in KHz */ /* CPU reference clock frequency: in KHz */
#define FREQ_80 80000
#define FREQ_83 83200 #define FREQ_83 83200
#define FREQ_100 99840 #define FREQ_100 99840
#define FREQ_133 133200 #define FREQ_133 133200
...@@ -56,6 +57,8 @@ static struct freq_desc freq_desc_tables[] = { ...@@ -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 } }, { 6, 0x37, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_166, 0, 0, 0, 0 } },
/* ANN */ /* ANN */
{ 6, 0x5a, 1, { FREQ_83, FREQ_100, FREQ_133, FREQ_100, 0, 0, 0, 0 } }, { 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) static int match_cpu(u8 family, u8 model)
......
...@@ -292,7 +292,7 @@ void vmalloc_sync_all(void) ...@@ -292,7 +292,7 @@ void vmalloc_sync_all(void)
return; return;
for (address = VMALLOC_START & PMD_MASK; for (address = VMALLOC_START & PMD_MASK;
address >= TASK_SIZE && address < FIXADDR_TOP; address >= TASK_SIZE_MAX && address < FIXADDR_TOP;
address += PMD_SIZE) { address += PMD_SIZE) {
struct page *page; struct page *page;
...@@ -854,8 +854,13 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, ...@@ -854,8 +854,13 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
return; return;
} }
#endif #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; error_code |= PF_PROT;
if (likely(show_unhandled_signals)) if (likely(show_unhandled_signals))
......
...@@ -11,7 +11,6 @@ ...@@ -11,7 +11,6 @@
#include <asm/msr.h> #include <asm/msr.h>
#include <asm/processor-flags.h> #include <asm/processor-flags.h>
#include <asm/page_types.h> #include <asm/page_types.h>
#include <asm/frame.h>
#define SAVE_XMM \ #define SAVE_XMM \
mov %rsp, %rax; \ mov %rsp, %rax; \
...@@ -40,10 +39,10 @@ ...@@ -40,10 +39,10 @@
mov (%rsp), %rsp mov (%rsp), %rsp
ENTRY(efi_call) ENTRY(efi_call)
FRAME_BEGIN pushq %rbp
movq %rsp, %rbp
SAVE_XMM SAVE_XMM
mov (%rsp), %rax mov 16(%rbp), %rax
mov 8(%rax), %rax
subq $48, %rsp subq $48, %rsp
mov %r9, 32(%rsp) mov %r9, 32(%rsp)
mov %rax, 40(%rsp) mov %rax, 40(%rsp)
...@@ -53,6 +52,6 @@ ENTRY(efi_call) ...@@ -53,6 +52,6 @@ ENTRY(efi_call)
call *%rdi call *%rdi
addq $48, %rsp addq $48, %rsp
RESTORE_XMM RESTORE_XMM
FRAME_END popq %rbp
ret ret
ENDPROC(efi_call) ENDPROC(efi_call)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册