x86/fpu/xstate: Fix XSTATE_WARN_ON() to emit relevant diagnostics
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 10 Aug 2022 22:19:09 +0000 (23:19 +0100)
committerBorislav Petkov <bp@suse.de>
Wed, 9 Nov 2022 12:28:31 +0000 (13:28 +0100)
"XSAVE consistency problem" has been reported under Xen, but that's the extent
of my divination skills.

Modify XSTATE_WARN_ON() to force the caller to provide relevant diagnostic
information, and modify each caller suitably.

For check_xstate_against_struct(), this removes a double WARN() where one will
do perfectly fine.

CC stable as this has been wonky debugging for 7 years and it is good to
have there too.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Cc: <stable@vger.kernel.org>
Link: https://lore.kernel.org/r/20220810221909.12768-1-andrew.cooper3@citrix.com
arch/x86/kernel/fpu/xstate.c

index 59e543b..c2dde46 100644 (file)
@@ -440,8 +440,8 @@ static void __init __xstate_dump_leaves(void)
        }
 }
 
-#define XSTATE_WARN_ON(x) do {                                                 \
-       if (WARN_ONCE(x, "XSAVE consistency problem, dumping leaves")) {        \
+#define XSTATE_WARN_ON(x, fmt, ...) do {                                       \
+       if (WARN_ONCE(x, "XSAVE consistency problem: " fmt, ##__VA_ARGS__)) {   \
                __xstate_dump_leaves();                                         \
        }                                                                       \
 } while (0)
@@ -554,8 +554,7 @@ static bool __init check_xstate_against_struct(int nr)
            (nr >= XFEATURE_MAX) ||
            (nr == XFEATURE_PT_UNIMPLEMENTED_SO_FAR) ||
            ((nr >= XFEATURE_RSRVD_COMP_11) && (nr <= XFEATURE_RSRVD_COMP_16))) {
-               WARN_ONCE(1, "no structure for xstate: %d\n", nr);
-               XSTATE_WARN_ON(1);
+               XSTATE_WARN_ON(1, "No structure for xstate: %d\n", nr);
                return false;
        }
        return true;
@@ -598,12 +597,13 @@ static bool __init paranoid_xstate_size_valid(unsigned int kernel_size)
                 * XSAVES.
                 */
                if (!xsaves && xfeature_is_supervisor(i)) {
-                       XSTATE_WARN_ON(1);
+                       XSTATE_WARN_ON(1, "Got supervisor feature %d, but XSAVES not advertised\n", i);
                        return false;
                }
        }
        size = xstate_calculate_size(fpu_kernel_cfg.max_features, compacted);
-       XSTATE_WARN_ON(size != kernel_size);
+       XSTATE_WARN_ON(size != kernel_size,
+                      "size %u != kernel_size %u\n", size, kernel_size);
        return size == kernel_size;
 }