|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v3 10/13] xen/arm64: Implement a fast path for handling SMCCC_ARCH_WORKAROUND_2
The function ARM_SMCCC_ARCH_WORKAROUND_2 will be called by the guest for
enabling/disabling the ssbd mitigation. So we want the handling to
be as fast as possible.
The new sequence will forward guest's ARCH_WORKAROUND_2 call to EL3 and
also track the state of the workaround per-vCPU.
Note that since we need to execute branches, this always executes after
the spectre-v2 mitigation.
This code is based on KVM counterpart "arm64: KVM: Handle guest's
ARCH_WORKAROUND_2 requests" written by Marc Zyngier.
This is part of XSA-263.
Signed-off-by: Julien Grall <julien.grall@xxxxxxx>
Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx>
---
Changes in v3:
- Add Stefano's reviewed-by
Changes in v2:
- Combine the 2 consecutive eor instructions in a single one.
---
xen/arch/arm/arm64/asm-offsets.c | 2 ++
xen/arch/arm/arm64/entry.S | 42 +++++++++++++++++++++++++++++++++++++++-
xen/arch/arm/cpuerrata.c | 18 +++++++++++++++++
3 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/xen/arch/arm/arm64/asm-offsets.c b/xen/arch/arm/arm64/asm-offsets.c
index ce24e44473..f5c696d092 100644
--- a/xen/arch/arm/arm64/asm-offsets.c
+++ b/xen/arch/arm/arm64/asm-offsets.c
@@ -22,6 +22,7 @@
void __dummy__(void)
{
OFFSET(UREGS_X0, struct cpu_user_regs, x0);
+ OFFSET(UREGS_X1, struct cpu_user_regs, x1);
OFFSET(UREGS_LR, struct cpu_user_regs, lr);
OFFSET(UREGS_SP, struct cpu_user_regs, sp);
@@ -45,6 +46,7 @@ void __dummy__(void)
BLANK();
DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info));
+ OFFSET(CPUINFO_flags, struct cpu_info, flags);
OFFSET(VCPU_arch_saved_context, struct vcpu, arch.saved_context);
diff --git a/xen/arch/arm/arm64/entry.S b/xen/arch/arm/arm64/entry.S
index e2344e565f..97b05f53ea 100644
--- a/xen/arch/arm/arm64/entry.S
+++ b/xen/arch/arm/arm64/entry.S
@@ -1,4 +1,6 @@
#include <asm/asm_defns.h>
+#include <asm/current.h>
+#include <asm/macros.h>
#include <asm/regs.h>
#include <asm/alternative.h>
#include <asm/smccc.h>
@@ -241,7 +243,7 @@ guest_sync:
* be encoded as an immediate for cmp.
*/
eor w0, w0, #ARM_SMCCC_ARCH_WORKAROUND_1_FID
- cbnz w0, guest_sync_slowpath
+ cbnz w0, check_wa2
/*
* Clobber both x0 and x1 to prevent leakage. Note that thanks
@@ -250,6 +252,44 @@ guest_sync:
mov x1, xzr
eret
+check_wa2:
+ /* ARM_SMCCC_ARCH_WORKAROUND_2 handling */
+ eor w0, w0, #(ARM_SMCCC_ARCH_WORKAROUND_1_FID ^
ARM_SMCCC_ARCH_WORKAROUND_2_FID)
+ cbnz w0, guest_sync_slowpath
+#ifdef CONFIG_ARM_SSBD
+alternative_cb arm_enable_wa2_handling
+ b wa2_end
+alternative_cb_end
+ /* Sanitize the argument */
+ mov x0, #-(UREGS_kernel_sizeof - UREGS_X1) /* x0 := offset of
guest's x1 on the stack */
+ ldr x1, [sp, x0] /* Load guest's x1 */
+ cmp w1, wzr
+ cset x1, ne
+
+ /*
+ * Update the guest flag. At this stage sp point after the field
+ * guest_cpu_user_regs in cpu_info.
+ */
+ adr_cpu_info x2
+ ldr x0, [x2, #CPUINFO_flags]
+ bfi x0, x1, #CPUINFO_WORKAROUND_2_FLAG_SHIFT, #1
+ str x0, [x2, #CPUINFO_flags]
+
+ /* Check that we actually need to perform the call */
+ ldr_this_cpu x0, ssbd_callback_required, x2
+ cbz x0, wa2_end
+
+ mov w0, #ARM_SMCCC_ARCH_WORKAROUND_2_FID
+ smc #0
+
+wa2_end:
+ /* Don't leak data from the SMC call */
+ mov x1, xzr
+ mov x2, xzr
+ mov x3, xzr
+#endif /* !CONFIG_ARM_SSBD */
+ mov x0, xzr
+ eret
guest_sync_slowpath:
/*
* x0/x1 may have been scratch by the fast path above, so avoid
diff --git a/xen/arch/arm/cpuerrata.c b/xen/arch/arm/cpuerrata.c
index 4292008692..7455f09f26 100644
--- a/xen/arch/arm/cpuerrata.c
+++ b/xen/arch/arm/cpuerrata.c
@@ -7,6 +7,7 @@
#include <xen/warning.h>
#include <asm/cpufeature.h>
#include <asm/cpuerrata.h>
+#include <asm/insn.h>
#include <asm/psci.h>
/* Override macros from asm/page.h to make them work with mfn_t */
@@ -272,6 +273,23 @@ static int __init parse_spec_ctrl(const char *s)
}
custom_param("spec-ctrl", parse_spec_ctrl);
+/* Arm64 only for now as for Arm32 the workaround is currently handled in C. */
+#ifdef CONFIG_ARM_64
+void __init arm_enable_wa2_handling(const struct alt_instr *alt,
+ const uint32_t *origptr,
+ uint32_t *updptr, int nr_inst)
+{
+ BUG_ON(nr_inst != 1);
+
+ /*
+ * Only allow mitigation on guest ARCH_WORKAROUND_2 if the SSBD
+ * state allow it to be flipped.
+ */
+ if ( get_ssbd_state() == ARM_SSBD_RUNTIME )
+ *updptr = aarch64_insn_gen_nop();
+}
+#endif
+
/*
* Assembly code may use the variable directly, so we need to make sure
* it fits in a register.
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |