Skip to content

Commit 0c389d9

Browse files
chazyMarc Zyngier
authored andcommitted
KVM: arm64: Don't save the host ELR_EL2 and SPSR_EL2 on VHE systems
On non-VHE systems we need to save the ELR_EL2 and SPSR_EL2 so that we can return to the host in EL1 in the same state and location where we issued a hypercall to EL2, but on VHE ELR_EL2 and SPSR_EL2 are not useful because we never enter a guest as a result of an exception entry that would be directly handled by KVM. The kernel entry code already saves ELR_EL1/SPSR_EL1 on exception entry, which is enough. Therefore, factor out these registers into separate save/restore functions, making it easy to exclude them from the VHE world-switch path later on. Reviewed-by: Marc Zyngier <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Signed-off-by: Christoffer Dall <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent 4cdecab commit 0c389d9

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

arch/arm64/kvm/hyp/sysreg-sr.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ static void __hyp_text __sysreg_save_el1_state(struct kvm_cpu_context *ctxt)
7171
ctxt->gp_regs.sp_el1 = read_sysreg(sp_el1);
7272
ctxt->gp_regs.elr_el1 = read_sysreg_el1(elr);
7373
ctxt->gp_regs.spsr[KVM_SPSR_EL1]= read_sysreg_el1(spsr);
74+
}
75+
76+
static void __hyp_text __sysreg_save_el2_return_state(struct kvm_cpu_context *ctxt)
77+
{
7478
ctxt->gp_regs.regs.pc = read_sysreg_el2(elr);
7579
ctxt->gp_regs.regs.pstate = read_sysreg_el2(spsr);
7680

@@ -83,6 +87,7 @@ void __hyp_text __sysreg_save_state_nvhe(struct kvm_cpu_context *ctxt)
8387
__sysreg_save_el1_state(ctxt);
8488
__sysreg_save_common_state(ctxt);
8589
__sysreg_save_user_state(ctxt);
90+
__sysreg_save_el2_return_state(ctxt);
8691
}
8792

8893
void sysreg_save_host_state_vhe(struct kvm_cpu_context *ctxt)
@@ -96,6 +101,7 @@ void sysreg_save_guest_state_vhe(struct kvm_cpu_context *ctxt)
96101
__sysreg_save_el1_state(ctxt);
97102
__sysreg_save_common_state(ctxt);
98103
__sysreg_save_user_state(ctxt);
104+
__sysreg_save_el2_return_state(ctxt);
99105
}
100106

101107
static void __hyp_text __sysreg_restore_common_state(struct kvm_cpu_context *ctxt)
@@ -140,6 +146,11 @@ static void __hyp_text __sysreg_restore_el1_state(struct kvm_cpu_context *ctxt)
140146
write_sysreg(ctxt->gp_regs.sp_el1, sp_el1);
141147
write_sysreg_el1(ctxt->gp_regs.elr_el1, elr);
142148
write_sysreg_el1(ctxt->gp_regs.spsr[KVM_SPSR_EL1],spsr);
149+
}
150+
151+
static void __hyp_text
152+
__sysreg_restore_el2_return_state(struct kvm_cpu_context *ctxt)
153+
{
143154
write_sysreg_el2(ctxt->gp_regs.regs.pc, elr);
144155
write_sysreg_el2(ctxt->gp_regs.regs.pstate, spsr);
145156

@@ -152,6 +163,7 @@ void __hyp_text __sysreg_restore_state_nvhe(struct kvm_cpu_context *ctxt)
152163
__sysreg_restore_el1_state(ctxt);
153164
__sysreg_restore_common_state(ctxt);
154165
__sysreg_restore_user_state(ctxt);
166+
__sysreg_restore_el2_return_state(ctxt);
155167
}
156168

157169
void sysreg_restore_host_state_vhe(struct kvm_cpu_context *ctxt)
@@ -165,6 +177,7 @@ void sysreg_restore_guest_state_vhe(struct kvm_cpu_context *ctxt)
165177
__sysreg_restore_el1_state(ctxt);
166178
__sysreg_restore_common_state(ctxt);
167179
__sysreg_restore_user_state(ctxt);
180+
__sysreg_restore_el2_return_state(ctxt);
168181
}
169182

170183
void __hyp_text __sysreg32_save_state(struct kvm_vcpu *vcpu)

0 commit comments

Comments
 (0)