* [PATCH v3 0/7] x86: Pile o' FS/GS changes @ 2016-04-08 0:31 Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 1/7] selftests/x86: Test the FSBASE/GSBASE API and context switching Andy Lutomirski ` (6 more replies) 0 siblings, 7 replies; 16+ messages in thread From: Andy Lutomirski @ 2016-04-08 0:31 UTC (permalink / raw) To: Borislav Petkov, security, x86, linux-kernel Cc: Linus Torvalds, Rudolf Marek, Andy Lutomirski Hi all- This whole mess is intended for x86/urgent. It fixes several bugs. It's probably a tiny performance regression on some workloads on Intel CPUs. It's probably varies between a less tiny regression and a small speedup on newer AMD CPUs. It's a bigger regression on AMD K8. The AMD code could be further sped up by adding a new 'clear_gs' pvop with a better native implementation. I don't particularly want to deal with a backported new pvop, so I didn't do that. Maybe I'll do it later on for new kernels, though. (For people who care about such things, there are probably three bugs in here depending how you count. Somewhere between one and two of them were independently discovered by Rudolf Marek.) Andy Lutomirski (5): selftests/x86: Test the FSBASE/GSBASE API and context switching x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS x86/cpu: Probe the behavior of nulling out a segment at boot time x86/switch_to: Rewrite the FS and GS context switch code x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify Borislav Petkov (2): x86/cpu: Add Erratum 88 detection on AMD x86/entry: Make gs_change a local label arch/x86/entry/entry_64.S | 12 +- arch/x86/include/asm/cpufeatures.h | 3 + arch/x86/kernel/cpu/amd.c | 1 + arch/x86/kernel/cpu/common.c | 71 ++++-- arch/x86/kernel/process_64.c | 167 ++++++++------ tools/testing/selftests/x86/Makefile | 1 + tools/testing/selftests/x86/fsgsbase.c | 398 +++++++++++++++++++++++++++++++++ 7 files changed, 560 insertions(+), 93 deletions(-) create mode 100644 tools/testing/selftests/x86/fsgsbase.c -- 2.5.5 ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3 1/7] selftests/x86: Test the FSBASE/GSBASE API and context switching 2016-04-08 0:31 [PATCH v3 0/7] x86: Pile o' FS/GS changes Andy Lutomirski @ 2016-04-08 0:31 ` Andy Lutomirski 2016-04-13 11:28 ` [tip:x86/asm] " tip-bot for Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 5/7] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify Andy Lutomirski ` (5 subsequent siblings) 6 siblings, 1 reply; 16+ messages in thread From: Andy Lutomirski @ 2016-04-08 0:31 UTC (permalink / raw) To: Borislav Petkov, security, x86, linux-kernel Cc: Linus Torvalds, Rudolf Marek, Andy Lutomirski This catches two distinct bugs in the current code. I'll fix them. Signed-off-by: Andy Lutomirski <luto@kernel.org> --- tools/testing/selftests/x86/Makefile | 1 + tools/testing/selftests/x86/fsgsbase.c | 398 +++++++++++++++++++++++++++++++++ 2 files changed, 399 insertions(+) create mode 100644 tools/testing/selftests/x86/fsgsbase.c diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index b47ebd170690..c73425de3cfe 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -9,6 +9,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_sysc TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ vdso_restorer +TARGETS_C_64BIT_ONLY := fsgsbase TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c new file mode 100644 index 000000000000..b7733055a359 --- /dev/null +++ b/tools/testing/selftests/x86/fsgsbase.c @@ -0,0 +1,398 @@ +/* + * fsgsbase.c, an fsgsbase test + * Copyright (c) 2014-2016 Andy Lutomirski + * GPL v2 + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <err.h> +#include <sys/user.h> +#include <asm/prctl.h> +#include <sys/prctl.h> +#include <signal.h> +#include <limits.h> +#include <sys/ucontext.h> +#include <sched.h> +#include <linux/futex.h> +#include <pthread.h> +#include <asm/ldt.h> +#include <sys/mman.h> + +#ifndef __x86_64__ +# error This test is 64-bit only +#endif + +static volatile sig_atomic_t want_segv; +static volatile unsigned long segv_addr; + +static int nerrs; + +static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + int flags) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | flags; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} + +static void clearhandler(int sig) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} + +static void sigsegv(int sig, siginfo_t *si, void *ctx_void) +{ + ucontext_t *ctx = (ucontext_t*)ctx_void; + + if (!want_segv) { + clearhandler(SIGSEGV); + return; /* Crash cleanly. */ + } + + want_segv = false; + segv_addr = (unsigned long)si->si_addr; + + ctx->uc_mcontext.gregs[REG_RIP] += 4; /* Skip the faulting mov */ + +} + +enum which_base { FS, GS }; + +static unsigned long read_base(enum which_base which) +{ + unsigned long offset; + /* + * Unless we have FSGSBASE, there's no direct way to do this from + * user mode. We can get at it indirectly using signals, though. + */ + + want_segv = true; + + offset = 0; + if (which == FS) { + /* Use a constant-length instruction here. */ + asm volatile ("mov %%fs:(%%rcx), %%rax" : : "c" (offset) : "rax"); + } else { + asm volatile ("mov %%gs:(%%rcx), %%rax" : : "c" (offset) : "rax"); + } + if (!want_segv) + return segv_addr + offset; + + /* + * If that didn't segfault, try the other end of the address space. + * Unless we get really unlucky and run into the vsyscall page, this + * is guaranteed to segfault. + */ + + offset = (ULONG_MAX >> 1) + 1; + if (which == FS) { + asm volatile ("mov %%fs:(%%rcx), %%rax" + : : "c" (offset) : "rax"); + } else { + asm volatile ("mov %%gs:(%%rcx), %%rax" + : : "c" (offset) : "rax"); + } + if (!want_segv) + return segv_addr + offset; + + abort(); +} + +static void check_gs_value(unsigned long value) +{ + unsigned long base; + unsigned short sel; + + printf("[RUN]\tARCH_SET_GS to 0x%lx\n", value); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, value) != 0) + err(1, "ARCH_SET_GS"); + + asm volatile ("mov %%gs, %0" : "=rm" (sel)); + base = read_base(GS); + if (base == value) { + printf("[OK]\tGSBASE was set as expected (selector 0x%hx)\n", + sel); + } else { + nerrs++; + printf("[FAIL]\tGSBASE was not as expected: got 0x%lx (selector 0x%hx)\n", + base, sel); + } + + if (syscall(SYS_arch_prctl, ARCH_GET_GS, &base) != 0) + err(1, "ARCH_GET_GS"); + if (base == value) { + printf("[OK]\tARCH_GET_GS worked as expected (selector 0x%hx)\n", + sel); + } else { + nerrs++; + printf("[FAIL]\tARCH_GET_GS was not as expected: got 0x%lx (selector 0x%hx)\n", + base, sel); + } +} + +static void mov_0_gs(unsigned long initial_base, bool schedule) +{ + unsigned long base, arch_base; + + printf("[RUN]\tARCH_SET_GS to 0x%lx then mov 0 to %%gs%s\n", initial_base, schedule ? " and schedule " : ""); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, initial_base) != 0) + err(1, "ARCH_SET_GS"); + + if (schedule) + usleep(10); + + asm volatile ("mov %0, %%gs" : : "rm" (0)); + base = read_base(GS); + if (syscall(SYS_arch_prctl, ARCH_GET_GS, &arch_base) != 0) + err(1, "ARCH_GET_GS"); + if (base == arch_base) { + printf("[OK]\tGSBASE is 0x%lx\n", base); + } else { + nerrs++; + printf("[FAIL]\tGSBASE changed to 0x%lx but kernel reports 0x%lx\n", base, arch_base); + } +} + +static volatile unsigned long remote_base; +static volatile bool remote_hard_zero; +static volatile unsigned int ftx; + +/* + * ARCH_SET_FS/GS(0) may or may not program a selector of zero. HARD_ZERO + * means to force the selector to zero to improve test coverage. + */ +#define HARD_ZERO 0xa1fa5f343cb85fa4 + +static void do_remote_base() +{ + unsigned long to_set = remote_base; + bool hard_zero = false; + if (to_set == HARD_ZERO) { + to_set = 0; + hard_zero = true; + } + + if (syscall(SYS_arch_prctl, ARCH_SET_GS, to_set) != 0) + err(1, "ARCH_SET_GS"); + + if (hard_zero) + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); + + unsigned short sel; + asm volatile ("mov %%gs, %0" : "=rm" (sel)); + printf("\tother thread: ARCH_SET_GS(0x%lx)%s -- sel is 0x%hx\n", + to_set, hard_zero ? " and clear gs" : "", sel); +} + +void do_unexpected_base(void) +{ + /* + * The goal here is to try to arrange for GS == 0, GSBASE != + * 0, and for the the kernel the think that GSBASE == 0. + * + * To make the test as reliable as possible, this uses + * explicit descriptorss. (This is not the only way. This + * could use ARCH_SET_GS with a low, nonzero base, but the + * relevant side effect of ARCH_SET_GS could change.) + */ + + /* Step 1: tell the kernel that we have GSBASE == 0. */ + if (syscall(SYS_arch_prctl, ARCH_SET_GS, 0) != 0) + err(1, "ARCH_SET_GS"); + + /* Step 2: change GSBASE without telling the kernel. */ + struct user_desc desc = { + .entry_number = 0, + .base_addr = 0xBAADF00D, + .limit = 0xfffff, + .seg_32bit = 1, + .contents = 0, /* Data, grow-up */ + .read_exec_only = 0, + .limit_in_pages = 1, + .seg_not_present = 0, + .useable = 0 + }; + if (syscall(SYS_modify_ldt, 1, &desc, sizeof(desc)) == 0) { + printf("\tother thread: using LDT slot 0\n"); + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0x7)); + } else { + /* No modify_ldt for us (configured out, perhaps) */ + + struct user_desc *low_desc = mmap( + NULL, sizeof(desc), + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + memcpy(low_desc, &desc, sizeof(desc)); + + low_desc->entry_number = -1; + + /* 32-bit set_thread_area */ + long ret; + asm volatile ("int $0x80" + : "=a" (ret) : "a" (243), "b" (low_desc) + : "flags"); + memcpy(&desc, low_desc, sizeof(desc)); + munmap(low_desc, sizeof(desc)); + + if (ret != 0) { + printf("[NOTE]\tcould not create a segment -- test won't do anything\n"); + return; + } + printf("\tother thread: using GDT slot %d\n", desc.entry_number); + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)((desc.entry_number << 3) | 0x3))); + } + + /* + * Step 3: set the selector back to zero. On AMD chips, this will + * preserve GSBASE. + */ + + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); +} + +static void *threadproc(void *ctx) +{ + while (1) { + while (ftx == 0) + syscall(SYS_futex, &ftx, FUTEX_WAIT, 0, NULL, NULL, 0); + if (ftx == 3) + return NULL; + + if (ftx == 1) + do_remote_base(); + else if (ftx == 2) + do_unexpected_base(); + else + errx(1, "helper thread got bad command"); + + ftx = 0; + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + } +} + +static void set_gs_and_switch_to(unsigned long local, unsigned long remote) +{ + unsigned long base; + + bool hard_zero = false; + if (local == HARD_ZERO) { + hard_zero = true; + local = 0; + } + + printf("[RUN]\tARCH_SET_GS(0x%lx)%s, then schedule to 0x%lx\n", + local, hard_zero ? " and clear gs" : "", remote); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, local) != 0) + err(1, "ARCH_SET_GS"); + if (hard_zero) + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); + + if (read_base(GS) != local) { + nerrs++; + printf("[FAIL]\tGSBASE wasn't set as expected\n"); + } + + remote_base = remote; + ftx = 1; + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + while (ftx != 0) + syscall(SYS_futex, &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); + + base = read_base(GS); + if (base == local) { + printf("[OK]\tGSBASE remained 0x%lx\n", local); + } else { + nerrs++; + printf("[FAIL]\tGSBASE changed to 0x%lx\n", base); + } +} + +static void test_unexpected_base(void) +{ + unsigned long base; + + printf("[RUN]\tARCH_SET_GS(0), clear gs, then manipulate GSBASE in a different thread\n"); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, 0) != 0) + err(1, "ARCH_SET_GS"); + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); + + ftx = 2; + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + while (ftx != 0) + syscall(SYS_futex, &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); + + base = read_base(GS); + if (base == 0) { + printf("[OK]\tGSBASE remained 0\n"); + } else { + nerrs++; + printf("[FAIL]\tGSBASE changed to 0x%lx\n", base); + } +} + +int main() +{ + pthread_t thread; + + sethandler(SIGSEGV, sigsegv, 0); + + check_gs_value(0); + check_gs_value(1); + check_gs_value(0x200000000); + check_gs_value(0); + check_gs_value(0x200000000); + check_gs_value(1); + + for (int sched = 0; sched < 2; sched++) { + mov_0_gs(0, !!sched); + mov_0_gs(1, !!sched); + mov_0_gs(0x200000000, !!sched); + } + + /* Set up for multithreading. */ + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) + err(1, "sched_setaffinity to CPU 0"); /* should never fail */ + + if (pthread_create(&thread, 0, threadproc, 0) != 0) + err(1, "pthread_create"); + + static unsigned long bases_with_hard_zero[] = { + 0, HARD_ZERO, 1, 0x200000000, + }; + + for (int local = 0; local < 4; local++) { + for (int remote = 0; remote < 4; remote++) { + set_gs_and_switch_to(bases_with_hard_zero[local], + bases_with_hard_zero[remote]); + } + } + + test_unexpected_base(); + + ftx = 3; /* Kill the thread. */ + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + + if (pthread_join(thread, NULL) != 0) + err(1, "pthread_join"); + + return nerrs == 0 ? 0 : 1; +} -- 2.5.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [tip:x86/asm] selftests/x86: Test the FSBASE/GSBASE API and context switching 2016-04-08 0:31 ` [PATCH v3 1/7] selftests/x86: Test the FSBASE/GSBASE API and context switching Andy Lutomirski @ 2016-04-13 11:28 ` tip-bot for Andy Lutomirski 0 siblings, 0 replies; 16+ messages in thread From: tip-bot for Andy Lutomirski @ 2016-04-13 11:28 UTC (permalink / raw) To: linux-tip-commits Cc: mingo, bp, bp, hpa, tglx, linux-kernel, r.marek, luto, peterz, luto, dvlasenk, brgerst, torvalds Commit-ID: 0051202f6ad5fd9c04d220343e66d1eb890f7b81 Gitweb: http://git.kernel.org/tip/0051202f6ad5fd9c04d220343e66d1eb890f7b81 Author: Andy Lutomirski <luto@kernel.org> AuthorDate: Thu, 7 Apr 2016 17:31:44 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Wed, 13 Apr 2016 10:20:41 +0200 selftests/x86: Test the FSBASE/GSBASE API and context switching This catches two distinct bugs in the current code. I'll fix them. Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Borislav Petkov <bp@suse.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rudolf Marek <r.marek@assembler.cz> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/7e5941148d1e2199f070dadcdf7355959f5f8e85.1460075211.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- tools/testing/selftests/x86/Makefile | 1 + tools/testing/selftests/x86/fsgsbase.c | 398 +++++++++++++++++++++++++++++++++ 2 files changed, 399 insertions(+) diff --git a/tools/testing/selftests/x86/Makefile b/tools/testing/selftests/x86/Makefile index b47ebd1..c73425d 100644 --- a/tools/testing/selftests/x86/Makefile +++ b/tools/testing/selftests/x86/Makefile @@ -9,6 +9,7 @@ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_sysc TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \ test_FCMOV test_FCOMI test_FISTTP \ vdso_restorer +TARGETS_C_64BIT_ONLY := fsgsbase TARGETS_C_32BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_32BIT_ONLY) TARGETS_C_64BIT_ALL := $(TARGETS_C_BOTHBITS) $(TARGETS_C_64BIT_ONLY) diff --git a/tools/testing/selftests/x86/fsgsbase.c b/tools/testing/selftests/x86/fsgsbase.c new file mode 100644 index 0000000..5b2b4b3 --- /dev/null +++ b/tools/testing/selftests/x86/fsgsbase.c @@ -0,0 +1,398 @@ +/* + * fsgsbase.c, an fsgsbase test + * Copyright (c) 2014-2016 Andy Lutomirski + * GPL v2 + */ + +#define _GNU_SOURCE +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <sys/syscall.h> +#include <unistd.h> +#include <err.h> +#include <sys/user.h> +#include <asm/prctl.h> +#include <sys/prctl.h> +#include <signal.h> +#include <limits.h> +#include <sys/ucontext.h> +#include <sched.h> +#include <linux/futex.h> +#include <pthread.h> +#include <asm/ldt.h> +#include <sys/mman.h> + +#ifndef __x86_64__ +# error This test is 64-bit only +#endif + +static volatile sig_atomic_t want_segv; +static volatile unsigned long segv_addr; + +static int nerrs; + +static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *), + int flags) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = handler; + sa.sa_flags = SA_SIGINFO | flags; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} + +static void clearhandler(int sig) +{ + struct sigaction sa; + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigemptyset(&sa.sa_mask); + if (sigaction(sig, &sa, 0)) + err(1, "sigaction"); +} + +static void sigsegv(int sig, siginfo_t *si, void *ctx_void) +{ + ucontext_t *ctx = (ucontext_t*)ctx_void; + + if (!want_segv) { + clearhandler(SIGSEGV); + return; /* Crash cleanly. */ + } + + want_segv = false; + segv_addr = (unsigned long)si->si_addr; + + ctx->uc_mcontext.gregs[REG_RIP] += 4; /* Skip the faulting mov */ + +} + +enum which_base { FS, GS }; + +static unsigned long read_base(enum which_base which) +{ + unsigned long offset; + /* + * Unless we have FSGSBASE, there's no direct way to do this from + * user mode. We can get at it indirectly using signals, though. + */ + + want_segv = true; + + offset = 0; + if (which == FS) { + /* Use a constant-length instruction here. */ + asm volatile ("mov %%fs:(%%rcx), %%rax" : : "c" (offset) : "rax"); + } else { + asm volatile ("mov %%gs:(%%rcx), %%rax" : : "c" (offset) : "rax"); + } + if (!want_segv) + return segv_addr + offset; + + /* + * If that didn't segfault, try the other end of the address space. + * Unless we get really unlucky and run into the vsyscall page, this + * is guaranteed to segfault. + */ + + offset = (ULONG_MAX >> 1) + 1; + if (which == FS) { + asm volatile ("mov %%fs:(%%rcx), %%rax" + : : "c" (offset) : "rax"); + } else { + asm volatile ("mov %%gs:(%%rcx), %%rax" + : : "c" (offset) : "rax"); + } + if (!want_segv) + return segv_addr + offset; + + abort(); +} + +static void check_gs_value(unsigned long value) +{ + unsigned long base; + unsigned short sel; + + printf("[RUN]\tARCH_SET_GS to 0x%lx\n", value); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, value) != 0) + err(1, "ARCH_SET_GS"); + + asm volatile ("mov %%gs, %0" : "=rm" (sel)); + base = read_base(GS); + if (base == value) { + printf("[OK]\tGSBASE was set as expected (selector 0x%hx)\n", + sel); + } else { + nerrs++; + printf("[FAIL]\tGSBASE was not as expected: got 0x%lx (selector 0x%hx)\n", + base, sel); + } + + if (syscall(SYS_arch_prctl, ARCH_GET_GS, &base) != 0) + err(1, "ARCH_GET_GS"); + if (base == value) { + printf("[OK]\tARCH_GET_GS worked as expected (selector 0x%hx)\n", + sel); + } else { + nerrs++; + printf("[FAIL]\tARCH_GET_GS was not as expected: got 0x%lx (selector 0x%hx)\n", + base, sel); + } +} + +static void mov_0_gs(unsigned long initial_base, bool schedule) +{ + unsigned long base, arch_base; + + printf("[RUN]\tARCH_SET_GS to 0x%lx then mov 0 to %%gs%s\n", initial_base, schedule ? " and schedule " : ""); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, initial_base) != 0) + err(1, "ARCH_SET_GS"); + + if (schedule) + usleep(10); + + asm volatile ("mov %0, %%gs" : : "rm" (0)); + base = read_base(GS); + if (syscall(SYS_arch_prctl, ARCH_GET_GS, &arch_base) != 0) + err(1, "ARCH_GET_GS"); + if (base == arch_base) { + printf("[OK]\tGSBASE is 0x%lx\n", base); + } else { + nerrs++; + printf("[FAIL]\tGSBASE changed to 0x%lx but kernel reports 0x%lx\n", base, arch_base); + } +} + +static volatile unsigned long remote_base; +static volatile bool remote_hard_zero; +static volatile unsigned int ftx; + +/* + * ARCH_SET_FS/GS(0) may or may not program a selector of zero. HARD_ZERO + * means to force the selector to zero to improve test coverage. + */ +#define HARD_ZERO 0xa1fa5f343cb85fa4 + +static void do_remote_base() +{ + unsigned long to_set = remote_base; + bool hard_zero = false; + if (to_set == HARD_ZERO) { + to_set = 0; + hard_zero = true; + } + + if (syscall(SYS_arch_prctl, ARCH_SET_GS, to_set) != 0) + err(1, "ARCH_SET_GS"); + + if (hard_zero) + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); + + unsigned short sel; + asm volatile ("mov %%gs, %0" : "=rm" (sel)); + printf("\tother thread: ARCH_SET_GS(0x%lx)%s -- sel is 0x%hx\n", + to_set, hard_zero ? " and clear gs" : "", sel); +} + +void do_unexpected_base(void) +{ + /* + * The goal here is to try to arrange for GS == 0, GSBASE != + * 0, and for the the kernel the think that GSBASE == 0. + * + * To make the test as reliable as possible, this uses + * explicit descriptorss. (This is not the only way. This + * could use ARCH_SET_GS with a low, nonzero base, but the + * relevant side effect of ARCH_SET_GS could change.) + */ + + /* Step 1: tell the kernel that we have GSBASE == 0. */ + if (syscall(SYS_arch_prctl, ARCH_SET_GS, 0) != 0) + err(1, "ARCH_SET_GS"); + + /* Step 2: change GSBASE without telling the kernel. */ + struct user_desc desc = { + .entry_number = 0, + .base_addr = 0xBAADF00D, + .limit = 0xfffff, + .seg_32bit = 1, + .contents = 0, /* Data, grow-up */ + .read_exec_only = 0, + .limit_in_pages = 1, + .seg_not_present = 0, + .useable = 0 + }; + if (syscall(SYS_modify_ldt, 1, &desc, sizeof(desc)) == 0) { + printf("\tother thread: using LDT slot 0\n"); + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0x7)); + } else { + /* No modify_ldt for us (configured out, perhaps) */ + + struct user_desc *low_desc = mmap( + NULL, sizeof(desc), + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_32BIT, -1, 0); + memcpy(low_desc, &desc, sizeof(desc)); + + low_desc->entry_number = -1; + + /* 32-bit set_thread_area */ + long ret; + asm volatile ("int $0x80" + : "=a" (ret) : "a" (243), "b" (low_desc) + : "flags"); + memcpy(&desc, low_desc, sizeof(desc)); + munmap(low_desc, sizeof(desc)); + + if (ret != 0) { + printf("[NOTE]\tcould not create a segment -- test won't do anything\n"); + return; + } + printf("\tother thread: using GDT slot %d\n", desc.entry_number); + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)((desc.entry_number << 3) | 0x3))); + } + + /* + * Step 3: set the selector back to zero. On AMD chips, this will + * preserve GSBASE. + */ + + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); +} + +static void *threadproc(void *ctx) +{ + while (1) { + while (ftx == 0) + syscall(SYS_futex, &ftx, FUTEX_WAIT, 0, NULL, NULL, 0); + if (ftx == 3) + return NULL; + + if (ftx == 1) + do_remote_base(); + else if (ftx == 2) + do_unexpected_base(); + else + errx(1, "helper thread got bad command"); + + ftx = 0; + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + } +} + +static void set_gs_and_switch_to(unsigned long local, unsigned long remote) +{ + unsigned long base; + + bool hard_zero = false; + if (local == HARD_ZERO) { + hard_zero = true; + local = 0; + } + + printf("[RUN]\tARCH_SET_GS(0x%lx)%s, then schedule to 0x%lx\n", + local, hard_zero ? " and clear gs" : "", remote); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, local) != 0) + err(1, "ARCH_SET_GS"); + if (hard_zero) + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); + + if (read_base(GS) != local) { + nerrs++; + printf("[FAIL]\tGSBASE wasn't set as expected\n"); + } + + remote_base = remote; + ftx = 1; + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + while (ftx != 0) + syscall(SYS_futex, &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); + + base = read_base(GS); + if (base == local) { + printf("[OK]\tGSBASE remained 0x%lx\n", local); + } else { + nerrs++; + printf("[FAIL]\tGSBASE changed to 0x%lx\n", base); + } +} + +static void test_unexpected_base(void) +{ + unsigned long base; + + printf("[RUN]\tARCH_SET_GS(0), clear gs, then manipulate GSBASE in a different thread\n"); + if (syscall(SYS_arch_prctl, ARCH_SET_GS, 0) != 0) + err(1, "ARCH_SET_GS"); + asm volatile ("mov %0, %%gs" : : "rm" ((unsigned short)0)); + + ftx = 2; + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + while (ftx != 0) + syscall(SYS_futex, &ftx, FUTEX_WAIT, 1, NULL, NULL, 0); + + base = read_base(GS); + if (base == 0) { + printf("[OK]\tGSBASE remained 0\n"); + } else { + nerrs++; + printf("[FAIL]\tGSBASE changed to 0x%lx\n", base); + } +} + +int main() +{ + pthread_t thread; + + sethandler(SIGSEGV, sigsegv, 0); + + check_gs_value(0); + check_gs_value(1); + check_gs_value(0x200000000); + check_gs_value(0); + check_gs_value(0x200000000); + check_gs_value(1); + + for (int sched = 0; sched < 2; sched++) { + mov_0_gs(0, !!sched); + mov_0_gs(1, !!sched); + mov_0_gs(0x200000000, !!sched); + } + + /* Set up for multithreading. */ + + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + CPU_SET(0, &cpuset); + if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) + err(1, "sched_setaffinity to CPU 0"); /* should never fail */ + + if (pthread_create(&thread, 0, threadproc, 0) != 0) + err(1, "pthread_create"); + + static unsigned long bases_with_hard_zero[] = { + 0, HARD_ZERO, 1, 0x200000000, + }; + + for (int local = 0; local < 4; local++) { + for (int remote = 0; remote < 4; remote++) { + set_gs_and_switch_to(bases_with_hard_zero[local], + bases_with_hard_zero[remote]); + } + } + + test_unexpected_base(); + + ftx = 3; /* Kill the thread. */ + syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0); + + if (pthread_join(thread, NULL) != 0) + err(1, "pthread_join"); + + return nerrs == 0 ? 0 : 1; +} ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 5/7] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify 2016-04-08 0:31 [PATCH v3 0/7] x86: Pile o' FS/GS changes Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 1/7] selftests/x86: Test the FSBASE/GSBASE API and context switching Andy Lutomirski @ 2016-04-08 0:31 ` Andy Lutomirski 2016-04-13 11:30 ` [tip:x86/asm] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify() tip-bot for Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 7/7] x86/entry: Make gs_change a local label Andy Lutomirski ` (4 subsequent siblings) 6 siblings, 1 reply; 16+ messages in thread From: Andy Lutomirski @ 2016-04-08 0:31 UTC (permalink / raw) To: Borislav Petkov, security, x86, linux-kernel Cc: Linus Torvalds, Rudolf Marek, Andy Lutomirski It was in detect_nopl, which was either a mistake by me or some kind of mis-merge. Fixes: ff236456f072 ("x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify") Signed-off-by: Andy Lutomirski <luto@kernel.org> --- arch/x86/kernel/cpu/common.c | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index ceef584ae8b0..9ede8aa41f18 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -862,31 +862,6 @@ static void detect_nopl(struct cpuinfo_x86 *c) #else set_cpu_cap(c, X86_FEATURE_NOPL); #endif - - /* - * ESPFIX is a strange bug. All real CPUs have it. Paravirt - * systems that run Linux at CPL > 0 may or may not have the - * issue, but, even if they have the issue, there's absolutely - * nothing we can do about it because we can't use the real IRET - * instruction. - * - * NB: For the time being, only 32-bit kernels support - * X86_BUG_ESPFIX as such. 64-bit kernels directly choose - * whether to apply espfix using paravirt hooks. If any - * non-paravirt system ever shows up that does *not* have the - * ESPFIX issue, we can change this. - */ -#ifdef CONFIG_X86_32 -#ifdef CONFIG_PARAVIRT - do { - extern void native_iret(void); - if (pv_cpu_ops.iret == native_iret) - set_cpu_bug(c, X86_BUG_ESPFIX); - } while (0); -#else - set_cpu_bug(c, X86_BUG_ESPFIX); -#endif -#endif } static void detect_null_seg_behavior(struct cpuinfo_x86 *c) @@ -952,6 +927,31 @@ static void generic_identify(struct cpuinfo_x86 *c) detect_nopl(c); detect_null_seg_behavior(c); + + /* + * ESPFIX is a strange bug. All real CPUs have it. Paravirt + * systems that run Linux at CPL > 0 may or may not have the + * issue, but, even if they have the issue, there's absolutely + * nothing we can do about it because we can't use the real IRET + * instruction. + * + * NB: For the time being, only 32-bit kernels support + * X86_BUG_ESPFIX as such. 64-bit kernels directly choose + * whether to apply espfix using paravirt hooks. If any + * non-paravirt system ever shows up that does *not* have the + * ESPFIX issue, we can change this. + */ +#ifdef CONFIG_X86_32 +#ifdef CONFIG_PARAVIRT + do { + extern void native_iret(void); + if (pv_cpu_ops.iret == native_iret) + set_cpu_bug(c, X86_BUG_ESPFIX); + } while (0); +#else + set_cpu_bug(c, X86_BUG_ESPFIX); +#endif +#endif } static void x86_init_cache_qos(struct cpuinfo_x86 *c) -- 2.5.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [tip:x86/asm] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify() 2016-04-08 0:31 ` [PATCH v3 5/7] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify Andy Lutomirski @ 2016-04-13 11:30 ` tip-bot for Andy Lutomirski 0 siblings, 0 replies; 16+ messages in thread From: tip-bot for Andy Lutomirski @ 2016-04-13 11:30 UTC (permalink / raw) To: linux-tip-commits Cc: tglx, torvalds, peterz, mingo, luto, linux-kernel, r.marek, luto, brgerst, bp, dvlasenk, hpa, bp Commit-ID: 0230bb038fa99af0c425fc4cffed307e545a9642 Gitweb: http://git.kernel.org/tip/0230bb038fa99af0c425fc4cffed307e545a9642 Author: Andy Lutomirski <luto@kernel.org> AuthorDate: Thu, 7 Apr 2016 17:31:48 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Wed, 13 Apr 2016 10:20:42 +0200 x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify() It was in detect_nopl(), which was either a mistake by me or some kind of mis-merge. Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Borislav Petkov <bp@suse.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rudolf Marek <r.marek@assembler.cz> Cc: Thomas Gleixner <tglx@linutronix.de> Fixes: ff236456f072 ("x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify") Link: http://lkml.kernel.org/r/0949337f13660461edca08ab67d1a841441289c9.1460075211.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- arch/x86/kernel/cpu/common.c | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 8e40eee..28d3255 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -862,31 +862,6 @@ static void detect_nopl(struct cpuinfo_x86 *c) #else set_cpu_cap(c, X86_FEATURE_NOPL); #endif - - /* - * ESPFIX is a strange bug. All real CPUs have it. Paravirt - * systems that run Linux at CPL > 0 may or may not have the - * issue, but, even if they have the issue, there's absolutely - * nothing we can do about it because we can't use the real IRET - * instruction. - * - * NB: For the time being, only 32-bit kernels support - * X86_BUG_ESPFIX as such. 64-bit kernels directly choose - * whether to apply espfix using paravirt hooks. If any - * non-paravirt system ever shows up that does *not* have the - * ESPFIX issue, we can change this. - */ -#ifdef CONFIG_X86_32 -#ifdef CONFIG_PARAVIRT - do { - extern void native_iret(void); - if (pv_cpu_ops.iret == native_iret) - set_cpu_bug(c, X86_BUG_ESPFIX); - } while (0); -#else - set_cpu_bug(c, X86_BUG_ESPFIX); -#endif -#endif } static void detect_null_seg_behavior(struct cpuinfo_x86 *c) @@ -952,6 +927,31 @@ static void generic_identify(struct cpuinfo_x86 *c) detect_nopl(c); detect_null_seg_behavior(c); + + /* + * ESPFIX is a strange bug. All real CPUs have it. Paravirt + * systems that run Linux at CPL > 0 may or may not have the + * issue, but, even if they have the issue, there's absolutely + * nothing we can do about it because we can't use the real IRET + * instruction. + * + * NB: For the time being, only 32-bit kernels support + * X86_BUG_ESPFIX as such. 64-bit kernels directly choose + * whether to apply espfix using paravirt hooks. If any + * non-paravirt system ever shows up that does *not* have the + * ESPFIX issue, we can change this. + */ +#ifdef CONFIG_X86_32 +# ifdef CONFIG_PARAVIRT + do { + extern void native_iret(void); + if (pv_cpu_ops.iret == native_iret) + set_cpu_bug(c, X86_BUG_ESPFIX); + } while (0); +# else + set_cpu_bug(c, X86_BUG_ESPFIX); +# endif +#endif } static void x86_init_cache_qos(struct cpuinfo_x86 *c) ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v3 7/7] x86/entry: Make gs_change a local label 2016-04-08 0:31 [PATCH v3 0/7] x86: Pile o' FS/GS changes Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 1/7] selftests/x86: Test the FSBASE/GSBASE API and context switching Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 5/7] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify Andy Lutomirski @ 2016-04-08 0:31 ` Andy Lutomirski 2016-04-13 11:31 ` [tip:x86/asm] x86/entry/64: " tip-bot for Borislav Petkov 2016-04-08 10:39 ` [PATCH v3 0/7] x86: Pile o' FS/GS changes Borislav Petkov ` (3 subsequent siblings) 6 siblings, 1 reply; 16+ messages in thread From: Andy Lutomirski @ 2016-04-08 0:31 UTC (permalink / raw) To: Borislav Petkov, security, x86, linux-kernel Cc: Linus Torvalds, Rudolf Marek, Borislav Petkov, Andy Lutomirski From: Borislav Petkov <bp@suse.de> ... so that it doesn't appear in objdump output. Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Andy Lutomirski <luto@kernel.org> --- arch/x86/entry/entry_64.S | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 64d2033d1e49..1693c17dbf81 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -781,7 +781,7 @@ ENTRY(native_load_gs_index) pushfq DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI) SWAPGS -gs_change: +.Lgs_change: movl %edi, %gs 2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE SWAPGS @@ -789,7 +789,7 @@ gs_change: ret END(native_load_gs_index) - _ASM_EXTABLE(gs_change, bad_gs) + _ASM_EXTABLE(.Lgs_change, bad_gs) .section .fixup, "ax" /* running with kernelgs */ bad_gs: @@ -1019,13 +1019,13 @@ ENTRY(error_entry) movl %ecx, %eax /* zero extend */ cmpq %rax, RIP+8(%rsp) je .Lbstep_iret - cmpq $gs_change, RIP+8(%rsp) + cmpq $.Lgs_change, RIP+8(%rsp) jne .Lerror_entry_done /* - * hack: gs_change can fail with user gsbase. If this happens, fix up + * hack: .Lgs_change can fail with user gsbase. If this happens, fix up * gsbase and proceed. We'll fix up the exception and land in - * gs_change's error handler with kernel gsbase. + * .Lgs_change's error handler with kernel gsbase. */ jmp .Lerror_entry_from_usermode_swapgs -- 2.5.5 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* [tip:x86/asm] x86/entry/64: Make gs_change a local label 2016-04-08 0:31 ` [PATCH v3 7/7] x86/entry: Make gs_change a local label Andy Lutomirski @ 2016-04-13 11:31 ` tip-bot for Borislav Petkov 0 siblings, 0 replies; 16+ messages in thread From: tip-bot for Borislav Petkov @ 2016-04-13 11:31 UTC (permalink / raw) To: linux-tip-commits Cc: hpa, tglx, dvlasenk, r.marek, luto, bp, mingo, bp, brgerst, torvalds, peterz, linux-kernel, luto Commit-ID: 42c748bb2544f21c3d115240527fe4478e193641 Gitweb: http://git.kernel.org/tip/42c748bb2544f21c3d115240527fe4478e193641 Author: Borislav Petkov <bp@suse.de> AuthorDate: Thu, 7 Apr 2016 17:31:50 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Wed, 13 Apr 2016 10:20:42 +0200 x86/entry/64: Make gs_change a local label ... so that it doesn't appear in objdump output. Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Andy Lutomirski <luto@kernel.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rudolf Marek <r.marek@assembler.cz> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/b9c532a0e5f8d56dede2bd59767d40024d5a75e2.1460075211.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- arch/x86/entry/entry_64.S | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 64d2033..1693c17 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -781,7 +781,7 @@ ENTRY(native_load_gs_index) pushfq DISABLE_INTERRUPTS(CLBR_ANY & ~CLBR_RDI) SWAPGS -gs_change: +.Lgs_change: movl %edi, %gs 2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE SWAPGS @@ -789,7 +789,7 @@ gs_change: ret END(native_load_gs_index) - _ASM_EXTABLE(gs_change, bad_gs) + _ASM_EXTABLE(.Lgs_change, bad_gs) .section .fixup, "ax" /* running with kernelgs */ bad_gs: @@ -1019,13 +1019,13 @@ ENTRY(error_entry) movl %ecx, %eax /* zero extend */ cmpq %rax, RIP+8(%rsp) je .Lbstep_iret - cmpq $gs_change, RIP+8(%rsp) + cmpq $.Lgs_change, RIP+8(%rsp) jne .Lerror_entry_done /* - * hack: gs_change can fail with user gsbase. If this happens, fix up + * hack: .Lgs_change can fail with user gsbase. If this happens, fix up * gsbase and proceed. We'll fix up the exception and land in - * gs_change's error handler with kernel gsbase. + * .Lgs_change's error handler with kernel gsbase. */ jmp .Lerror_entry_from_usermode_swapgs ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v3 0/7] x86: Pile o' FS/GS changes 2016-04-08 0:31 [PATCH v3 0/7] x86: Pile o' FS/GS changes Andy Lutomirski ` (2 preceding siblings ...) 2016-04-08 0:31 ` [PATCH v3 7/7] x86/entry: Make gs_change a local label Andy Lutomirski @ 2016-04-08 10:39 ` Borislav Petkov 2016-04-08 10:40 ` Borislav Petkov ` (2 subsequent siblings) 6 siblings, 0 replies; 16+ messages in thread From: Borislav Petkov @ 2016-04-08 10:39 UTC (permalink / raw) To: Andy Lutomirski; +Cc: security, x86, linux-kernel, Linus Torvalds, Rudolf Marek On Thu, Apr 07, 2016 at 05:31:43PM -0700, Andy Lutomirski wrote: > Hi all- > > This whole mess is intended for x86/urgent. It fixes several bugs. > > It's probably a tiny performance regression on some workloads on > Intel CPUs. It's probably varies between a less tiny regression and > a small speedup on newer AMD CPUs. It's a bigger regression on AMD > K8. Shhh, otherwise the 2-3 K8 users left would crawl out of the woodwork complaining. ;-) > The AMD code could be further sped up by adding a new 'clear_gs' > pvop with a better native implementation. I don't particularly want > to deal with a backported new pvop, so I didn't do that. Maybe I'll > do it later on for new kernels, though. Yeah, before you do that, we should probably measure that first to see whether it is worth the trouble and the added pvop gunk at all. -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 0/7] x86: Pile o' FS/GS changes 2016-04-08 0:31 [PATCH v3 0/7] x86: Pile o' FS/GS changes Andy Lutomirski ` (3 preceding siblings ...) 2016-04-08 10:39 ` [PATCH v3 0/7] x86: Pile o' FS/GS changes Borislav Petkov @ 2016-04-08 10:40 ` Borislav Petkov [not found] ` <c6e7b507c72ca3bdbf6c7a8a3ceaa0334e873bd9.1460075211.git.luto@kernel.org> [not found] ` <aec6b2df1bfc56101d4e9e2e5d5d570bf41663c6.1460075211.git.luto@kernel.org> 6 siblings, 0 replies; 16+ messages in thread From: Borislav Petkov @ 2016-04-08 10:40 UTC (permalink / raw) To: Andy Lutomirski; +Cc: security, x86, linux-kernel, Linus Torvalds, Rudolf Marek On Thu, Apr 07, 2016 at 05:31:43PM -0700, Andy Lutomirski wrote: > Hi all- > > This whole mess is intended for x86/urgent. It fixes several bugs. > > It's probably a tiny performance regression on some workloads on > Intel CPUs. It's probably varies between a less tiny regression and > a small speedup on newer AMD CPUs. It's a bigger regression on AMD > K8. > > The AMD code could be further sped up by adding a new 'clear_gs' > pvop with a better native implementation. I don't particularly want > to deal with a backported new pvop, so I didn't do that. Maybe I'll > do it later on for new kernels, though. > > (For people who care about such things, there are probably three > bugs in here depending how you count. Somewhere between one and two > of them were independently discovered by Rudolf Marek.) > > Andy Lutomirski (5): > selftests/x86: Test the FSBASE/GSBASE API and context switching > x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS > x86/cpu: Probe the behavior of nulling out a segment at boot time > x86/switch_to: Rewrite the FS and GS context switch code > x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify > > Borislav Petkov (2): > x86/cpu: Add Erratum 88 detection on AMD > x86/entry: Make gs_change a local label > > arch/x86/entry/entry_64.S | 12 +- > arch/x86/include/asm/cpufeatures.h | 3 + > arch/x86/kernel/cpu/amd.c | 1 + > arch/x86/kernel/cpu/common.c | 71 ++++-- > arch/x86/kernel/process_64.c | 167 ++++++++------ > tools/testing/selftests/x86/Makefile | 1 + > tools/testing/selftests/x86/fsgsbase.c | 398 +++++++++++++++++++++++++++++++++ > 7 files changed, 560 insertions(+), 93 deletions(-) > create mode 100644 tools/testing/selftests/x86/fsgsbase.c Forgot to add: Reviewed-by: Borislav Petkov <bp@suse.de> -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. ^ permalink raw reply [flat|nested] 16+ messages in thread
[parent not found: <c6e7b507c72ca3bdbf6c7a8a3ceaa0334e873bd9.1460075211.git.luto@kernel.org>]
* Re: [PATCH v3 2/7] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS [not found] ` <c6e7b507c72ca3bdbf6c7a8a3ceaa0334e873bd9.1460075211.git.luto@kernel.org> @ 2016-04-08 7:13 ` Ingo Molnar 2016-04-08 9:39 ` Dmitry Safonov 2016-04-08 16:03 ` Andy Lutomirski 2016-04-13 11:29 ` [tip:x86/asm] " tip-bot for Andy Lutomirski 1 sibling, 2 replies; 16+ messages in thread From: Ingo Molnar @ 2016-04-08 7:13 UTC (permalink / raw) To: Andy Lutomirski Cc: Borislav Petkov, security, x86, linux-kernel, Linus Torvalds, Rudolf Marek, Denys Vlasenko, Thomas Gleixner, H. Peter Anvin * Andy Lutomirski <luto@kernel.org> wrote: > ARCH_GET_FS and ARCH_GET_GS attempted to figure out the fsbase and > gsbase respectively from saved thread state. This was wrong: fsbase > and gsbase live in registers while a thread is running, not in > memory. So I'm wondering, the current code looks totally broken,what user-space code can possibly use this? I checked glibc and Wine, and neither of them does. Wine uses ARCH_SET_GS and glibc uses ARCH_SET_FS, but that's all - neither actually tries to use the ARCH_GET_* reading APIs. So for backporting purposes I'd be much happier about simply returning -EINVAL or -ENOSYS, and we could re-introduce this code in v4.7. Thanks, Ingo ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 2/7] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS 2016-04-08 7:13 ` [PATCH v3 2/7] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS Ingo Molnar @ 2016-04-08 9:39 ` Dmitry Safonov 2016-04-08 16:03 ` Andy Lutomirski 1 sibling, 0 replies; 16+ messages in thread From: Dmitry Safonov @ 2016-04-08 9:39 UTC (permalink / raw) To: Ingo Molnar Cc: Andy Lutomirski, Borislav Petkov, security, x86, linux-kernel, Linus Torvalds, Rudolf Marek, Denys Vlasenko, Thomas Gleixner, H. Peter Anvin, gorcunov 2016-04-08 10:13 GMT+03:00 Ingo Molnar <mingo@kernel.org>: > > * Andy Lutomirski <luto@kernel.org> wrote: > >> ARCH_GET_FS and ARCH_GET_GS attempted to figure out the fsbase and >> gsbase respectively from saved thread state. This was wrong: fsbase >> and gsbase live in registers while a thread is running, not in >> memory. > > So I'm wondering, the current code looks totally broken,what user-space code can > possibly use this? I checked glibc and Wine, and neither of them does. Wine uses > ARCH_SET_GS and glibc uses ARCH_SET_FS, but that's all - neither actually tries to > use the ARCH_GET_* reading APIs. Just FYI, CRIU also does not use ARCH_GET_{FS,GS}, only ARCH_SET_{FS,GS}. It gets them with the help of PTRACE_GETREGSET. > So for backporting purposes I'd be much happier about simply returning -EINVAL or > -ENOSYS, and we could re-introduce this code in v4.7. ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 2/7] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS 2016-04-08 7:13 ` [PATCH v3 2/7] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS Ingo Molnar 2016-04-08 9:39 ` Dmitry Safonov @ 2016-04-08 16:03 ` Andy Lutomirski 1 sibling, 0 replies; 16+ messages in thread From: Andy Lutomirski @ 2016-04-08 16:03 UTC (permalink / raw) To: Ingo Molnar Cc: Andy Lutomirski, Borislav Petkov, security, X86 ML, linux-kernel, Linus Torvalds, Rudolf Marek, Denys Vlasenko, Thomas Gleixner, H. Peter Anvin On Fri, Apr 8, 2016 at 12:13 AM, Ingo Molnar <mingo@kernel.org> wrote: > > * Andy Lutomirski <luto@kernel.org> wrote: > >> ARCH_GET_FS and ARCH_GET_GS attempted to figure out the fsbase and >> gsbase respectively from saved thread state. This was wrong: fsbase >> and gsbase live in registers while a thread is running, not in >> memory. > > So I'm wondering, the current code looks totally broken,what user-space code can > possibly use this? I checked glibc and Wine, and neither of them does. Wine uses > ARCH_SET_GS and glibc uses ARCH_SET_FS, but that's all - neither actually tries to > use the ARCH_GET_* reading APIs. > > So for backporting purposes I'd be much happier about simply returning -EINVAL or > -ENOSYS, and we could re-introduce this code in v4.7. > Let's just not backport this one. There's no security issue here. If you like the rest of the series, can you remove the stable tag from this patch when you apply it? I think the old code was at least correct enough that if you did ARCH_GET_FS after ARCH_SET_FS with no funny business in between, it would work. --Andy -- Andy Lutomirski AMA Capital Management, LLC ^ permalink raw reply [flat|nested] 16+ messages in thread
* [tip:x86/asm] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS [not found] ` <c6e7b507c72ca3bdbf6c7a8a3ceaa0334e873bd9.1460075211.git.luto@kernel.org> 2016-04-08 7:13 ` [PATCH v3 2/7] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS Ingo Molnar @ 2016-04-13 11:29 ` tip-bot for Andy Lutomirski 1 sibling, 0 replies; 16+ messages in thread From: tip-bot for Andy Lutomirski @ 2016-04-13 11:29 UTC (permalink / raw) To: linux-tip-commits Cc: peterz, mingo, luto, torvalds, r.marek, dvlasenk, bp, linux-kernel, bp, brgerst, luto, tglx, hpa Commit-ID: d47b50e7a111bb7a56fb1c974728b56209d7f515 Gitweb: http://git.kernel.org/tip/d47b50e7a111bb7a56fb1c974728b56209d7f515 Author: Andy Lutomirski <luto@kernel.org> AuthorDate: Thu, 7 Apr 2016 17:31:45 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Wed, 13 Apr 2016 10:20:41 +0200 x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS ARCH_GET_FS and ARCH_GET_GS attempted to figure out the fsbase and gsbase respectively from saved thread state. This was wrong: fsbase and gsbase live in registers while a thread is running, not in memory. For reasons I can't fathom, the fsbase and gsbase code were different. Since neither was correct, I didn't try to figure out what the point of the difference was. Change it to simply read the MSRs. The code for reading the base for a remote thread is also completely wrong if the target thread uses its own descriptors (which is the case for all 32-bit threaded programs), but fixing that is a different story. Signed-off-by: Andy Lutomirski <luto@kernel.org> Reviewed-by: Borislav Petkov <bp@suse.de> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rudolf Marek <r.marek@assembler.cz> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/c6e7b507c72ca3bdbf6c7a8a3ceaa0334e873bd9.1460075211.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- arch/x86/kernel/process_64.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 6cbab31..c671b9b 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c @@ -566,10 +566,10 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) break; case ARCH_GET_FS: { unsigned long base; - if (task->thread.fsindex == FS_TLS_SEL) - base = read_32bit_tls(task, FS_TLS); - else if (doit) + if (doit) rdmsrl(MSR_FS_BASE, base); + else if (task->thread.fsindex == FS_TLS_SEL) + base = read_32bit_tls(task, FS_TLS); else base = task->thread.fs; ret = put_user(base, (unsigned long __user *)addr); @@ -577,16 +577,11 @@ long do_arch_prctl(struct task_struct *task, int code, unsigned long addr) } case ARCH_GET_GS: { unsigned long base; - unsigned gsindex; - if (task->thread.gsindex == GS_TLS_SEL) + if (doit) + rdmsrl(MSR_KERNEL_GS_BASE, base); + else if (task->thread.gsindex == GS_TLS_SEL) base = read_32bit_tls(task, GS_TLS); - else if (doit) { - savesegment(gs, gsindex); - if (gsindex) - rdmsrl(MSR_KERNEL_GS_BASE, base); - else - base = task->thread.gs; - } else + else base = task->thread.gs; ret = put_user(base, (unsigned long __user *)addr); break; ^ permalink raw reply related [flat|nested] 16+ messages in thread
[parent not found: <aec6b2df1bfc56101d4e9e2e5d5d570bf41663c6.1460075211.git.luto@kernel.org>]
* Re: [PATCH v3 6/7] x86/cpu: Add Erratum 88 detection on AMD [not found] ` <aec6b2df1bfc56101d4e9e2e5d5d570bf41663c6.1460075211.git.luto@kernel.org> @ 2016-04-08 1:40 ` Andy Lutomirski 2016-04-08 9:51 ` Borislav Petkov 2016-04-13 11:30 ` [tip:x86/asm] " tip-bot for Borislav Petkov 1 sibling, 1 reply; 16+ messages in thread From: Andy Lutomirski @ 2016-04-08 1:40 UTC (permalink / raw) To: Andy Lutomirski Cc: Borislav Petkov, security, X86 ML, linux-kernel, Linus Torvalds, Rudolf Marek, Borislav Petkov, stable, Andi Kleen On Thu, Apr 7, 2016 at 5:31 PM, Andy Lutomirski <luto@kernel.org> wrote: > From: Borislav Petkov <bp@suse.de> > > Erratum 88 affects old AMD K8s, where a SWAPGS fails to cause an input > dependency on GS. Therefore, we need to MFENCE before it. > > But that MFENCE is expensive and unnecessary on the remaining x86 CPUs > out there so patch it out on the CPUs which don't require it. This is basically identical to: https://lkml.kernel.org/g/1458576969-13309-4-git-send-email-andi@firstfloor.org Whoops! I thought I'd seen that somewhere but I couldn't spot it. Ingo, etc: we should probably apply one of those patches with a -stable tag (to mitigate the otherwise potentially unpleasant performance regression in here), but I don't really care which one. Andi's has a name for the bug that seems nicer by one character to me, but it would have to be (trivally) rebased. --Andy > > Signed-off-by: Borislav Petkov <bp@suse.de> > Cc: <stable@vger.kernel.org> > Signed-off-by: Andy Lutomirski <luto@kernel.org > --- > arch/x86/entry/entry_64.S | 2 +- > arch/x86/include/asm/cpufeatures.h | 2 ++ > arch/x86/kernel/cpu/amd.c | 1 + > 3 files changed, 4 insertions(+), 1 deletion(-) > > diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S > index 858b555e274b..64d2033d1e49 100644 > --- a/arch/x86/entry/entry_64.S > +++ b/arch/x86/entry/entry_64.S > @@ -783,7 +783,7 @@ ENTRY(native_load_gs_index) > SWAPGS > gs_change: > movl %edi, %gs > -2: mfence /* workaround */ > +2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE > SWAPGS > popfq > ret > diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h > index 2a052302bc43..7bfb6b70c745 100644 > --- a/arch/x86/include/asm/cpufeatures.h > +++ b/arch/x86/include/asm/cpufeatures.h > @@ -295,6 +295,8 @@ > #define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ > #define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ > #define X86_BUG_NULL_SEG X86_BUG(9) /* Nulling a selector preserves the base */ > +#define X86_BUG_SWAPGS_FENCE X86_BUG(10) /* SWAPGS without input dep on GS */ > + > > #ifdef CONFIG_X86_32 > /* > diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c > index 6e47e3a916f1..b7cc9efe08b5 100644 > --- a/arch/x86/kernel/cpu/amd.c > +++ b/arch/x86/kernel/cpu/amd.c > @@ -632,6 +632,7 @@ static void init_amd_k8(struct cpuinfo_x86 *c) > */ > msr_set_bit(MSR_K7_HWCR, 6); > #endif > + set_cpu_bug(c, X86_BUG_SWAPGS_FENCE); > } > > static void init_amd_gh(struct cpuinfo_x86 *c) > -- > 2.5.5 > -- Andy Lutomirski AMA Capital Management, LLC ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3 6/7] x86/cpu: Add Erratum 88 detection on AMD 2016-04-08 1:40 ` [PATCH v3 6/7] x86/cpu: Add Erratum 88 detection on AMD Andy Lutomirski @ 2016-04-08 9:51 ` Borislav Petkov 0 siblings, 0 replies; 16+ messages in thread From: Borislav Petkov @ 2016-04-08 9:51 UTC (permalink / raw) To: Andy Lutomirski Cc: Andy Lutomirski, security, X86 ML, linux-kernel, Linus Torvalds, Rudolf Marek, Borislav Petkov, stable, Andi Kleen On Thu, Apr 07, 2016 at 06:40:13PM -0700, Andy Lutomirski wrote: > Ingo, etc: we should probably apply one of those patches with a > -stable tag (to mitigate the otherwise potentially unpleasant > performance regression in here), but I don't really care which one. > Andi's has a name for the bug that seems nicer by one character to me, > but it would have to be (trivally) rebased. I don't care which one as long as the commit message says "erratum 88" somewhere. -- Regards/Gruss, Boris. ECO tip #101: Trim your mails when you reply. ^ permalink raw reply [flat|nested] 16+ messages in thread
* [tip:x86/asm] x86/cpu: Add Erratum 88 detection on AMD [not found] ` <aec6b2df1bfc56101d4e9e2e5d5d570bf41663c6.1460075211.git.luto@kernel.org> 2016-04-08 1:40 ` [PATCH v3 6/7] x86/cpu: Add Erratum 88 detection on AMD Andy Lutomirski @ 2016-04-13 11:30 ` tip-bot for Borislav Petkov 1 sibling, 0 replies; 16+ messages in thread From: tip-bot for Borislav Petkov @ 2016-04-13 11:30 UTC (permalink / raw) To: linux-tip-commits Cc: bp, peterz, brgerst, linux-kernel, mingo, tglx, bp, dvlasenk, hpa, r.marek, torvalds, luto Commit-ID: 96e5d28ae7a5250f3deb2434f1895c9daf48b1bd Gitweb: http://git.kernel.org/tip/96e5d28ae7a5250f3deb2434f1895c9daf48b1bd Author: Borislav Petkov <bp@suse.de> AuthorDate: Thu, 7 Apr 2016 17:31:49 -0700 Committer: Ingo Molnar <mingo@kernel.org> CommitDate: Wed, 13 Apr 2016 10:20:42 +0200 x86/cpu: Add Erratum 88 detection on AMD Erratum 88 affects old AMD K8s, where a SWAPGS fails to cause an input dependency on GS. Therefore, we need to MFENCE before it. But that MFENCE is expensive and unnecessary on the remaining x86 CPUs out there so patch it out on the CPUs which don't require it. Signed-off-by: Borislav Petkov <bp@suse.de> Signed-off-by: Andy Lutomirski <luto@kernel.org Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rudolf Marek <r.marek@assembler.cz> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/aec6b2df1bfc56101d4e9e2e5d5d570bf41663c6.1460075211.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> --- arch/x86/entry/entry_64.S | 2 +- arch/x86/include/asm/cpufeatures.h | 2 ++ arch/x86/kernel/cpu/amd.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 858b555..64d2033 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -783,7 +783,7 @@ ENTRY(native_load_gs_index) SWAPGS gs_change: movl %edi, %gs -2: mfence /* workaround */ +2: ALTERNATIVE "", "mfence", X86_BUG_SWAPGS_FENCE SWAPGS popfq ret diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 2a05230..7bfb6b7 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -295,6 +295,8 @@ #define X86_BUG_CLFLUSH_MONITOR X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */ #define X86_BUG_SYSRET_SS_ATTRS X86_BUG(8) /* SYSRET doesn't fix up SS attrs */ #define X86_BUG_NULL_SEG X86_BUG(9) /* Nulling a selector preserves the base */ +#define X86_BUG_SWAPGS_FENCE X86_BUG(10) /* SWAPGS without input dep on GS */ + #ifdef CONFIG_X86_32 /* diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 6e47e3a..b7cc9ef 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -632,6 +632,7 @@ static void init_amd_k8(struct cpuinfo_x86 *c) */ msr_set_bit(MSR_K7_HWCR, 6); #endif + set_cpu_bug(c, X86_BUG_SWAPGS_FENCE); } static void init_amd_gh(struct cpuinfo_x86 *c) ^ permalink raw reply related [flat|nested] 16+ messages in thread
end of thread, other threads:[~2016-04-13 11:33 UTC | newest] Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-04-08 0:31 [PATCH v3 0/7] x86: Pile o' FS/GS changes Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 1/7] selftests/x86: Test the FSBASE/GSBASE API and context switching Andy Lutomirski 2016-04-13 11:28 ` [tip:x86/asm] " tip-bot for Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 5/7] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify Andy Lutomirski 2016-04-13 11:30 ` [tip:x86/asm] x86/cpu: Move X86_BUG_ESPFIX initialization to generic_identify() tip-bot for Andy Lutomirski 2016-04-08 0:31 ` [PATCH v3 7/7] x86/entry: Make gs_change a local label Andy Lutomirski 2016-04-13 11:31 ` [tip:x86/asm] x86/entry/64: " tip-bot for Borislav Petkov 2016-04-08 10:39 ` [PATCH v3 0/7] x86: Pile o' FS/GS changes Borislav Petkov 2016-04-08 10:40 ` Borislav Petkov [not found] ` <c6e7b507c72ca3bdbf6c7a8a3ceaa0334e873bd9.1460075211.git.luto@kernel.org> 2016-04-08 7:13 ` [PATCH v3 2/7] x86/arch_prctl: Fix ARCH_GET_FS and ARCH_GET_GS Ingo Molnar 2016-04-08 9:39 ` Dmitry Safonov 2016-04-08 16:03 ` Andy Lutomirski 2016-04-13 11:29 ` [tip:x86/asm] " tip-bot for Andy Lutomirski [not found] ` <aec6b2df1bfc56101d4e9e2e5d5d570bf41663c6.1460075211.git.luto@kernel.org> 2016-04-08 1:40 ` [PATCH v3 6/7] x86/cpu: Add Erratum 88 detection on AMD Andy Lutomirski 2016-04-08 9:51 ` Borislav Petkov 2016-04-13 11:30 ` [tip:x86/asm] " tip-bot for Borislav Petkov
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.