]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jan 2018 08:54:33 +0000 (09:54 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 15 Jan 2018 08:54:33 +0000 (09:54 +0100)
added patches:
security-kconfig-correct-the-documentation-reference-for-pti.patch
selftests-x86-add-test_vsyscall.patch
x86-perf-disable-intel_bts-when-pti.patch
x86-pti-fix-pcid-and-sanitize-defines.patch
x86-retpoline-checksum32-convert-assembler-indirect-jumps.patch
x86-retpoline-crypto-convert-crypto-assembler-indirect-jumps.patch
x86-retpoline-entry-convert-entry-assembler-indirect-jumps.patch
x86-retpoline-fill-return-stack-buffer-on-vmexit.patch
x86-retpoline-ftrace-convert-ftrace-assembler-indirect-jumps.patch
x86-retpoline-hyperv-convert-assembler-indirect-jumps.patch
x86-retpoline-irq32-convert-assembler-indirect-jumps.patch
x86-retpoline-remove-compile-time-warning.patch
x86-retpoline-xen-convert-xen-hypercall-indirect-jumps.patch

14 files changed:
queue-4.14/security-kconfig-correct-the-documentation-reference-for-pti.patch [new file with mode: 0644]
queue-4.14/selftests-x86-add-test_vsyscall.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/x86-perf-disable-intel_bts-when-pti.patch [new file with mode: 0644]
queue-4.14/x86-pti-fix-pcid-and-sanitize-defines.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-checksum32-convert-assembler-indirect-jumps.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-crypto-convert-crypto-assembler-indirect-jumps.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-entry-convert-entry-assembler-indirect-jumps.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-fill-return-stack-buffer-on-vmexit.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-ftrace-convert-ftrace-assembler-indirect-jumps.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-hyperv-convert-assembler-indirect-jumps.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-irq32-convert-assembler-indirect-jumps.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-remove-compile-time-warning.patch [new file with mode: 0644]
queue-4.14/x86-retpoline-xen-convert-xen-hypercall-indirect-jumps.patch [new file with mode: 0644]

diff --git a/queue-4.14/security-kconfig-correct-the-documentation-reference-for-pti.patch b/queue-4.14/security-kconfig-correct-the-documentation-reference-for-pti.patch
new file mode 100644 (file)
index 0000000..7dbe8b2
--- /dev/null
@@ -0,0 +1,42 @@
+From a237f762681e2a394ca67f21df2feb2b76a3609b Mon Sep 17 00:00:00 2001
+From: "W. Trevor King" <wking@tremily.us>
+Date: Fri, 12 Jan 2018 15:24:59 -0800
+Subject: security/Kconfig: Correct the Documentation reference for PTI
+
+From: W. Trevor King <wking@tremily.us>
+
+commit a237f762681e2a394ca67f21df2feb2b76a3609b upstream.
+
+When the config option for PTI was added a reference to documentation was
+added as well. But the documentation did not exist at that point. The final
+documentation has a different file name.
+
+Fix it up to point to the proper file.
+
+Fixes: 385ce0ea ("x86/mm/pti: Add Kconfig")
+Signed-off-by: W. Trevor King <wking@tremily.us>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: linux-mm@kvack.org
+Cc: linux-security-module@vger.kernel.org
+Cc: James Morris <james.l.morris@oracle.com>
+Cc: "Serge E. Hallyn" <serge@hallyn.com>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/3009cc8ccbddcd897ec1e0cb6dda524929de0d14.1515799398.git.wking@tremily.us
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/Kconfig |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/Kconfig
++++ b/security/Kconfig
+@@ -63,7 +63,7 @@ config PAGE_TABLE_ISOLATION
+         ensuring that the majority of kernel addresses are not mapped
+         into userspace.
+-        See Documentation/x86/pagetable-isolation.txt for more details.
++        See Documentation/x86/pti.txt for more details.
+ config SECURITY_INFINIBAND
+       bool "Infiniband Security Hooks"
diff --git a/queue-4.14/selftests-x86-add-test_vsyscall.patch b/queue-4.14/selftests-x86-add-test_vsyscall.patch
new file mode 100644 (file)
index 0000000..680a3f8
--- /dev/null
@@ -0,0 +1,568 @@
+From 352909b49ba0d74929b96af6dfbefc854ab6ebb5 Mon Sep 17 00:00:00 2001
+From: Andy Lutomirski <luto@kernel.org>
+Date: Thu, 11 Jan 2018 17:16:51 -0800
+Subject: selftests/x86: Add test_vsyscall
+
+From: Andy Lutomirski <luto@kernel.org>
+
+commit 352909b49ba0d74929b96af6dfbefc854ab6ebb5 upstream.
+
+This tests that the vsyscall entries do what they're expected to do.
+It also confirms that attempts to read the vsyscall page behave as
+expected.
+
+If changes are made to the vsyscall code or its memory map handling,
+running this test in all three of vsyscall=none, vsyscall=emulate,
+and vsyscall=native are helpful.
+
+(Because it's easy, this also compares the vsyscall results to their
+ vDSO equivalents.)
+
+Note to KAISER backporters: please test this under all three
+vsyscall modes.  Also, in the emulate and native modes, make sure
+that test_vsyscall_64 agrees with the command line or config
+option as to which mode you're in.  It's quite easy to mess up
+the kernel such that native mode accidentally emulates
+or vice versa.
+
+Greg, etc: please backport this to all your Meltdown-patched
+kernels.  It'll help make sure the patches didn't regress
+vsyscalls.
+
+CSigned-off-by: Andy Lutomirski <luto@kernel.org>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Dave Hansen <dave.hansen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Cc: H. Peter Anvin <hpa@zytor.com>
+Cc: Hugh Dickins <hughd@google.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: Juergen Gross <jgross@suse.com>
+Cc: Kees Cook <keescook@chromium.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: stable@vger.kernel.org
+Link: http://lkml.kernel.org/r/2b9c5a174c1d60fd7774461d518aa75598b1d8fd.1515719552.git.luto@kernel.org
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/testing/selftests/x86/Makefile        |    2 
+ tools/testing/selftests/x86/test_vsyscall.c |  500 ++++++++++++++++++++++++++++
+ 2 files changed, 501 insertions(+), 1 deletion(-)
+
+--- a/tools/testing/selftests/x86/Makefile
++++ b/tools/testing/selftests/x86/Makefile
+@@ -7,7 +7,7 @@ include ../lib.mk
+ TARGETS_C_BOTHBITS := single_step_syscall sysret_ss_attrs syscall_nt ptrace_syscall test_mremap_vdso \
+                       check_initial_reg_state sigreturn ldt_gdt iopl mpx-mini-test ioperm \
+-                      protection_keys test_vdso
++                      protection_keys test_vdso test_vsyscall
+ TARGETS_C_32BIT_ONLY := entry_from_vm86 syscall_arg_fault test_syscall_vdso unwind_vdso \
+                       test_FCMOV test_FCOMI test_FISTTP \
+                       vdso_restorer
+--- /dev/null
++++ b/tools/testing/selftests/x86/test_vsyscall.c
+@@ -0,0 +1,500 @@
++/* SPDX-License-Identifier: GPL-2.0 */
++
++#define _GNU_SOURCE
++
++#include <stdio.h>
++#include <sys/time.h>
++#include <time.h>
++#include <stdlib.h>
++#include <sys/syscall.h>
++#include <unistd.h>
++#include <dlfcn.h>
++#include <string.h>
++#include <inttypes.h>
++#include <signal.h>
++#include <sys/ucontext.h>
++#include <errno.h>
++#include <err.h>
++#include <sched.h>
++#include <stdbool.h>
++#include <setjmp.h>
++
++#ifdef __x86_64__
++# define VSYS(x) (x)
++#else
++# define VSYS(x) 0
++#endif
++
++#ifndef SYS_getcpu
++# ifdef __x86_64__
++#  define SYS_getcpu 309
++# else
++#  define SYS_getcpu 318
++# endif
++#endif
++
++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");
++}
++
++/* vsyscalls and vDSO */
++bool should_read_vsyscall = false;
++
++typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
++gtod_t vgtod = (gtod_t)VSYS(0xffffffffff600000);
++gtod_t vdso_gtod;
++
++typedef int (*vgettime_t)(clockid_t, struct timespec *);
++vgettime_t vdso_gettime;
++
++typedef long (*time_func_t)(time_t *t);
++time_func_t vtime = (time_func_t)VSYS(0xffffffffff600400);
++time_func_t vdso_time;
++
++typedef long (*getcpu_t)(unsigned *, unsigned *, void *);
++getcpu_t vgetcpu = (getcpu_t)VSYS(0xffffffffff600800);
++getcpu_t vdso_getcpu;
++
++static void init_vdso(void)
++{
++      void *vdso = dlopen("linux-vdso.so.1", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
++      if (!vdso)
++              vdso = dlopen("linux-gate.so.1", RTLD_LAZY | RTLD_LOCAL | RTLD_NOLOAD);
++      if (!vdso) {
++              printf("[WARN]\tfailed to find vDSO\n");
++              return;
++      }
++
++      vdso_gtod = (gtod_t)dlsym(vdso, "__vdso_gettimeofday");
++      if (!vdso_gtod)
++              printf("[WARN]\tfailed to find gettimeofday in vDSO\n");
++
++      vdso_gettime = (vgettime_t)dlsym(vdso, "__vdso_clock_gettime");
++      if (!vdso_gettime)
++              printf("[WARN]\tfailed to find clock_gettime in vDSO\n");
++
++      vdso_time = (time_func_t)dlsym(vdso, "__vdso_time");
++      if (!vdso_time)
++              printf("[WARN]\tfailed to find time in vDSO\n");
++
++      vdso_getcpu = (getcpu_t)dlsym(vdso, "__vdso_getcpu");
++      if (!vdso_getcpu) {
++              /* getcpu() was never wired up in the 32-bit vDSO. */
++              printf("[%s]\tfailed to find getcpu in vDSO\n",
++                     sizeof(long) == 8 ? "WARN" : "NOTE");
++      }
++}
++
++static int init_vsys(void)
++{
++#ifdef __x86_64__
++      int nerrs = 0;
++      FILE *maps;
++      char line[128];
++      bool found = false;
++
++      maps = fopen("/proc/self/maps", "r");
++      if (!maps) {
++              printf("[WARN]\tCould not open /proc/self/maps -- assuming vsyscall is r-x\n");
++              should_read_vsyscall = true;
++              return 0;
++      }
++
++      while (fgets(line, sizeof(line), maps)) {
++              char r, x;
++              void *start, *end;
++              char name[128];
++              if (sscanf(line, "%p-%p %c-%cp %*x %*x:%*x %*u %s",
++                         &start, &end, &r, &x, name) != 5)
++                      continue;
++
++              if (strcmp(name, "[vsyscall]"))
++                      continue;
++
++              printf("\tvsyscall map: %s", line);
++
++              if (start != (void *)0xffffffffff600000 ||
++                  end != (void *)0xffffffffff601000) {
++                      printf("[FAIL]\taddress range is nonsense\n");
++                      nerrs++;
++              }
++
++              printf("\tvsyscall permissions are %c-%c\n", r, x);
++              should_read_vsyscall = (r == 'r');
++              if (x != 'x') {
++                      vgtod = NULL;
++                      vtime = NULL;
++                      vgetcpu = NULL;
++              }
++
++              found = true;
++              break;
++      }
++
++      fclose(maps);
++
++      if (!found) {
++              printf("\tno vsyscall map in /proc/self/maps\n");
++              should_read_vsyscall = false;
++              vgtod = NULL;
++              vtime = NULL;
++              vgetcpu = NULL;
++      }
++
++      return nerrs;
++#else
++      return 0;
++#endif
++}
++
++/* syscalls */
++static inline long sys_gtod(struct timeval *tv, struct timezone *tz)
++{
++      return syscall(SYS_gettimeofday, tv, tz);
++}
++
++static inline int sys_clock_gettime(clockid_t id, struct timespec *ts)
++{
++      return syscall(SYS_clock_gettime, id, ts);
++}
++
++static inline long sys_time(time_t *t)
++{
++      return syscall(SYS_time, t);
++}
++
++static inline long sys_getcpu(unsigned * cpu, unsigned * node,
++                            void* cache)
++{
++      return syscall(SYS_getcpu, cpu, node, cache);
++}
++
++static jmp_buf jmpbuf;
++
++static void sigsegv(int sig, siginfo_t *info, void *ctx_void)
++{
++      siglongjmp(jmpbuf, 1);
++}
++
++static double tv_diff(const struct timeval *a, const struct timeval *b)
++{
++      return (double)(a->tv_sec - b->tv_sec) +
++              (double)((int)a->tv_usec - (int)b->tv_usec) * 1e-6;
++}
++
++static int check_gtod(const struct timeval *tv_sys1,
++                    const struct timeval *tv_sys2,
++                    const struct timezone *tz_sys,
++                    const char *which,
++                    const struct timeval *tv_other,
++                    const struct timezone *tz_other)
++{
++      int nerrs = 0;
++      double d1, d2;
++
++      if (tz_other && (tz_sys->tz_minuteswest != tz_other->tz_minuteswest || tz_sys->tz_dsttime != tz_other->tz_dsttime)) {
++              printf("[FAIL] %s tz mismatch\n", which);
++              nerrs++;
++      }
++
++      d1 = tv_diff(tv_other, tv_sys1);
++      d2 = tv_diff(tv_sys2, tv_other);
++      printf("\t%s time offsets: %lf %lf\n", which, d1, d2);
++
++      if (d1 < 0 || d2 < 0) {
++              printf("[FAIL]\t%s time was inconsistent with the syscall\n", which);
++              nerrs++;
++      } else {
++              printf("[OK]\t%s gettimeofday()'s timeval was okay\n", which);
++      }
++
++      return nerrs;
++}
++
++static int test_gtod(void)
++{
++      struct timeval tv_sys1, tv_sys2, tv_vdso, tv_vsys;
++      struct timezone tz_sys, tz_vdso, tz_vsys;
++      long ret_vdso = -1;
++      long ret_vsys = -1;
++      int nerrs = 0;
++
++      printf("[RUN]\ttest gettimeofday()\n");
++
++      if (sys_gtod(&tv_sys1, &tz_sys) != 0)
++              err(1, "syscall gettimeofday");
++      if (vdso_gtod)
++              ret_vdso = vdso_gtod(&tv_vdso, &tz_vdso);
++      if (vgtod)
++              ret_vsys = vgtod(&tv_vsys, &tz_vsys);
++      if (sys_gtod(&tv_sys2, &tz_sys) != 0)
++              err(1, "syscall gettimeofday");
++
++      if (vdso_gtod) {
++              if (ret_vdso == 0) {
++                      nerrs += check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vDSO", &tv_vdso, &tz_vdso);
++              } else {
++                      printf("[FAIL]\tvDSO gettimeofday() failed: %ld\n", ret_vdso);
++                      nerrs++;
++              }
++      }
++
++      if (vgtod) {
++              if (ret_vsys == 0) {
++                      nerrs += check_gtod(&tv_sys1, &tv_sys2, &tz_sys, "vsyscall", &tv_vsys, &tz_vsys);
++              } else {
++                      printf("[FAIL]\tvsys gettimeofday() failed: %ld\n", ret_vsys);
++                      nerrs++;
++              }
++      }
++
++      return nerrs;
++}
++
++static int test_time(void) {
++      int nerrs = 0;
++
++      printf("[RUN]\ttest time()\n");
++      long t_sys1, t_sys2, t_vdso = 0, t_vsys = 0;
++      long t2_sys1 = -1, t2_sys2 = -1, t2_vdso = -1, t2_vsys = -1;
++      t_sys1 = sys_time(&t2_sys1);
++      if (vdso_time)
++              t_vdso = vdso_time(&t2_vdso);
++      if (vtime)
++              t_vsys = vtime(&t2_vsys);
++      t_sys2 = sys_time(&t2_sys2);
++      if (t_sys1 < 0 || t_sys1 != t2_sys1 || t_sys2 < 0 || t_sys2 != t2_sys2) {
++              printf("[FAIL]\tsyscall failed (ret1:%ld output1:%ld ret2:%ld output2:%ld)\n", t_sys1, t2_sys1, t_sys2, t2_sys2);
++              nerrs++;
++              return nerrs;
++      }
++
++      if (vdso_time) {
++              if (t_vdso < 0 || t_vdso != t2_vdso) {
++                      printf("[FAIL]\tvDSO failed (ret:%ld output:%ld)\n", t_vdso, t2_vdso);
++                      nerrs++;
++              } else if (t_vdso < t_sys1 || t_vdso > t_sys2) {
++                      printf("[FAIL]\tvDSO returned the wrong time (%ld %ld %ld)\n", t_sys1, t_vdso, t_sys2);
++                      nerrs++;
++              } else {
++                      printf("[OK]\tvDSO time() is okay\n");
++              }
++      }
++
++      if (vtime) {
++              if (t_vsys < 0 || t_vsys != t2_vsys) {
++                      printf("[FAIL]\tvsyscall failed (ret:%ld output:%ld)\n", t_vsys, t2_vsys);
++                      nerrs++;
++              } else if (t_vsys < t_sys1 || t_vsys > t_sys2) {
++                      printf("[FAIL]\tvsyscall returned the wrong time (%ld %ld %ld)\n", t_sys1, t_vsys, t_sys2);
++                      nerrs++;
++              } else {
++                      printf("[OK]\tvsyscall time() is okay\n");
++              }
++      }
++
++      return nerrs;
++}
++
++static int test_getcpu(int cpu)
++{
++      int nerrs = 0;
++      long ret_sys, ret_vdso = -1, ret_vsys = -1;
++
++      printf("[RUN]\tgetcpu() on CPU %d\n", cpu);
++
++      cpu_set_t cpuset;
++      CPU_ZERO(&cpuset);
++      CPU_SET(cpu, &cpuset);
++      if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
++              printf("[SKIP]\tfailed to force CPU %d\n", cpu);
++              return nerrs;
++      }
++
++      unsigned cpu_sys, cpu_vdso, cpu_vsys, node_sys, node_vdso, node_vsys;
++      unsigned node = 0;
++      bool have_node = false;
++      ret_sys = sys_getcpu(&cpu_sys, &node_sys, 0);
++      if (vdso_getcpu)
++              ret_vdso = vdso_getcpu(&cpu_vdso, &node_vdso, 0);
++      if (vgetcpu)
++              ret_vsys = vgetcpu(&cpu_vsys, &node_vsys, 0);
++
++      if (ret_sys == 0) {
++              if (cpu_sys != cpu) {
++                      printf("[FAIL]\tsyscall reported CPU %hu but should be %d\n", cpu_sys, cpu);
++                      nerrs++;
++              }
++
++              have_node = true;
++              node = node_sys;
++      }
++
++      if (vdso_getcpu) {
++              if (ret_vdso) {
++                      printf("[FAIL]\tvDSO getcpu() failed\n");
++                      nerrs++;
++              } else {
++                      if (!have_node) {
++                              have_node = true;
++                              node = node_vdso;
++                      }
++
++                      if (cpu_vdso != cpu) {
++                              printf("[FAIL]\tvDSO reported CPU %hu but should be %d\n", cpu_vdso, cpu);
++                              nerrs++;
++                      } else {
++                              printf("[OK]\tvDSO reported correct CPU\n");
++                      }
++
++                      if (node_vdso != node) {
++                              printf("[FAIL]\tvDSO reported node %hu but should be %hu\n", node_vdso, node);
++                              nerrs++;
++                      } else {
++                              printf("[OK]\tvDSO reported correct node\n");
++                      }
++              }
++      }
++
++      if (vgetcpu) {
++              if (ret_vsys) {
++                      printf("[FAIL]\tvsyscall getcpu() failed\n");
++                      nerrs++;
++              } else {
++                      if (!have_node) {
++                              have_node = true;
++                              node = node_vsys;
++                      }
++
++                      if (cpu_vsys != cpu) {
++                              printf("[FAIL]\tvsyscall reported CPU %hu but should be %d\n", cpu_vsys, cpu);
++                              nerrs++;
++                      } else {
++                              printf("[OK]\tvsyscall reported correct CPU\n");
++                      }
++
++                      if (node_vsys != node) {
++                              printf("[FAIL]\tvsyscall reported node %hu but should be %hu\n", node_vsys, node);
++                              nerrs++;
++                      } else {
++                              printf("[OK]\tvsyscall reported correct node\n");
++                      }
++              }
++      }
++
++      return nerrs;
++}
++
++static int test_vsys_r(void)
++{
++#ifdef __x86_64__
++      printf("[RUN]\tChecking read access to the vsyscall page\n");
++      bool can_read;
++      if (sigsetjmp(jmpbuf, 1) == 0) {
++              *(volatile int *)0xffffffffff600000;
++              can_read = true;
++      } else {
++              can_read = false;
++      }
++
++      if (can_read && !should_read_vsyscall) {
++              printf("[FAIL]\tWe have read access, but we shouldn't\n");
++              return 1;
++      } else if (!can_read && should_read_vsyscall) {
++              printf("[FAIL]\tWe don't have read access, but we should\n");
++              return 1;
++      } else {
++              printf("[OK]\tgot expected result\n");
++      }
++#endif
++
++      return 0;
++}
++
++
++#ifdef __x86_64__
++#define X86_EFLAGS_TF (1UL << 8)
++static volatile sig_atomic_t num_vsyscall_traps;
++
++static unsigned long get_eflags(void)
++{
++      unsigned long eflags;
++      asm volatile ("pushfq\n\tpopq %0" : "=rm" (eflags));
++      return eflags;
++}
++
++static void set_eflags(unsigned long eflags)
++{
++      asm volatile ("pushq %0\n\tpopfq" : : "rm" (eflags) : "flags");
++}
++
++static void sigtrap(int sig, siginfo_t *info, void *ctx_void)
++{
++      ucontext_t *ctx = (ucontext_t *)ctx_void;
++      unsigned long ip = ctx->uc_mcontext.gregs[REG_RIP];
++
++      if (((ip ^ 0xffffffffff600000UL) & ~0xfffUL) == 0)
++              num_vsyscall_traps++;
++}
++
++static int test_native_vsyscall(void)
++{
++      time_t tmp;
++      bool is_native;
++
++      if (!vtime)
++              return 0;
++
++      printf("[RUN]\tchecking for native vsyscall\n");
++      sethandler(SIGTRAP, sigtrap, 0);
++      set_eflags(get_eflags() | X86_EFLAGS_TF);
++      vtime(&tmp);
++      set_eflags(get_eflags() & ~X86_EFLAGS_TF);
++
++      /*
++       * If vsyscalls are emulated, we expect a single trap in the
++       * vsyscall page -- the call instruction will trap with RIP
++       * pointing to the entry point before emulation takes over.
++       * In native mode, we expect two traps, since whatever code
++       * the vsyscall page contains will be more than just a ret
++       * instruction.
++       */
++      is_native = (num_vsyscall_traps > 1);
++
++      printf("\tvsyscalls are %s (%d instructions in vsyscall page)\n",
++             (is_native ? "native" : "emulated"),
++             (int)num_vsyscall_traps);
++
++      return 0;
++}
++#endif
++
++int main(int argc, char **argv)
++{
++      int nerrs = 0;
++
++      init_vdso();
++      nerrs += init_vsys();
++
++      nerrs += test_gtod();
++      nerrs += test_time();
++      nerrs += test_getcpu(0);
++      nerrs += test_getcpu(1);
++
++      sethandler(SIGSEGV, sigsegv, 0);
++      nerrs += test_vsys_r();
++
++#ifdef __x86_64__
++      nerrs += test_native_vsyscall();
++#endif
++
++      return nerrs ? 1 : 0;
++}
index 64317ef33b59dcf5a7b9056a1157b2dd215f755f..6c2a54610309239b2eb6b189de481c71a20ebe5a 100644 (file)
@@ -103,3 +103,16 @@ objtool-detect-jumps-to-retpoline-thunks.patch
 objtool-allow-alternatives-to-be-ignored.patch
 x86-retpoline-add-initial-retpoline-support.patch
 x86-spectre-add-boot-time-option-to-select-spectre-v2-mitigation.patch
