x86/cpu: Print VMX flags in /proc/cpuinfo using VMX_FEATURES_*
authorSean Christopherson <sean.j.christopherson@intel.com>
Sat, 21 Dec 2019 04:45:05 +0000 (20:45 -0800)
committerBorislav Petkov <bp@suse.de>
Mon, 13 Jan 2020 17:36:02 +0000 (18:36 +0100)
Add support for generating VMX feature names in capflags.c and use the
resulting x86_vmx_flags to print the VMX flags in /proc/cpuinfo.  Don't
print VMX flags if no bits are set in word 0, which holds Pin Controls.
Pin Control's INTR and NMI exiting are fundamental pillars of VMX, if
they are not supported then the CPU is broken, it does not actually
support VMX, or the kernel wasn't built with support for the target CPU.

Print the features in a dedicated "vmx flags" line to avoid polluting
the common "flags" and to avoid having to prefix all flags with "vmx_",
which results in horrendously long names.

Keep synthetic VMX flags in cpufeatures to preserve /proc/cpuinfo's ABI
for those flags.  This means that "flags" and "vmx flags" will have
duplicate entries for tpr_shadow (virtual_tpr), vnmi, ept, flexpriority,
vpid and ept_ad, but caps the pollution of "flags" at those six VMX
features.  The vendor-specific code that populates the synthetic flags
will be consolidated in a future patch to further minimize the lasting
damage.

Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Link: https://lkml.kernel.org/r/20191221044513.21680-12-sean.j.christopherson@intel.com
arch/x86/boot/mkcpustr.c
arch/x86/kernel/cpu/Makefile
arch/x86/kernel/cpu/mkcapflags.sh
arch/x86/kernel/cpu/proc.c

index 9caa10e822172d0c091460af8dcf25d37cf2032e..da0ccc5de538064f5a3bf767d9dd8918e6562f38 100644 (file)
@@ -15,6 +15,7 @@
 #include "../include/asm/required-features.h"
 #include "../include/asm/disabled-features.h"
 #include "../include/asm/cpufeatures.h"
+#include "../include/asm/vmxfeatures.h"
 #include "../kernel/cpu/capflags.c"
 
 int main(void)
index 57652c603929223c47f2df772d6b7991725303fb..7dc4ad68eb411ef480ab2436b232ef0a6770cf55 100644 (file)
@@ -54,11 +54,12 @@ obj-$(CONFIG_ACRN_GUEST)            += acrn.o
 
 ifdef CONFIG_X86_FEATURE_NAMES
 quiet_cmd_mkcapflags = MKCAP   $@
-      cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $< $@
+      cmd_mkcapflags = $(CONFIG_SHELL) $(srctree)/$(src)/mkcapflags.sh $@ $^
 
 cpufeature = $(src)/../../include/asm/cpufeatures.h
+vmxfeature = $(src)/../../include/asm/vmxfeatures.h
 
-$(obj)/capflags.c: $(cpufeature) $(src)/mkcapflags.sh FORCE
+$(obj)/capflags.c: $(cpufeature) $(vmxfeature) $(src)/mkcapflags.sh FORCE
        $(call if_changed,mkcapflags)
 endif
 targets += capflags.c
index aed45b8895d5b5f5c293ae4f6a47499e580f5825..1db560ed2ca35a0d3572f01c25ea4f9f96d015fd 100644 (file)
@@ -6,8 +6,7 @@
 
 set -e
 
-IN=$1
-OUT=$2
+OUT=$1
 
 dump_array()
 {
@@ -15,6 +14,7 @@ dump_array()
        SIZE=$2
        PFX=$3
        POSTFIX=$4
+       IN=$5
 
        PFX_SZ=$(echo $PFX | wc -c)
        TABS="$(printf '\t\t\t\t\t')"
@@ -57,11 +57,18 @@ trap 'rm "$OUT"' EXIT
        echo "#endif"
        echo ""
 
-       dump_array "x86_cap_flags" "NCAPINTS*32" "X86_FEATURE_" ""
+       dump_array "x86_cap_flags" "NCAPINTS*32" "X86_FEATURE_" "" $2
        echo ""
 
-       dump_array "x86_bug_flags" "NBUGINTS*32" "X86_BUG_" "NCAPINTS*32"
+       dump_array "x86_bug_flags" "NBUGINTS*32" "X86_BUG_" "NCAPINTS*32" $2
+       echo ""
 
+       echo "#ifdef CONFIG_X86_VMX_FEATURE_NAMES"
+       echo "#ifndef _ASM_X86_VMXFEATURES_H"
+       echo "#include <asm/vmxfeatures.h>"
+       echo "#endif"
+       dump_array "x86_vmx_flags" "NVMXINTS*32" "VMX_FEATURE_" "" $3
+       echo "#endif /* CONFIG_X86_VMX_FEATURE_NAMES */"
 ) > $OUT
 
 trap - EXIT
index cb2e49810d687fe67ae304edcb480469b95480b7..4eec8889b0ff1de48787fd162985bf930b89fd11 100644 (file)
@@ -7,6 +7,10 @@
 
 #include "cpu.h"
 
+#ifdef CONFIG_X86_VMX_FEATURE_NAMES
+extern const char * const x86_vmx_flags[NVMXINTS*32];
+#endif
+
 /*
  *     Get CPU information for use by the procfs.
  */
@@ -102,6 +106,17 @@ static int show_cpuinfo(struct seq_file *m, void *v)
                if (cpu_has(c, i) && x86_cap_flags[i] != NULL)
                        seq_printf(m, " %s", x86_cap_flags[i]);
 
+#ifdef CONFIG_X86_VMX_FEATURE_NAMES
+       if (cpu_has(c, X86_FEATURE_VMX) && c->vmx_capability[0]) {
+               seq_puts(m, "\nvmx flags\t:");
+               for (i = 0; i < 32*NVMXINTS; i++) {
+                       if (test_bit(i, (unsigned long *)c->vmx_capability) &&
+                           x86_vmx_flags[i] != NULL)
+                               seq_printf(m, " %s", x86_vmx_flags[i]);
+               }
+       }
+#endif
+
        seq_puts(m, "\nbugs\t\t:");
        for (i = 0; i < 32*NBUGINTS; i++) {
                unsigned int bug_bit = 32*NCAPINTS + i;