]> www.infradead.org Git - linux-platform-drivers-x86.git/commitdiff
proc: provide details on indirect branch speculation
authorAnand K Mistry <amistry@google.com>
Wed, 16 Dec 2020 04:42:36 +0000 (20:42 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 16 Dec 2020 06:46:15 +0000 (22:46 -0800)
Similar to speculation store bypass, show information about the indirect
branch speculation mode of a task in /proc/$pid/status.

For testing/benchmarking, I needed to see whether IB (Indirect Branch)
speculation (see Spectre-v2) is enabled on a task, to see whether an
IBPB instruction should be executed on an address space switch.
Unfortunately, this information isn't available anywhere else and
currently the only way to get it is to hack the kernel to expose it
(like this change).  It also helped expose a bug with conditional IB
speculation on certain CPUs.

Another place this could be useful is to audit the system when using
sanboxing.  With this change, I can confirm that seccomp-enabled
process have IB speculation force disabled as expected when the kernel
command line parameter `spectre_v2_user=seccomp`.

Since there's already a 'Speculation_Store_Bypass' field, I used that
as precedent for adding this one.

[amistry@google.com: remove underscores from field name to workaround documentation issue]
Link: https://lkml.kernel.org/r/20201106131015.v2.1.I7782b0cedb705384a634cfd8898eb7523562da99@changeid
Link: https://lkml.kernel.org/r/20201030172731.1.I7782b0cedb705384a634cfd8898eb7523562da99@changeid
Signed-off-by: Anand K Mistry <amistry@google.com>
Cc: Anthony Steinhauser <asteinhauser@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Anand K Mistry <amistry@google.com>
Cc: Alexey Dobriyan <adobriyan@gmail.com>
Cc: Alexey Gladkov <gladkov.alexey@gmail.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Kees Cook <keescook@chromium.org>
Cc: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: NeilBrown <neilb@suse.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Documentation/filesystems/proc.rst
fs/proc/array.c

index e5fa972d4c7631171a3df2322f552ab964d74361..2fa69f710e2a2dd93e3241258ca8dd2fc8afd45b 100644 (file)
@@ -210,6 +210,7 @@ read the file /proc/PID/status::
   NoNewPrivs:     0
   Seccomp:        0
   Speculation_Store_Bypass:       thread vulnerable
+  SpeculationIndirectBranch:      conditional enabled
   voluntary_ctxt_switches:        0
   nonvoluntary_ctxt_switches:     1
 
@@ -292,6 +293,7 @@ It's slow but very precise.
  NoNewPrivs                  no_new_privs, like prctl(PR_GET_NO_NEW_PRIV, ...)
  Seccomp                     seccomp mode, like prctl(PR_GET_SECCOMP, ...)
  Speculation_Store_Bypass    speculative store bypass mitigation status
+ SpeculationIndirectBranch   indirect branch speculation mode
  Cpus_allowed                mask of CPUs on which this process may run
  Cpus_allowed_list           Same as previous, but in "list format"
  Mems_allowed                mask of memory nodes allowed to this process
index a23c3e220a5ffbdd317281800919f04681c01505..bb87e4d89cd8fc4e95c6bc277933ea2edddd3cf1 100644 (file)
@@ -369,6 +369,34 @@ static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
                seq_puts(m, "vulnerable");
                break;
        }
+
+       seq_puts(m, "\nSpeculationIndirectBranch:\t");
+       switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_INDIRECT_BRANCH)) {
+       case -EINVAL:
+               seq_puts(m, "unsupported");
+               break;
+       case PR_SPEC_NOT_AFFECTED:
+               seq_puts(m, "not affected");
+               break;
+       case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
+               seq_puts(m, "conditional force disabled");
+               break;
+       case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
+               seq_puts(m, "conditional disabled");
+               break;
+       case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
+               seq_puts(m, "conditional enabled");
+               break;
+       case PR_SPEC_ENABLE:
+               seq_puts(m, "always enabled");
+               break;
+       case PR_SPEC_DISABLE:
+               seq_puts(m, "always disabled");
+               break;
+       default:
+               seq_puts(m, "unknown");
+               break;
+       }
        seq_putc(m, '\n');
 }