+x86-retpoline-crypto-convert-crypto-assembler-indirect-jumps.patch
+x86-retpoline-entry-convert-entry-assembler-indirect-jumps.patch
+x86-retpoline-ftrace-convert-ftrace-assembler-indirect-jumps.patch
+x86-retpoline-hyperv-convert-assembler-indirect-jumps.patch
+x86-retpoline-xen-convert-xen-hypercall-indirect-jumps.patch
+x86-retpoline-checksum32-convert-assembler-indirect-jumps.patch
+x86-retpoline-irq32-convert-assembler-indirect-jumps.patch
+x86-retpoline-fill-return-stack-buffer-on-vmexit.patch
+selftests-x86-add-test_vsyscall.patch
+x86-pti-fix-pcid-and-sanitize-defines.patch
+security-kconfig-correct-the-documentation-reference-for-pti.patch
+x86-perf-disable-intel_bts-when-pti.patch
+x86-retpoline-remove-compile-time-warning.patch
diff --git a/queue-4.14/x86-perf-disable-intel_bts-when-pti.patch b/queue-4.14/x86-perf-disable-intel_bts-when-pti.patch
new file mode 100644 (file)
index 0000000..bc8ea23
--- /dev/null
@@ -0,0 +1,69 @@
+From 99a9dc98ba52267ce5e062b52de88ea1f1b2a7d8 Mon Sep 17 00:00:00 2001
+From: Peter Zijlstra <peterz@infradead.org>
+Date: Sun, 14 Jan 2018 11:27:13 +0100
+Subject: x86,perf: Disable intel_bts when PTI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Peter Zijlstra <peterz@infradead.org>
+
+commit 99a9dc98ba52267ce5e062b52de88ea1f1b2a7d8 upstream.
+
+The intel_bts driver does not use the 'normal' BTS buffer which is exposed
+through the cpu_entry_area but instead uses the memory allocated for the
+perf AUX buffer.
+
+This obviously comes apart when using PTI because then the kernel mapping;
+which includes that AUX buffer memory; disappears. Fixing this requires to
+expose a mapping which is visible in all context and that's not trivial.
+
+As a quick fix disable this driver when PTI is enabled to prevent
+malfunction.
+
+Fixes: 385ce0ea4c07 ("x86/mm/pti: Add Kconfig")
+Reported-by: Vince Weaver <vincent.weaver@maine.edu>
+Reported-by: Robert Święcki <robert@swiecki.net>
+Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
+Cc: greg@kroah.com
+Cc: hughd@google.com
+Cc: luto@amacapital.net
+Cc: Vince Weaver <vince@deater.net>
+Cc: torvalds@linux-foundation.org
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20180114102713.GB6166@worktop.programming.kicks-ass.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/events/intel/bts.c |   18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/arch/x86/events/intel/bts.c
++++ b/arch/x86/events/intel/bts.c
+@@ -582,6 +582,24 @@ static __init int bts_init(void)
+       if (!boot_cpu_has(X86_FEATURE_DTES64) || !x86_pmu.bts)
+               return -ENODEV;
++      if (boot_cpu_has(X86_FEATURE_PTI)) {
++              /*
++               * BTS hardware writes through a virtual memory map we must
++               * either use the kernel physical map, or the user mapping of
++               * the AUX buffer.
++               *
++               * However, since this driver supports per-CPU and per-task inherit
++               * we cannot use the user mapping since it will not be availble
++               * if we're not running the owning process.
++               *
++               * With PTI we can't use the kernal map either, because its not
++               * there when we run userspace.
++               *
++               * For now, disable this driver when using PTI.
++               */
++              return -ENODEV;
++      }
++
+       bts_pmu.capabilities    = PERF_PMU_CAP_AUX_NO_SG | PERF_PMU_CAP_ITRACE |
+                                 PERF_PMU_CAP_EXCLUSIVE;
+       bts_pmu.task_ctx_nr     = perf_sw_context;
diff --git a/queue-4.14/x86-pti-fix-pcid-and-sanitize-defines.patch b/queue-4.14/x86-pti-fix-pcid-and-sanitize-defines.patch
new file mode 100644 (file)
index 0000000..9b88d42
--- /dev/null
@@ -0,0 +1,173 @@
+From f10ee3dcc9f0aba92a5c4c064628be5200765dc2 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Sun, 14 Jan 2018 00:23:57 +0100
+Subject: x86/pti: Fix !PCID and sanitize defines
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit f10ee3dcc9f0aba92a5c4c064628be5200765dc2 upstream.
+
+The switch to the user space page tables in the low level ASM code sets
+unconditionally bit 12 and bit 11 of CR3. Bit 12 is switching the base
+address of the page directory to the user part, bit 11 is switching the
+PCID to the PCID associated with the user page tables.
+
+This fails on a machine which lacks PCID support because bit 11 is set in
+CR3. Bit 11 is reserved when PCID is inactive.
+
+While the Intel SDM claims that the reserved bits are ignored when PCID is
+disabled, the AMD APM states that they should be cleared.
+
+This went unnoticed as the AMD APM was not checked when the code was
+developed and reviewed and test systems with Intel CPUs never failed to
+boot. The report is against a Centos 6 host where the guest fails to boot,
+so it's not yet clear whether this is a virt issue or can happen on real
+hardware too, but thats irrelevant as the AMD APM clearly ask for clearing
+the reserved bits.
+
+Make sure that on non PCID machines bit 11 is not set by the page table
+switching code.
+
+Andy suggested to rename the related bits and masks so they are clearly
+describing what they should be used for, which is done as well for clarity.
+
+That split could have been done with alternatives but the macro hell is
+horrible and ugly. This can be done on top if someone cares to remove the
+extra orq. For now it's a straight forward fix.
+
+Fixes: 6fd166aae78c ("x86/mm: Use/Fix PCID to optimize user/kernel switches")
+Reported-by: Laura Abbott <labbott@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: stable <stable@vger.kernel.org>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Willy Tarreau <w@1wt.eu>
+Cc: David Woodhouse <dwmw@amazon.co.uk>
+Link: https://lkml.kernel.org/r/alpine.DEB.2.20.1801140009150.2371@nanos
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/entry/calling.h               |   36 +++++++++++++++++----------------
+ arch/x86/include/asm/processor-flags.h |    2 -
+ arch/x86/include/asm/tlbflush.h        |    6 ++---
+ 3 files changed, 23 insertions(+), 21 deletions(-)
+
+--- a/arch/x86/entry/calling.h
++++ b/arch/x86/entry/calling.h
+@@ -198,8 +198,11 @@ For 32-bit we have the following convent
+  * PAGE_TABLE_ISOLATION PGDs are 8k.  Flip bit 12 to switch between the two
+  * halves:
+  */
+-#define PTI_SWITCH_PGTABLES_MASK      (1<<PAGE_SHIFT)
+-#define PTI_SWITCH_MASK               (PTI_SWITCH_PGTABLES_MASK|(1<<X86_CR3_PTI_SWITCH_BIT))
++#define PTI_USER_PGTABLE_BIT          PAGE_SHIFT
++#define PTI_USER_PGTABLE_MASK         (1 << PTI_USER_PGTABLE_BIT)
++#define PTI_USER_PCID_BIT             X86_CR3_PTI_PCID_USER_BIT
++#define PTI_USER_PCID_MASK            (1 << PTI_USER_PCID_BIT)
++#define PTI_USER_PGTABLE_AND_PCID_MASK  (PTI_USER_PCID_MASK | PTI_USER_PGTABLE_MASK)
+ .macro SET_NOFLUSH_BIT        reg:req
+       bts     $X86_CR3_PCID_NOFLUSH_BIT, \reg
+@@ -208,7 +211,7 @@ For 32-bit we have the following convent
+ .macro ADJUST_KERNEL_CR3 reg:req
+       ALTERNATIVE "", "SET_NOFLUSH_BIT \reg", X86_FEATURE_PCID
+       /* Clear PCID and "PAGE_TABLE_ISOLATION bit", point CR3 at kernel pagetables: */
+-      andq    $(~PTI_SWITCH_MASK), \reg
++      andq    $(~PTI_USER_PGTABLE_AND_PCID_MASK), \reg
+ .endm
+ .macro SWITCH_TO_KERNEL_CR3 scratch_reg:req
+@@ -239,15 +242,19 @@ For 32-bit we have the following convent
+       /* Flush needed, clear the bit */
+       btr     \scratch_reg, THIS_CPU_user_pcid_flush_mask
+       movq    \scratch_reg2, \scratch_reg
+-      jmp     .Lwrcr3_\@
++      jmp     .Lwrcr3_pcid_\@
+ .Lnoflush_\@:
+       movq    \scratch_reg2, \scratch_reg
+       SET_NOFLUSH_BIT \scratch_reg
++.Lwrcr3_pcid_\@:
++      /* Flip the ASID to the user version */
++      orq     $(PTI_USER_PCID_MASK), \scratch_reg
++
+ .Lwrcr3_\@:
+-      /* Flip the PGD and ASID to the user version */
+-      orq     $(PTI_SWITCH_MASK), \scratch_reg
++      /* Flip the PGD to the user version */
++      orq     $(PTI_USER_PGTABLE_MASK), \scratch_reg
+       mov     \scratch_reg, %cr3
+ .Lend_\@:
+ .endm
+@@ -263,17 +270,12 @@ For 32-bit we have the following convent
+       movq    %cr3, \scratch_reg
+       movq    \scratch_reg, \save_reg
+       /*
+-       * Is the "switch mask" all zero?  That means that both of
+-       * these are zero:
+-       *
+-       *      1. The user/kernel PCID bit, and
+-       *      2. The user/kernel "bit" that points CR3 to the
+-       *         bottom half of the 8k PGD
+-       *
+-       * That indicates a kernel CR3 value, not a user CR3.
++       * Test the user pagetable bit. If set, then the user page tables
++       * are active. If clear CR3 already has the kernel page table
++       * active.
+        */
+-      testq   $(PTI_SWITCH_MASK), \scratch_reg
+-      jz      .Ldone_\@
++      bt      $PTI_USER_PGTABLE_BIT, \scratch_reg
++      jnc     .Ldone_\@
+       ADJUST_KERNEL_CR3 \scratch_reg
+       movq    \scratch_reg, %cr3
+@@ -290,7 +292,7 @@ For 32-bit we have the following convent
+        * KERNEL pages can always resume with NOFLUSH as we do
+        * explicit flushes.
+        */
+-      bt      $X86_CR3_PTI_SWITCH_BIT, \save_reg
++      bt      $PTI_USER_PGTABLE_BIT, \save_reg
+       jnc     .Lnoflush_\@
+       /*
+--- a/arch/x86/include/asm/processor-flags.h
++++ b/arch/x86/include/asm/processor-flags.h
+@@ -40,7 +40,7 @@
+ #define CR3_NOFLUSH   BIT_ULL(63)
+ #ifdef CONFIG_PAGE_TABLE_ISOLATION
+-# define X86_CR3_PTI_SWITCH_BIT       11
++# define X86_CR3_PTI_PCID_USER_BIT    11
+ #endif
+ #else
+--- a/arch/x86/include/asm/tlbflush.h
++++ b/arch/x86/include/asm/tlbflush.h
+@@ -81,13 +81,13 @@ static inline u16 kern_pcid(u16 asid)
+        * Make sure that the dynamic ASID space does not confict with the
+        * bit we are using to switch between user and kernel ASIDs.
+        */
+-      BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1 << X86_CR3_PTI_SWITCH_BIT));
++      BUILD_BUG_ON(TLB_NR_DYN_ASIDS >= (1 << X86_CR3_PTI_PCID_USER_BIT));
+       /*
+        * The ASID being passed in here should have respected the
+        * MAX_ASID_AVAILABLE and thus never have the switch bit set.
+        */
+-      VM_WARN_ON_ONCE(asid & (1 << X86_CR3_PTI_SWITCH_BIT));
++      VM_WARN_ON_ONCE(asid & (1 << X86_CR3_PTI_PCID_USER_BIT));
+ #endif
+       /*
+        * The dynamically-assigned ASIDs that get passed in are small
+@@ -112,7 +112,7 @@ static inline u16 user_pcid(u16 asid)
+ {
+       u16 ret = kern_pcid(asid);
+ #ifdef CONFIG_PAGE_TABLE_ISOLATION
+-      ret |= 1 << X86_CR3_PTI_SWITCH_BIT;
++      ret |= 1 << X86_CR3_PTI_PCID_USER_BIT;
+ #endif
+       return ret;
+ }
diff --git a/queue-4.14/x86-retpoline-checksum32-convert-assembler-indirect-jumps.patch b/queue-4.14/x86-retpoline-checksum32-convert-assembler-indirect-jumps.patch
new file mode 100644 (file)
index 0000000..c40ee9e
--- /dev/null
@@ -0,0 +1,67 @@
+From 5096732f6f695001fa2d6f1335a2680b37912c69 Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw@amazon.co.uk>
+Date: Thu, 11 Jan 2018 21:46:32 +0000
+Subject: x86/retpoline/checksum32: Convert assembler indirect jumps
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+commit 5096732f6f695001fa2d6f1335a2680b37912c69 upstream.
+
+Convert all indirect jumps in 32bit checksum assembler code to use
+non-speculative sequences when CONFIG_RETPOLINE is enabled.
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515707194-20531-11-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/lib/checksum_32.S |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/lib/checksum_32.S
++++ b/arch/x86/lib/checksum_32.S
+@@ -29,7 +29,8 @@
+ #include <asm/errno.h>
+ #include <asm/asm.h>
+ #include <asm/export.h>
+-                              
++#include <asm/nospec-branch.h>
++
+ /*
+  * computes a partial checksum, e.g. for TCP/UDP fragments
+  */
+@@ -156,7 +157,7 @@ ENTRY(csum_partial)
+       negl %ebx
+       lea 45f(%ebx,%ebx,2), %ebx
+       testl %esi, %esi
+-      jmp *%ebx
++      JMP_NOSPEC %ebx
+       # Handle 2-byte-aligned regions
+ 20:   addw (%esi), %ax
+@@ -439,7 +440,7 @@ ENTRY(csum_partial_copy_generic)
+       andl $-32,%edx
+       lea 3f(%ebx,%ebx), %ebx
+       testl %esi, %esi 
+-      jmp *%ebx
++      JMP_NOSPEC %ebx
+ 1:    addl $64,%esi
+       addl $64,%edi 
+       SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
diff --git a/queue-4.14/x86-retpoline-crypto-convert-crypto-assembler-indirect-jumps.patch b/queue-4.14/x86-retpoline-crypto-convert-crypto-assembler-indirect-jumps.patch
new file mode 100644 (file)
index 0000000..159af88
--- /dev/null
@@ -0,0 +1,125 @@
+From 9697fa39efd3fc3692f2949d4045f393ec58450b Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw@amazon.co.uk>
+Date: Thu, 11 Jan 2018 21:46:27 +0000
+Subject: x86/retpoline/crypto: Convert crypto assembler indirect jumps
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+commit 9697fa39efd3fc3692f2949d4045f393ec58450b upstream.
+
+Convert all indirect jumps in crypto assembler code to use non-speculative
+sequences when CONFIG_RETPOLINE is enabled.
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515707194-20531-6-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/crypto/aesni-intel_asm.S            |    5 +++--
+ arch/x86/crypto/camellia-aesni-avx-asm_64.S  |    3 ++-
+ arch/x86/crypto/camellia-aesni-avx2-asm_64.S |    3 ++-
+ arch/x86/crypto/crc32c-pcl-intel-asm_64.S    |    3 ++-
+ 4 files changed, 9 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/crypto/aesni-intel_asm.S
++++ b/arch/x86/crypto/aesni-intel_asm.S
+@@ -32,6 +32,7 @@
+ #include <linux/linkage.h>
+ #include <asm/inst.h>
+ #include <asm/frame.h>
++#include <asm/nospec-branch.h>
+ /*
+  * The following macros are used to move an (un)aligned 16 byte value to/from
+@@ -2884,7 +2885,7 @@ ENTRY(aesni_xts_crypt8)
+       pxor INC, STATE4
+       movdqu IV, 0x30(OUTP)
+-      call *%r11
++      CALL_NOSPEC %r11
+       movdqu 0x00(OUTP), INC
+       pxor INC, STATE1
+@@ -2929,7 +2930,7 @@ ENTRY(aesni_xts_crypt8)
+       _aesni_gf128mul_x_ble()
+       movups IV, (IVP)
+-      call *%r11
++      CALL_NOSPEC %r11
+       movdqu 0x40(OUTP), INC
+       pxor INC, STATE1
+--- a/arch/x86/crypto/camellia-aesni-avx-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx-asm_64.S
+@@ -17,6 +17,7 @@
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/nospec-branch.h>
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+@@ -1227,7 +1228,7 @@ camellia_xts_crypt_16way:
+       vpxor 14 * 16(%rax), %xmm15, %xmm14;
+       vpxor 15 * 16(%rax), %xmm15, %xmm15;
+-      call *%r9;
++      CALL_NOSPEC %r9;
+       addq $(16 * 16), %rsp;
+--- a/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
++++ b/arch/x86/crypto/camellia-aesni-avx2-asm_64.S
+@@ -12,6 +12,7 @@
+ #include <linux/linkage.h>
+ #include <asm/frame.h>
++#include <asm/nospec-branch.h>
+ #define CAMELLIA_TABLE_BYTE_LEN 272
+@@ -1343,7 +1344,7 @@ camellia_xts_crypt_32way:
+       vpxor 14 * 32(%rax), %ymm15, %ymm14;
+       vpxor 15 * 32(%rax), %ymm15, %ymm15;
+-      call *%r9;
++      CALL_NOSPEC %r9;
+       addq $(16 * 32), %rsp;
+--- a/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
++++ b/arch/x86/crypto/crc32c-pcl-intel-asm_64.S
+@@ -45,6 +45,7 @@
+ #include <asm/inst.h>
+ #include <linux/linkage.h>
++#include <asm/nospec-branch.h>
+ ## ISCSI CRC 32 Implementation with crc32 and pclmulqdq Instruction
+@@ -172,7 +173,7 @@ continue_block:
+       movzxw  (bufp, %rax, 2), len
+       lea     crc_array(%rip), bufp
+       lea     (bufp, len, 1), bufp
+-      jmp     *bufp
++      JMP_NOSPEC bufp
+       ################################################################
+       ## 2a) PROCESS FULL BLOCKS:
diff --git a/queue-4.14/x86-retpoline-entry-convert-entry-assembler-indirect-jumps.patch b/queue-4.14/x86-retpoline-entry-convert-entry-assembler-indirect-jumps.patch
new file mode 100644 (file)
index 0000000..8aaf65e
--- /dev/null
@@ -0,0 +1,125 @@
+From 2641f08bb7fc63a636a2b18173221d7040a3512e Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw@amazon.co.uk>
+Date: Thu, 11 Jan 2018 21:46:28 +0000
+Subject: x86/retpoline/entry: Convert entry assembler indirect jumps
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+commit 2641f08bb7fc63a636a2b18173221d7040a3512e upstream.
+
+Convert indirect jumps in core 32/64bit entry assembler code to use
+non-speculative sequences when CONFIG_RETPOLINE is enabled.
+
+Don't use CALL_NOSPEC in entry_SYSCALL_64_fastpath because the return
+address after the 'call' instruction must be *precisely* at the
+.Lentry_SYSCALL_64_after_fastpath label for stub_ptregs_64 to work,
+and the use of alternatives will mess that up unless we play horrid
+games to prepend with NOPs and make the variants the same length. It's
+not worth it; in the case where we ALTERNATIVE out the retpoline, the
+first instruction at __x86.indirect_thunk.rax is going to be a bare
+jmp *%rax anyway.
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515707194-20531-7-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/entry/entry_32.S |    5 +++--
+ arch/x86/entry/entry_64.S |   12 +++++++++---
+ 2 files changed, 12 insertions(+), 5 deletions(-)
+
+--- a/arch/x86/entry/entry_32.S
++++ b/arch/x86/entry/entry_32.S
+@@ -44,6 +44,7 @@
+ #include <asm/asm.h>
+ #include <asm/smap.h>
+ #include <asm/frame.h>
++#include <asm/nospec-branch.h>
+       .section .entry.text, "ax"
+@@ -290,7 +291,7 @@ ENTRY(ret_from_fork)
+       /* kernel thread */
+ 1:    movl    %edi, %eax
+-      call    *%ebx
++      CALL_NOSPEC %ebx
+       /*
+        * A kernel thread is allowed to return here after successfully
+        * calling do_execve().  Exit to userspace to complete the execve()
+@@ -919,7 +920,7 @@ common_exception:
+       movl    %ecx, %es
+       TRACE_IRQS_OFF
+       movl    %esp, %eax                      # pt_regs pointer
+-      call    *%edi
++      CALL_NOSPEC %edi
+       jmp     ret_from_exception
+ END(common_exception)
+--- a/arch/x86/entry/entry_64.S
++++ b/arch/x86/entry/entry_64.S
+@@ -37,6 +37,7 @@
+ #include <asm/pgtable_types.h>
+ #include <asm/export.h>
+ #include <asm/frame.h>
++#include <asm/nospec-branch.h>
+ #include <linux/err.h>
+ #include "calling.h"
+@@ -187,7 +188,7 @@ ENTRY(entry_SYSCALL_64_trampoline)
+        */
+       pushq   %rdi
+       movq    $entry_SYSCALL_64_stage2, %rdi
+-      jmp     *%rdi
++      JMP_NOSPEC %rdi
+ END(entry_SYSCALL_64_trampoline)
+       .popsection
+@@ -266,7 +267,12 @@ entry_SYSCALL_64_fastpath:
+        * It might end up jumping to the slow path.  If it jumps, RAX
+        * and all argument registers are clobbered.
+        */
++#ifdef CONFIG_RETPOLINE
++      movq    sys_call_table(, %rax, 8), %rax
++      call    __x86_indirect_thunk_rax
++#else
+       call    *sys_call_table(, %rax, 8)
++#endif
+ .Lentry_SYSCALL_64_after_fastpath_call:
+       movq    %rax, RAX(%rsp)
+@@ -438,7 +444,7 @@ ENTRY(stub_ptregs_64)
+       jmp     entry_SYSCALL64_slow_path
+ 1:
+-      jmp     *%rax                           /* Called from C */
++      JMP_NOSPEC %rax                         /* Called from C */
+ END(stub_ptregs_64)
+ .macro ptregs_stub func
+@@ -517,7 +523,7 @@ ENTRY(ret_from_fork)
+ 1:
+       /* kernel thread */
+       movq    %r12, %rdi
+-      call    *%rbx
++      CALL_NOSPEC %rbx
+       /*
+        * A kernel thread is allowed to return here after successfully
+        * calling do_execve().  Exit to userspace to complete the execve()
diff --git a/queue-4.14/x86-retpoline-fill-return-stack-buffer-on-vmexit.patch b/queue-4.14/x86-retpoline-fill-return-stack-buffer-on-vmexit.patch
new file mode 100644 (file)
index 0000000..f77d0ed
--- /dev/null
@@ -0,0 +1,188 @@
+From 117cc7a908c83697b0b737d15ae1eb5943afe35b Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw@amazon.co.uk>
+Date: Fri, 12 Jan 2018 11:11:27 +0000
+Subject: x86/retpoline: Fill return stack buffer on vmexit
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+commit 117cc7a908c83697b0b737d15ae1eb5943afe35b upstream.
+
+In accordance with the Intel and AMD documentation, we need to overwrite
+all entries in the RSB on exiting a guest, to prevent malicious branch
+target predictions from affecting the host kernel. This is needed both
+for retpoline and for IBRS.
+
+[ak: numbers again for the RSB stuffing labels]
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Tested-by: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515755487-8524-1-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/nospec-branch.h |   78 ++++++++++++++++++++++++++++++++++-
+ arch/x86/kvm/svm.c                   |    4 +
+ arch/x86/kvm/vmx.c                   |    4 +
+ 3 files changed, 85 insertions(+), 1 deletion(-)
+
+--- a/arch/x86/include/asm/nospec-branch.h
++++ b/arch/x86/include/asm/nospec-branch.h
+@@ -7,6 +7,48 @@
+ #include <asm/alternative-asm.h>
+ #include <asm/cpufeatures.h>
++/*
++ * Fill the CPU return stack buffer.
++ *
++ * Each entry in the RSB, if used for a speculative 'ret', contains an
++ * infinite 'pause; jmp' loop to capture speculative execution.
++ *
++ * This is required in various cases for retpoline and IBRS-based
++ * mitigations for the Spectre variant 2 vulnerability. Sometimes to
++ * eliminate potentially bogus entries from the RSB, and sometimes
++ * purely to ensure that it doesn't get empty, which on some CPUs would
++ * allow predictions from other (unwanted!) sources to be used.
++ *
++ * We define a CPP macro such that it can be used from both .S files and
++ * inline assembly. It's possible to do a .macro and then include that
++ * from C via asm(".include <asm/nospec-branch.h>") but let's not go there.
++ */
++
++#define RSB_CLEAR_LOOPS               32      /* To forcibly overwrite all entries */
++#define RSB_FILL_LOOPS                16      /* To avoid underflow */
++
++/*
++ * Google experimented with loop-unrolling and this turned out to be
++ * the optimal version — two calls, each with their own speculation
++ * trap should their return address end up getting used, in a loop.
++ */
++#define __FILL_RETURN_BUFFER(reg, nr, sp)     \
++      mov     $(nr/2), reg;                   \
++771:                                          \
++      call    772f;                           \
++773:  /* speculation trap */                  \
++      pause;                                  \
++      jmp     773b;                           \
++772:                                          \
++      call    774f;                           \
++775:  /* speculation trap */                  \
++      pause;                                  \
++      jmp     775b;                           \
++774:                                          \
++      dec     reg;                            \
++      jnz     771b;                           \
++      add     $(BITS_PER_LONG/8) * nr, sp;
++
+ #ifdef __ASSEMBLY__
+ /*
+@@ -76,6 +118,20 @@
+ #endif
+ .endm
++ /*
++  * A simpler FILL_RETURN_BUFFER macro. Don't make people use the CPP
++  * monstrosity above, manually.
++  */
++.macro FILL_RETURN_BUFFER reg:req nr:req ftr:req
++#ifdef CONFIG_RETPOLINE
++      ANNOTATE_NOSPEC_ALTERNATIVE
++      ALTERNATIVE "jmp .Lskip_rsb_\@",                                \
++              __stringify(__FILL_RETURN_BUFFER(\reg,\nr,%_ASM_SP))    \
++              \ftr
++.Lskip_rsb_\@:
++#endif
++.endm
++
+ #else /* __ASSEMBLY__ */
+ #define ANNOTATE_NOSPEC_ALTERNATIVE                           \
+@@ -119,7 +175,7 @@
+       X86_FEATURE_RETPOLINE)
+ # define THUNK_TARGET(addr) [thunk_target] "rm" (addr)
+-#else /* No retpoline */
++#else /* No retpoline for C / inline asm */
+ # define CALL_NOSPEC "call *%[thunk_target]\n"
+ # define THUNK_TARGET(addr) [thunk_target] "rm" (addr)
+ #endif
+@@ -134,5 +190,25 @@ enum spectre_v2_mitigation {
+       SPECTRE_V2_IBRS,
+ };
++/*
++ * On VMEXIT we must ensure that no RSB predictions learned in the guest
++ * can be followed in the host, by overwriting the RSB completely. Both
++ * retpoline and IBRS mitigations for Spectre v2 need this; only on future
++ * CPUs with IBRS_ATT *might* it be avoided.
++ */
++static inline void vmexit_fill_RSB(void)
++{
++#ifdef CONFIG_RETPOLINE
++      unsigned long loops = RSB_CLEAR_LOOPS / 2;
++
++      asm volatile (ANNOTATE_NOSPEC_ALTERNATIVE
++                    ALTERNATIVE("jmp 910f",
++                                __stringify(__FILL_RETURN_BUFFER(%0, RSB_CLEAR_LOOPS, %1)),
++                                X86_FEATURE_RETPOLINE)
++                    "910:"
++                    : "=&r" (loops), ASM_CALL_CONSTRAINT
++                    : "r" (loops) : "memory" );
++#endif
++}
+ #endif /* __ASSEMBLY__ */
+ #endif /* __NOSPEC_BRANCH_H__ */
+--- a/arch/x86/kvm/svm.c
++++ b/arch/x86/kvm/svm.c
+@@ -45,6 +45,7 @@
+ #include <asm/debugreg.h>
+ #include <asm/kvm_para.h>
+ #include <asm/irq_remapping.h>
++#include <asm/nospec-branch.h>
+ #include <asm/virtext.h>
+ #include "trace.h"
+@@ -5013,6 +5014,9 @@ static void svm_vcpu_run(struct kvm_vcpu
+ #endif
+               );
++      /* Eliminate branch target predictions from guest mode */
++      vmexit_fill_RSB();
++
+ #ifdef CONFIG_X86_64
+       wrmsrl(MSR_GS_BASE, svm->host.gs_base);
+ #else
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -50,6 +50,7 @@
+ #include <asm/apic.h>
+ #include <asm/irq_remapping.h>
+ #include <asm/mmu_context.h>
++#include <asm/nospec-branch.h>
+ #include "trace.h"
+ #include "pmu.h"
+@@ -9483,6 +9484,9 @@ static void __noclone vmx_vcpu_run(struc
+ #endif
+             );
++      /* Eliminate branch target predictions from guest mode */
++      vmexit_fill_RSB();
++
+       /* MSR_IA32_DEBUGCTLMSR is zeroed on vmexit. Restore it if needed */
+       if (debugctlmsr)
+               update_debugctlmsr(debugctlmsr);
diff --git a/queue-4.14/x86-retpoline-ftrace-convert-ftrace-assembler-indirect-jumps.patch b/queue-4.14/x86-retpoline-ftrace-convert-ftrace-assembler-indirect-jumps.patch
new file mode 100644 (file)
index 0000000..0d50bec
--- /dev/null
@@ -0,0 +1,94 @@
+From 9351803bd803cdbeb9b5a7850b7b6f464806e3db Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw@amazon.co.uk>
+Date: Thu, 11 Jan 2018 21:46:29 +0000
+Subject: x86/retpoline/ftrace: Convert ftrace assembler indirect jumps
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+commit 9351803bd803cdbeb9b5a7850b7b6f464806e3db upstream.
+
+Convert all indirect jumps in ftrace assembler code to use non-speculative
+sequences when CONFIG_RETPOLINE is enabled.
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515707194-20531-8-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/ftrace_32.S |    6 ++++--
+ arch/x86/kernel/ftrace_64.S |    8 ++++----
+ 2 files changed, 8 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/kernel/ftrace_32.S
++++ b/arch/x86/kernel/ftrace_32.S
+@@ -8,6 +8,7 @@
+ #include <asm/segment.h>
+ #include <asm/export.h>
+ #include <asm/ftrace.h>
++#include <asm/nospec-branch.h>
+ #ifdef CC_USING_FENTRY
+ # define function_hook        __fentry__
+@@ -197,7 +198,8 @@ ftrace_stub:
+       movl    0x4(%ebp), %edx
+       subl    $MCOUNT_INSN_SIZE, %eax
+-      call    *ftrace_trace_function
++      movl    ftrace_trace_function, %ecx
++      CALL_NOSPEC %ecx
+       popl    %edx
+       popl    %ecx
+@@ -241,5 +243,5 @@ return_to_handler:
+       movl    %eax, %ecx
+       popl    %edx
+       popl    %eax
+-      jmp     *%ecx
++      JMP_NOSPEC %ecx
+ #endif
+--- a/arch/x86/kernel/ftrace_64.S
++++ b/arch/x86/kernel/ftrace_64.S
+@@ -7,7 +7,7 @@
+ #include <asm/ptrace.h>
+ #include <asm/ftrace.h>
+ #include <asm/export.h>
+-
++#include <asm/nospec-branch.h>
+       .code64
+       .section .entry.text, "ax"
+@@ -286,8 +286,8 @@ trace:
+        * ip and parent ip are used and the list function is called when
+        * function tracing is enabled.
+        */
+-      call   *ftrace_trace_function
+-
++      movq ftrace_trace_function, %r8
++      CALL_NOSPEC %r8
+       restore_mcount_regs
+       jmp fgraph_trace
+@@ -329,5 +329,5 @@ GLOBAL(return_to_handler)
+       movq 8(%rsp), %rdx
+       movq (%rsp), %rax
+       addq $24, %rsp
+-      jmp *%rdi
++      JMP_NOSPEC %rdi
+ #endif
diff --git a/queue-4.14/x86-retpoline-hyperv-convert-assembler-indirect-jumps.patch b/queue-4.14/x86-retpoline-hyperv-convert-assembler-indirect-jumps.patch
new file mode 100644 (file)
index 0000000..dea1658
--- /dev/null
@@ -0,0 +1,106 @@
+From e70e5892b28c18f517f29ab6e83bd57705104b31 Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw@amazon.co.uk>
+Date: Thu, 11 Jan 2018 21:46:30 +0000
+Subject: x86/retpoline/hyperv: Convert assembler indirect jumps
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+commit e70e5892b28c18f517f29ab6e83bd57705104b31 upstream.
+
+Convert all indirect jumps in hyperv inline asm code to use non-speculative
+sequences when CONFIG_RETPOLINE is enabled.
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515707194-20531-9-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/mshyperv.h |   18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+--- a/arch/x86/include/asm/mshyperv.h
++++ b/arch/x86/include/asm/mshyperv.h
+@@ -7,6 +7,7 @@
+ #include <linux/nmi.h>
+ #include <asm/io.h>
+ #include <asm/hyperv.h>
++#include <asm/nospec-branch.h>
+ /*
+  * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent
+@@ -186,10 +187,11 @@ static inline u64 hv_do_hypercall(u64 co
+               return U64_MAX;
+       __asm__ __volatile__("mov %4, %%r8\n"
+-                           "call *%5"
++                           CALL_NOSPEC
+                            : "=a" (hv_status), ASM_CALL_CONSTRAINT,
+                              "+c" (control), "+d" (input_address)
+-                           :  "r" (output_address), "m" (hv_hypercall_pg)
++                           :  "r" (output_address),
++                              THUNK_TARGET(hv_hypercall_pg)
+                            : "cc", "memory", "r8", "r9", "r10", "r11");
+ #else
+       u32 input_address_hi = upper_32_bits(input_address);
+@@ -200,13 +202,13 @@ static inline u64 hv_do_hypercall(u64 co
+       if (!hv_hypercall_pg)
+               return U64_MAX;
+-      __asm__ __volatile__("call *%7"
++      __asm__ __volatile__(CALL_NOSPEC
+                            : "=A" (hv_status),
+                              "+c" (input_address_lo), ASM_CALL_CONSTRAINT
+                            : "A" (control),
+                              "b" (input_address_hi),
+                              "D"(output_address_hi), "S"(output_address_lo),
+-                             "m" (hv_hypercall_pg)
++                             THUNK_TARGET(hv_hypercall_pg)
+                            : "cc", "memory");
+ #endif /* !x86_64 */
+       return hv_status;
+@@ -227,10 +229,10 @@ static inline u64 hv_do_fast_hypercall8(
+ #ifdef CONFIG_X86_64
+       {
+-              __asm__ __volatile__("call *%4"
++              __asm__ __volatile__(CALL_NOSPEC
+                                    : "=a" (hv_status), ASM_CALL_CONSTRAINT,
+                                      "+c" (control), "+d" (input1)
+-                                   : "m" (hv_hypercall_pg)
++                                   : THUNK_TARGET(hv_hypercall_pg)
+                                    : "cc", "r8", "r9", "r10", "r11");
+       }
+ #else
+@@ -238,13 +240,13 @@ static inline u64 hv_do_fast_hypercall8(
+               u32 input1_hi = upper_32_bits(input1);
+               u32 input1_lo = lower_32_bits(input1);
+-              __asm__ __volatile__ ("call *%5"
++              __asm__ __volatile__ (CALL_NOSPEC
+                                     : "=A"(hv_status),
+                                       "+c"(input1_lo),
+                                       ASM_CALL_CONSTRAINT
+                                     : "A" (control),
+                                       "b" (input1_hi),
+-                                      "m" (hv_hypercall_pg)
++                                      THUNK_TARGET(hv_hypercall_pg)
+                                     : "cc", "edi", "esi");
+       }
+ #endif
diff --git a/queue-4.14/x86-retpoline-irq32-convert-assembler-indirect-jumps.patch b/queue-4.14/x86-retpoline-irq32-convert-assembler-indirect-jumps.patch
new file mode 100644 (file)
index 0000000..6c34aed
--- /dev/null
@@ -0,0 +1,74 @@
+From 7614e913db1f40fff819b36216484dc3808995d4 Mon Sep 17 00:00:00 2001
+From: Andi Kleen <ak@linux.intel.com>
+Date: Thu, 11 Jan 2018 21:46:33 +0000
+Subject: x86/retpoline/irq32: Convert assembler indirect jumps
+
+From: Andi Kleen <ak@linux.intel.com>
+
+commit 7614e913db1f40fff819b36216484dc3808995d4 upstream.
+
+Convert all indirect jumps in 32bit irq inline asm code to use non
+speculative sequences.
+
+Signed-off-by: Andi Kleen <ak@linux.intel.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515707194-20531-12-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/irq_32.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/kernel/irq_32.c
++++ b/arch/x86/kernel/irq_32.c
+@@ -20,6 +20,7 @@
+ #include <linux/mm.h>
+ #include <asm/apic.h>
++#include <asm/nospec-branch.h>
+ #ifdef CONFIG_DEBUG_STACKOVERFLOW
+@@ -55,11 +56,11 @@ DEFINE_PER_CPU(struct irq_stack *, softi
+ static void call_on_stack(void *func, void *stack)
+ {
+       asm volatile("xchgl     %%ebx,%%esp     \n"
+-                   "call      *%%edi          \n"
++                   CALL_NOSPEC
+                    "movl      %%ebx,%%esp     \n"
+                    : "=b" (stack)
+                    : "0" (stack),
+-                     "D"(func)
++                     [thunk_target] "D"(func)
+                    : "memory", "cc", "edx", "ecx", "eax");
+ }
+@@ -95,11 +96,11 @@ static inline int execute_on_irq_stack(i
+               call_on_stack(print_stack_overflow, isp);
+       asm volatile("xchgl     %%ebx,%%esp     \n"
+-                   "call      *%%edi          \n"
++                   CALL_NOSPEC
+                    "movl      %%ebx,%%esp     \n"
+                    : "=a" (arg1), "=b" (isp)
+                    :  "0" (desc),   "1" (isp),
+-                      "D" (desc->handle_irq)
++                      [thunk_target] "D" (desc->handle_irq)
+                    : "memory", "cc", "ecx");
+       return 1;
+ }
diff --git a/queue-4.14/x86-retpoline-remove-compile-time-warning.patch b/queue-4.14/x86-retpoline-remove-compile-time-warning.patch
new file mode 100644 (file)
index 0000000..ded5948
--- /dev/null
@@ -0,0 +1,60 @@
+From b8b9ce4b5aec8de9e23cabb0a26b78641f9ab1d6 Mon Sep 17 00:00:00 2001
+From: Thomas Gleixner <tglx@linutronix.de>
+Date: Sun, 14 Jan 2018 22:13:29 +0100
+Subject: x86/retpoline: Remove compile time warning
+
+From: Thomas Gleixner <tglx@linutronix.de>
+
+commit b8b9ce4b5aec8de9e23cabb0a26b78641f9ab1d6 upstream.
+
+Remove the compile time warning when CONFIG_RETPOLINE=y and the compiler
+does not have retpoline support. Linus rationale for this is:
+
+  It's wrong because it will just make people turn off RETPOLINE, and the
+  asm updates - and return stack clearing - that are independent of the
+  compiler are likely the most important parts because they are likely the
+  ones easiest to target.
+
+  And it's annoying because most people won't be able to do anything about
+  it. The number of people building their own compiler? Very small. So if
+  their distro hasn't got a compiler yet (and pretty much nobody does), the
+  warning is just annoying crap.
+
+  It is already properly reported as part of the sysfs interface. The
+  compile-time warning only encourages bad things.
+
+Fixes: 76b043848fd2 ("x86/retpoline: Add initial retpoline support")
+Requested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: David Woodhouse <dwmw@amazon.co.uk>
+Cc: Peter Zijlstra (Intel) <peterz@infradead.org>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Link: https://lkml.kernel.org/r/CA+55aFzWgquv4i6Mab6bASqYXg3ErV3XDFEYf=GEcCDQg5uAtw@mail.gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/Makefile |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/arch/x86/Makefile
++++ b/arch/x86/Makefile
+@@ -240,8 +240,6 @@ ifdef CONFIG_RETPOLINE
+     RETPOLINE_CFLAGS += $(call cc-option,-mindirect-branch=thunk-extern -mindirect-branch-register)
+     ifneq ($(RETPOLINE_CFLAGS),)
+         KBUILD_CFLAGS += $(RETPOLINE_CFLAGS) -DRETPOLINE
+-    else
+-        $(warning CONFIG_RETPOLINE=y, but not supported by the compiler. Toolchain update recommended.)
+     endif
+ endif
diff --git a/queue-4.14/x86-retpoline-xen-convert-xen-hypercall-indirect-jumps.patch b/queue-4.14/x86-retpoline-xen-convert-xen-hypercall-indirect-jumps.patch
new file mode 100644 (file)
index 0000000..0343482
--- /dev/null
@@ -0,0 +1,60 @@
+From ea08816d5b185ab3d09e95e393f265af54560350 Mon Sep 17 00:00:00 2001
+From: David Woodhouse <dwmw@amazon.co.uk>
+Date: Thu, 11 Jan 2018 21:46:31 +0000
+Subject: x86/retpoline/xen: Convert Xen hypercall indirect jumps
+
+From: David Woodhouse <dwmw@amazon.co.uk>
+
+commit ea08816d5b185ab3d09e95e393f265af54560350 upstream.
+
+Convert indirect call in Xen hypercall to use non-speculative sequence,
+when CONFIG_RETPOLINE is enabled.
+
+Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Arjan van de Ven <arjan@linux.intel.com>
+Acked-by: Ingo Molnar <mingo@kernel.org>
+Reviewed-by: Juergen Gross <jgross@suse.com>
+Cc: gnomes@lxorguk.ukuu.org.uk
+Cc: Rik van Riel <riel@redhat.com>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: thomas.lendacky@amd.com
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Jiri Kosina <jikos@kernel.org>
+Cc: Andy Lutomirski <luto@amacapital.net>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Kees Cook <keescook@google.com>
+Cc: Tim Chen <tim.c.chen@linux.intel.com>
+Cc: Greg Kroah-Hartman <gregkh@linux-foundation.org>
+Cc: Paul Turner <pjt@google.com>
+Link: https://lkml.kernel.org/r/1515707194-20531-10-git-send-email-dwmw@amazon.co.uk
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/xen/hypercall.h |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/arch/x86/include/asm/xen/hypercall.h
++++ b/arch/x86/include/asm/xen/hypercall.h
+@@ -44,6 +44,7 @@
+ #include <asm/page.h>
+ #include <asm/pgtable.h>
+ #include <asm/smap.h>
++#include <asm/nospec-branch.h>
+ #include <xen/interface/xen.h>
+ #include <xen/interface/sched.h>
+@@ -217,9 +218,9 @@ privcmd_call(unsigned call,
+       __HYPERCALL_5ARG(a1, a2, a3, a4, a5);
+       stac();
+-      asm volatile("call *%[call]"
++      asm volatile(CALL_NOSPEC
+                    : __HYPERCALL_5PARAM
+-                   : [call] "a" (&hypercall_page[call])
++                   : [thunk_target] "a" (&hypercall_page[call])
+                    : __HYPERCALL_CLOBBER5);
+       clac();