FRED and IDT differ by a Supervisor Token on the base of the shstk.  This
means that switch_stack_and_jump() needs to discard one extra word when FRED
is active.

Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com>
---
CC: Jan Beulich <jbeul...@suse.com>
CC: Roger Pau Monné <roger....@citrix.com>

RFC.  I don't like this, but it does work.

This emits opt_fred logic outside of CONFIG_XEN_SHSTK.  But frankly, the
construct is already too unweildly, and all options I can think of make it
moreso.
---
 xen/arch/x86/include/asm/current.h | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/include/asm/current.h 
b/xen/arch/x86/include/asm/current.h
index 962eb76a82b3..24d7d906a8c6 100644
--- a/xen/arch/x86/include/asm/current.h
+++ b/xen/arch/x86/include/asm/current.h
@@ -11,6 +11,7 @@
 #include <xen/page-size.h>
 
 #include <asm/cpu-user-regs.h>
+#include <asm/traps.h>
 
 /*
  * Xen's cpu stacks are 8 pages (8-page aligned), arranged as:
@@ -154,7 +155,6 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
     "rdsspd %[ssp];"                                            \
     "cmp $1, %[ssp];"                                           \
     "je .L_shstk_done.%=;" /* CET not active?  Skip. */         \
-    "mov $%c[skstk_base], %[val];"                              \
     "and $%c[stack_mask], %[ssp];"                              \
     "sub %[ssp], %[val];"                                       \
     "shr $3, %[val];"                                           \
@@ -177,6 +177,8 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
 
 #define switch_stack_and_jump(fn, instr, constr)                        \
     ({                                                                  \
+        unsigned int token_offset =                                     \
+            (PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - (opt_fred ? 0 : 8);  \
         unsigned int tmp;                                               \
         BUILD_BUG_ON(!ssaj_has_attr_noreturn(fn));                      \
         __asm__ __volatile__ (                                          \
@@ -184,12 +186,11 @@ unsigned long get_stack_dump_bottom (unsigned long sp);
             "mov %[stk], %%rsp;"                                        \
             CHECK_FOR_LIVEPATCH_WORK                                    \
             instr "[fun]"                                               \
-            : [val] "=&r" (tmp),                                        \
+            : [val] "=r" (tmp),                                         \
               [ssp] "=&r" (tmp)                                         \
             : [stk] "r" (guest_cpu_user_regs()),                        \
               [fun] constr (fn),                                        \
-              [skstk_base] "i"                                          \
-              ((PRIMARY_SHSTK_SLOT + 1) * PAGE_SIZE - 8),               \
+              "[val]" (token_offset),                                   \
               [stack_mask] "i" (STACK_SIZE - 1),                        \
               _ASM_BUGFRAME_INFO(BUGFRAME_bug, __LINE__,                \
                                  __FILE__, NULL)                        \
-- 
2.39.5


Reply via email to