Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: kvm: Move lr save/restore from do_el2_call into EL1

Today the 'hvc' calling KVM or the hyp-stub is expected to preserve all
registers. KVM saves/restores the registers it needs on the EL2 stack using
do_el2_call(). The hyp-stub has no stack, later patches need to be able to
be able to clobber the link register.

Move the link register save/restore to the the call sites.

Signed-off-by: James Morse <james.morse@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>

authored by

James Morse and committed by
Will Deacon
00a44cda e7227d0e

+16 -7
+8 -2
arch/arm64/kernel/hyp-stub.S
··· 101 101 */ 102 102 103 103 ENTRY(__hyp_get_vectors) 104 + str lr, [sp, #-16]! 104 105 mov x0, xzr 105 - // fall through 106 - ENTRY(__hyp_set_vectors) 107 106 hvc #0 107 + ldr lr, [sp], #16 108 108 ret 109 109 ENDPROC(__hyp_get_vectors) 110 + 111 + ENTRY(__hyp_set_vectors) 112 + str lr, [sp, #-16]! 113 + hvc #0 114 + ldr lr, [sp], #16 115 + ret 110 116 ENDPROC(__hyp_set_vectors)
+6 -1
arch/arm64/kvm/hyp.S
··· 38 38 * A function pointer with a value of 0 has a special meaning, and is 39 39 * used to implement __hyp_get_vectors in the same way as in 40 40 * arch/arm64/kernel/hyp_stub.S. 41 + * HVC behaves as a 'bl' call and will clobber lr. 41 42 */ 42 43 ENTRY(__kvm_call_hyp) 43 - alternative_if_not ARM64_HAS_VIRT_HOST_EXTN 44 + alternative_if_not ARM64_HAS_VIRT_HOST_EXTN 45 + str lr, [sp, #-16]! 44 46 hvc #0 47 + ldr lr, [sp], #16 45 48 ret 46 49 alternative_else 47 50 b __vhe_hyp_call 51 + nop 52 + nop 48 53 nop 49 54 alternative_endif 50 55 ENDPROC(__kvm_call_hyp)
+2 -4
arch/arm64/kvm/hyp/hyp-entry.S
··· 42 42 * Shuffle the parameters before calling the function 43 43 * pointed to in x0. Assumes parameters in x[1,2,3]. 44 44 */ 45 - sub sp, sp, #16 46 - str lr, [sp] 47 45 mov lr, x0 48 46 mov x0, x1 49 47 mov x1, x2 50 48 mov x2, x3 51 49 blr lr 52 - ldr lr, [sp] 53 - add sp, sp, #16 54 50 .endm 55 51 56 52 ENTRY(__vhe_hyp_call) 53 + str lr, [sp, #-16]! 57 54 do_el2_call 55 + ldr lr, [sp], #16 58 56 /* 59 57 * We used to rely on having an exception return to get 60 58 * an implicit isb. In the E2H case, we don't have it anymore.