[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v1 1/3] xen/riscv: fix switch_stack_and_jump()



The following compilation issue occurs when UBSAN related stuff is enabled:
prelink.o: in function `smp_processor_id':
  /build/xen/./arch/riscv/include/asm/current.h:46:(.init.text+0x274e2):
  relocation truncated to fit: R_RISCV_JAL against `init_done'
make[2]: *** [arch/riscv/Makefile:45: xen-syms] Error 1

The switch_stack_and_jump macro uses "j " #fn which assembles to
JAL x0, init_done is a RISC-V J-type instruction with only ±1MB range.

Without UBSAN, .init.text is small enough that init_done (which lives in
.text, not .init.text) is within 1MB of the JAL. With UBSAN enabled, all
the instrumentation calls bloat .init.text well past 1MB, so init_done
is now >1MB away from the JAL. The linker tries to truncate the 20-bit
J-type offset and fails.

The linker confusingly attributes the error to smp_processor_id:46
because the compiler inlines that function into the same init function
that ends with switch_stack_and_jump, and the debug info places the
JAL within that inlined scope.

Note that the `tail` instruction looks more natural here, but the `jr`
instruction is chosen instead to avoid depending on how the assembler
expands the `tail` instruction and which register it uses as a scratch
area (`t1` in the case of GAS), which would then need to be listed in
the clobber section of `asm volatile`.

Fixes: e66003e7be199 ("xen/riscv: introduce setup_initial_pages")
Signed-off-by: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
Reviewed-by: Baptiste Le Duc <baptiste.le-duc@xxxxxxxxxx>
---
 xen/arch/riscv/include/asm/current.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/xen/arch/riscv/include/asm/current.h 
b/xen/arch/riscv/include/asm/current.h
index 5fbee8182caa..cc004670d18c 100644
--- a/xen/arch/riscv/include/asm/current.h
+++ b/xen/arch/riscv/include/asm/current.h
@@ -51,11 +51,11 @@ DECLARE_PER_CPU(struct vcpu *, curr_vcpu);
 #define vcpu_guest_cpu_user_regs(vcpu) \
     (&(vcpu)->arch.cpu_info->guest_cpu_user_regs)
 
-#define switch_stack_and_jump(stack, fn) do {               \
-    asm volatile (                                          \
-            "mv sp, %0\n"                                   \
-            "j " #fn :: "r" (stack), "X" (fn) : "memory" ); \
-    unreachable();                                          \
+#define switch_stack_and_jump(stack, fn) do {                    \
+    asm volatile (                                               \
+            "mv sp, %0\n"                                        \
+            "jr %1" :: "r" (stack), "r" (fn) : "memory" );       \
+    unreachable();                                               \
 } while ( false )
 
 #define get_per_cpu_offset() __per_cpu_offset[smp_processor_id()]
-- 
2.54.0




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.