arm64: KVM: Preserve pending vSError in world switch
The HCR_EL2.VSE bit is used to signal an SError to a guest, and has the peculiar feature of getting cleared when the guest has taken the abort (this is the only bit that behaves as such in this register). This means that if we signal such an abort, we must leave it in the guest context until it disappears from HCR_EL2, and at which point it must be cleared from the context. This is achieved by reading back from HCR_EL2 until the guest takes the fault. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
This commit is contained in:
parent
7b17145ec7
commit
44636f976f
|
@ -110,6 +110,15 @@ static hyp_alternate_select(__deactivate_traps_arch,
|
||||||
|
|
||||||
static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
|
static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* If we pended a virtual abort, preserve it until it gets
|
||||||
|
* cleared. See D1.14.3 (Virtual Interrupts) for details, but
|
||||||
|
* the crucial bit is "On taking a vSError interrupt,
|
||||||
|
* HCR_EL2.VSE is cleared to 0."
|
||||||
|
*/
|
||||||
|
if (vcpu->arch.hcr_el2 & HCR_VSE)
|
||||||
|
vcpu->arch.hcr_el2 = read_sysreg(hcr_el2);
|
||||||
|
|
||||||
__deactivate_traps_arch()();
|
__deactivate_traps_arch()();
|
||||||
write_sysreg(0, hstr_el2);
|
write_sysreg(0, hstr_el2);
|
||||||
write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2);
|
write_sysreg(read_sysreg(mdcr_el2) & MDCR_EL2_HPMN_MASK, mdcr_el2);
|
||||||
|
|
Loading…
Reference in New Issue