]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
x86/xen: use new hypercall functions instead of hypercall page
authorJuergen Gross <jgross@suse.com>
Thu, 17 Oct 2024 12:47:13 +0000 (14:47 +0200)
committerJuergen Gross <jgross@suse.com>
Tue, 17 Dec 2024 07:23:41 +0000 (08:23 +0100)
Call the Xen hypervisor via the new xen_hypercall_func static-call
instead of the hypercall page.

This is part of XSA-466 / CVE-2024-53241.

Reported-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Co-developed-by: Peter Zijlstra <peterz@infradead.org>
Co-developed-by: Josh Poimboeuf <jpoimboe@redhat.com>
arch/x86/include/asm/xen/hypercall.h

index 6b4dd4de08a6d4ac40cb76036f33f1d0b9179070..7d5f8ad66774102c8325db27345ecf601e781d02 100644 (file)
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/pgtable.h>
+#include <linux/instrumentation.h>
 
 #include <trace/events/xen.h>
 
+#include <asm/alternative.h>
 #include <asm/page.h>
 #include <asm/smap.h>
 #include <asm/nospec-branch.h>
@@ -91,9 +93,17 @@ extern struct { char _entry[32]; } hypercall_page[];
 void xen_hypercall_func(void);
 DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
 
-#define __HYPERCALL            "call hypercall_page+%c[offset]"
-#define __HYPERCALL_ENTRY(x)                                           \
-       [offset] "i" (__HYPERVISOR_##x * sizeof(hypercall_page[0]))
+#ifdef MODULE
+#define __ADDRESSABLE_xen_hypercall
+#else
+#define __ADDRESSABLE_xen_hypercall __ADDRESSABLE_ASM_STR(__SCK__xen_hypercall)
+#endif
+
+#define __HYPERCALL                                    \
+       __ADDRESSABLE_xen_hypercall                     \
+       "call __SCT__xen_hypercall"
+
+#define __HYPERCALL_ENTRY(x)   "a" (x)
 
 #ifdef CONFIG_X86_32
 #define __HYPERCALL_RETREG     "eax"
@@ -151,7 +161,7 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
        __HYPERCALL_0ARG();                                             \
        asm volatile (__HYPERCALL                                       \
                      : __HYPERCALL_0PARAM                              \
-                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)        \
                      : __HYPERCALL_CLOBBER0);                          \
        (type)__res;                                                    \
 })
@@ -162,7 +172,7 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
        __HYPERCALL_1ARG(a1);                                           \
        asm volatile (__HYPERCALL                                       \
                      : __HYPERCALL_1PARAM                              \
-                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)        \
                      : __HYPERCALL_CLOBBER1);                          \
        (type)__res;                                                    \
 })
@@ -173,7 +183,7 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
        __HYPERCALL_2ARG(a1, a2);                                       \
        asm volatile (__HYPERCALL                                       \
                      : __HYPERCALL_2PARAM                              \
-                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)        \
                      : __HYPERCALL_CLOBBER2);                          \
        (type)__res;                                                    \
 })
@@ -184,7 +194,7 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
        __HYPERCALL_3ARG(a1, a2, a3);                                   \
        asm volatile (__HYPERCALL                                       \
                      : __HYPERCALL_3PARAM                              \
-                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)        \
                      : __HYPERCALL_CLOBBER3);                          \
        (type)__res;                                                    \
 })
@@ -195,7 +205,7 @@ DECLARE_STATIC_CALL(xen_hypercall, xen_hypercall_func);
        __HYPERCALL_4ARG(a1, a2, a3, a4);                               \
        asm volatile (__HYPERCALL                                       \
                      : __HYPERCALL_4PARAM                              \
-                     : __HYPERCALL_ENTRY(name)                         \
+                     : __HYPERCALL_ENTRY(__HYPERVISOR_ ## name)        \
                      : __HYPERCALL_CLOBBER4);                          \
        (type)__res;                                                    \
 })
@@ -209,12 +219,9 @@ xen_single_call(unsigned int call,
        __HYPERCALL_DECLS;
        __HYPERCALL_5ARG(a1, a2, a3, a4, a5);
 
-       if (call >= PAGE_SIZE / sizeof(hypercall_page[0]))
-               return -EINVAL;
-
-       asm volatile(CALL_NOSPEC
+       asm volatile(__HYPERCALL
                     : __HYPERCALL_5PARAM
-                    : [thunk_target] "a" (&hypercall_page[call])
+                    : __HYPERCALL_ENTRY(call)
                     : __HYPERCALL_CLOBBER5);
 
        return (long)__res;