xen/arm64: Implement a fast path for handling SMCCC_ARCH_WORKAROUND_1

The function SMCCC_ARCH_WORKAROUND_1 will be called by the guest for
hardening the branch predictor. So we want the handling to be as fast as
possible.

As the mitigation is applied on every guest exit, we can check for the
call before saving all the context and return very early.

For now, only provide a fast path for HVC64 call. Because the code rely
on 2 registers, x0 and x1 are saved in advance.

Signed-off-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Volodymyr Babchuk <volodymyr.babchuk@epam.com>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Andre Przywara <andre.przywara@arm.com>
This commit is contained in:
Julien Grall authored and Stefano Stabellini committed 2018-02-26 14:59:09 -08:00
1 parent 2bd4f05113
commit ce73d72e97
2 files changed
+59 -2

No files matched your search

+57 -2
View File
@@ -1,6 +1,7 @@
#include <asm/asm_defns.h>
#include <asm/regs.h>
#include <asm/alternative.h>
#include <asm/smccc.h>
#include <public/xen.h>
/*
@@ -90,8 +91,12 @@ lr .req x30 /* link register */
.endm
/*
* Save state on entry to hypervisor, restore on exit
*
* save_x0_x1: Does the macro needs to save x0/x1? Defaults to 1
* If 0, we rely on the on x0/x1 to have been saved at the correct
* position on the stack before.
*/
.macro entry, hyp, compat
.macro entry, hyp, compat, save_x0_x1=1
sub sp, sp, #(UREGS_SPSR_el1 - UREGS_LR) /* CPSR, PC, SP, LR */
push x28, x29
push x26, x27
@@ -107,7 +112,16 @@ lr .req x30 /* link register */
push x6, x7
push x4, x5
push x2, x3
/*
* The caller may already have saved x0/x1 on the stack at the
* correct address and corrupt them with another value. Only
* save them if save_x0_x1 == 1.
*/
.if \save_x0_x1 == 1
push x0, x1
.else
sub sp, sp, #16
.endif
.if \hyp == 1 /* Hypervisor mode */
@@ -200,7 +214,48 @@ hyp_irq:
exit hyp=1
guest_sync:
entry hyp=0, compat=0
/*
* Save x0, x1 in advance
*/
stp x0, x1, [sp, #-(UREGS_kernel_sizeof - UREGS_X0)]
/*
* x1 is used because x0 may contain the function identifier.
* This avoids to restore x0 from the stack.
*/
mrs x1, esr_el2
lsr x1, x1, #HSR_EC_SHIFT /* x1 = ESR_EL2.EC */
cmp x1, #HSR_EC_HVC64
b.ne 1f /* Not a HVC skip fastpath. */
mrs x1, esr_el2
and x1, x1, #0xffff /* Check the immediate [0:16] */
cbnz x1, 1f /* should be 0 for HVC #0 */
/*
* Fastest path possible for ARM_SMCCC_ARCH_WORKAROUND_1.
* The workaround has already been applied on the exception
* entry from the guest, so let's quickly get back to the guest.
*
* Note that eor is used because the function identifier cannot
* be encoded as an immediate for cmp.
*/
eor w0, w0, #ARM_SMCCC_ARCH_WORKAROUND_1_FID
cbnz w0, 1f
/*
* Clobber both x0 and x1 to prevent leakage. Note that thanks
* the eor, x0 = 0.
*/
mov x1, xzr
eret
1:
/*
* x0/x1 may have been scratch by the fast path above, so avoid
* to save them.
*/
entry hyp=0, compat=0, save_x0_x1=0
/*
* The vSError will be checked while SKIP_SYNCHRONIZE_SERROR_ENTRY_EXIT
* is not set. If a vSError took place, the initial exception will be
+2
View File
@@ -306,6 +306,8 @@
#define HDCR_TPM (_AC(1,U)<<6) /* Trap Performance Monitors accesses */
#define HDCR_TPMCR (_AC(1,U)<<5) /* Trap PMCR accesses */
#define HSR_EC_SHIFT 26
#define HSR_EC_UNKNOWN 0x00
#define HSR_EC_WFI_WFE 0x01
#define HSR_EC_CP15_32 0x03
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.