diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2016-09-06 14:02:17 +0100 |
---|---|---|
committer | Christoffer Dall <christoffer.dall@linaro.org> | 2016-09-08 12:53:00 +0200 |
commit | 3272f0d08e4490b792b99cf6034a2bb859bf6c9f (patch) | |
tree | feeacabe06da56fb71a94adce04293bd0a8d18ca /arch/arm64 | |
parent | 21977a4c57cd92c71113e21319302b5a399f9d2d (diff) | |
download | linux-3272f0d08e4490b792b99cf6034a2bb859bf6c9f.tar.bz2 |
arm64: KVM: Inject a vSerror if detecting a bad GICV access at EL2
If, when proxying a GICV access at EL2, we detect that the guest is
doing something silly, report an EL1 SError instead ofgnoring the
access.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
Diffstat (limited to 'arch/arm64')
-rw-r--r-- | arch/arm64/include/asm/kvm_hyp.h | 2 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp/switch.c | 18 |
2 files changed, 16 insertions, 4 deletions
diff --git a/arch/arm64/include/asm/kvm_hyp.h b/arch/arm64/include/asm/kvm_hyp.h index 88ec3ac35a32..b18e852d27e8 100644 --- a/arch/arm64/include/asm/kvm_hyp.h +++ b/arch/arm64/include/asm/kvm_hyp.h @@ -123,7 +123,7 @@ typeof(orig) * __hyp_text fname(void) \ void __vgic_v2_save_state(struct kvm_vcpu *vcpu); void __vgic_v2_restore_state(struct kvm_vcpu *vcpu); -bool __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu); +int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu); void __vgic_v3_save_state(struct kvm_vcpu *vcpu); void __vgic_v3_restore_state(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c index 8b81cc6f3717..731519cfee8e 100644 --- a/arch/arm64/kvm/hyp/switch.c +++ b/arch/arm64/kvm/hyp/switch.c @@ -311,9 +311,21 @@ again: !kvm_vcpu_dabt_isextabt(vcpu) && !kvm_vcpu_dabt_iss1tw(vcpu); - if (valid && __vgic_v2_perform_cpuif_access(vcpu)) { - __skip_instr(vcpu); - goto again; + if (valid) { + int ret = __vgic_v2_perform_cpuif_access(vcpu); + + if (ret == 1) { + __skip_instr(vcpu); + goto again; + } + + if (ret == -1) { + /* Promote an illegal access to an SError */ + __skip_instr(vcpu); + exit_code = ARM_EXCEPTION_EL1_SERROR; + } + + /* 0 falls through to be handler out of EL2 */ } } |