summaryrefslogtreecommitdiffstats
path: root/arch/arm/kvm
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-09-06 15:02:08 +0200
committerChristoffer Dall <christoffer.dall@linaro.org>2016-09-08 12:53:00 +0200
commit1f7e378d1235a3cb5c9cdd8c62fe13cb6c3cf157 (patch)
tree8b5226c1b222b755a028199d609b323d8aa8d159 /arch/arm/kvm
parentarm64: KVM: Handle async aborts delivered while at EL2 (diff)
downloadlinux-1f7e378d1235a3cb5c9cdd8c62fe13cb6c3cf157.tar.xz
linux-1f7e378d1235a3cb5c9cdd8c62fe13cb6c3cf157.zip
arm: KVM: Preserve pending Virtual Abort in world switch
The HCR.VA bit is used to signal an Abort 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, and at which point it must be cleared from the context. Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'arch/arm/kvm')
-rw-r--r--arch/arm/kvm/hyp/switch.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
index 37b336549700..9da16fd1005f 100644
--- a/arch/arm/kvm/hyp/switch.c
+++ b/arch/arm/kvm/hyp/switch.c
@@ -54,6 +54,15 @@ static void __hyp_text __deactivate_traps(struct kvm_vcpu *vcpu)
{
u32 val;
+ /*
+ * If we pended a virtual abort, preserve it until it gets
+ * cleared. See B1.9.9 (Virtual Abort exception) for details,
+ * but the crucial bit is the zeroing of HCR.VA in the
+ * pseudocode.
+ */
+ if (vcpu->arch.hcr & HCR_VA)
+ vcpu->arch.hcr = read_sysreg(HCR);
+
write_sysreg(0, HCR);
write_sysreg(0, HSTR);
val = read_sysreg(HDCR);