x86/fpu/xstate: Define new macros for supervisor and user xstates
authorFenghua Yu <fenghua.yu@intel.com>
Tue, 12 May 2020 14:54:36 +0000 (07:54 -0700)
committerBorislav Petkov <bp@suse.de>
Tue, 12 May 2020 18:34:38 +0000 (20:34 +0200)
XCNTXT_MASK is 'all supported xfeatures' before introducing supervisor
xstates.  Rename it to XFEATURE_MASK_USER_SUPPORTED to make clear that
these are user xstates.

Replace XFEATURE_MASK_SUPERVISOR with the following:
- XFEATURE_MASK_SUPERVISOR_SUPPORTED: Currently nothing.  ENQCMD and
  Control-flow Enforcement Technology (CET) will be introduced in separate
  series.
- XFEATURE_MASK_SUPERVISOR_UNSUPPORTED: Currently only Processor Trace.
- XFEATURE_MASK_SUPERVISOR_ALL: the combination of above.

Co-developed-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Yu-cheng Yu <yu-cheng.yu@intel.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Tony Luck <tony.luck@intel.com>
Link: https://lkml.kernel.org/r/20200512145444.15483-3-yu-cheng.yu@intel.com
arch/x86/include/asm/fpu/xstate.h
arch/x86/kernel/fpu/init.c
arch/x86/kernel/fpu/xstate.c

index fc4db51..b08fa82 100644 (file)
 #define XSAVE_YMM_SIZE     256
 #define XSAVE_YMM_OFFSET    (XSAVE_HDR_SIZE + XSAVE_HDR_OFFSET)
 
-/* Supervisor features */
-#define XFEATURE_MASK_SUPERVISOR (XFEATURE_MASK_PT)
-
-/* All currently supported features */
-#define XCNTXT_MASK            (XFEATURE_MASK_FP | \
-                                XFEATURE_MASK_SSE | \
-                                XFEATURE_MASK_YMM | \
-                                XFEATURE_MASK_OPMASK | \
-                                XFEATURE_MASK_ZMM_Hi256 | \
-                                XFEATURE_MASK_Hi16_ZMM  | \
-                                XFEATURE_MASK_PKRU | \
-                                XFEATURE_MASK_BNDREGS | \
-                                XFEATURE_MASK_BNDCSR)
+/* All currently supported user features */
+#define XFEATURE_MASK_USER_SUPPORTED (XFEATURE_MASK_FP | \
+                                     XFEATURE_MASK_SSE | \
+                                     XFEATURE_MASK_YMM | \
+                                     XFEATURE_MASK_OPMASK | \
+                                     XFEATURE_MASK_ZMM_Hi256 | \
+                                     XFEATURE_MASK_Hi16_ZMM     | \
+                                     XFEATURE_MASK_PKRU | \
+                                     XFEATURE_MASK_BNDREGS | \
+                                     XFEATURE_MASK_BNDCSR)
+
+/* All currently supported supervisor features */
+#define XFEATURE_MASK_SUPERVISOR_SUPPORTED (0)
+
+/*
+ * Unsupported supervisor features. When a supervisor feature in this mask is
+ * supported in the future, move it to the supported supervisor feature mask.
+ */
+#define XFEATURE_MASK_SUPERVISOR_UNSUPPORTED (XFEATURE_MASK_PT)
+
+/* All supervisor states including supported and unsupported states. */
+#define XFEATURE_MASK_SUPERVISOR_ALL (XFEATURE_MASK_SUPERVISOR_SUPPORTED | \
+                                     XFEATURE_MASK_SUPERVISOR_UNSUPPORTED)
 
 #ifdef CONFIG_X86_64
 #define REX_PREFIX     "0x48, "
index 6ce7e0a..61ddc3a 100644 (file)
@@ -224,7 +224,8 @@ static void __init fpu__init_system_xstate_size_legacy(void)
  */
 u64 __init fpu__get_supported_xfeatures_mask(void)
 {
-       return XCNTXT_MASK;
+       return XFEATURE_MASK_USER_SUPPORTED |
+              XFEATURE_MASK_SUPERVISOR_SUPPORTED;
 }
 
 /* Legacy code to initialize eager fpu mode. */
index 8ed6439..9997df7 100644 (file)
@@ -208,14 +208,13 @@ void fpu__init_cpu_xstate(void)
        if (!boot_cpu_has(X86_FEATURE_XSAVE) || !xfeatures_mask)
                return;
        /*
-        * Make it clear that XSAVES supervisor states are not yet
-        * implemented should anyone expect it to work by changing
-        * bits in XFEATURE_MASK_* macros and XCR0.
+        * Unsupported supervisor xstates should not be found in
+        * the xfeatures mask.
         */
-       WARN_ONCE((xfeatures_mask & XFEATURE_MASK_SUPERVISOR),
-               "x86/fpu: XSAVES supervisor states are not yet implemented.\n");
+       WARN_ONCE((xfeatures_mask & XFEATURE_MASK_SUPERVISOR_UNSUPPORTED),
+                 "x86/fpu: Found unsupported supervisor xstates.\n");
 
-       xfeatures_mask &= ~XFEATURE_MASK_SUPERVISOR;
+       xfeatures_mask &= ~XFEATURE_MASK_SUPERVISOR_UNSUPPORTED;
 
        cr4_set_bits(X86_CR4_OSXSAVE);
        xsetbv(XCR_XFEATURE_ENABLED_MASK, xfeatures_mask);
@@ -438,7 +437,7 @@ static int xfeature_uncompacted_offset(int xfeature_nr)
         * format. Checking a supervisor state's uncompacted offset is
         * an error.
         */
-       if (XFEATURE_MASK_SUPERVISOR & BIT_ULL(xfeature_nr)) {
+       if (XFEATURE_MASK_SUPERVISOR_ALL & BIT_ULL(xfeature_nr)) {
                WARN_ONCE(1, "No fixed offset for xstate %d\n", xfeature_nr);
                return -1;
        }
@@ -475,7 +474,7 @@ int using_compacted_format(void)
 int validate_user_xstate_header(const struct xstate_header *hdr)
 {
        /* No unknown or supervisor features may be set */
-       if (hdr->xfeatures & (~xfeatures_mask | XFEATURE_MASK_SUPERVISOR))
+       if (hdr->xfeatures & ~(xfeatures_mask & XFEATURE_MASK_USER_SUPPORTED))
                return -EINVAL;
 
        /* Userspace must use the uncompacted format */
@@ -768,7 +767,8 @@ void __init fpu__init_system_xstate(void)
         * Update info used for ptrace frames; use standard-format size and no
         * supervisor xstates:
         */
-       update_regset_xstate_info(fpu_user_xstate_size, xfeatures_mask & ~XFEATURE_MASK_SUPERVISOR);
+       update_regset_xstate_info(fpu_user_xstate_size,
+                                 xfeatures_mask & XFEATURE_MASK_USER_SUPPORTED);
 
        fpu__init_prepare_fx_sw_frame();
        setup_init_fpu_buf();
@@ -996,7 +996,7 @@ int copy_xstate_to_kernel(void *kbuf, struct xregs_state *xsave, unsigned int of
         */
        memset(&header, 0, sizeof(header));
        header.xfeatures = xsave->header.xfeatures;
-       header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR;
+       header.xfeatures &= XFEATURE_MASK_USER_SUPPORTED;
 
        /*
         * Copy xregs_state->header:
@@ -1080,7 +1080,7 @@ int copy_xstate_to_user(void __user *ubuf, struct xregs_state *xsave, unsigned i
         */
        memset(&header, 0, sizeof(header));
        header.xfeatures = xsave->header.xfeatures;
-       header.xfeatures &= ~XFEATURE_MASK_SUPERVISOR;
+       header.xfeatures &= XFEATURE_MASK_USER_SUPPORTED;
 
        /*
         * Copy xregs_state->header:
@@ -1173,7 +1173,7 @@ int copy_kernel_to_xstate(struct xregs_state *xsave, const void *kbuf)
         * The state that came in from userspace was user-state only.
         * Mask all the user states out of 'xfeatures':
         */
-       xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
+       xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR_ALL;
 
        /*
         * Add back in the features that came in from userspace:
@@ -1229,7 +1229,7 @@ int copy_user_to_xstate(struct xregs_state *xsave, const void __user *ubuf)
         * The state that came in from userspace was user-state only.
         * Mask all the user states out of 'xfeatures':
         */
-       xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR;
+       xsave->header.xfeatures &= XFEATURE_MASK_SUPERVISOR_ALL;
 
        /*
         * Add back in the features that came in from userspace: