summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Bennée <alex.bennee@linaro.org>2017-11-23 12:11:33 +0000
committerChristoffer Dall <christoffer.dall@linaro.org>2017-11-29 18:17:46 +0100
commite70dce73befcf96607bc6e24c2c8f84229d6721e (patch)
treec6ac26fab0be1d38180417827a6a23276b3ca1cd
parent1eb591288b956bdd75e464e69b6b8207ffa6e5e3 (diff)
downloadlinux-e70dce73befcf96607bc6e24c2c8f84229d6721e.tar.gz
linux-e70dce73befcf96607bc6e24c2c8f84229d6721e.tar.bz2
linux-e70dce73befcf96607bc6e24c2c8f84229d6721e.zip
kvm: arm64: handle single-step during SError exceptions
When an SError arrives during single-step both the SError and debug exceptions may be pending when the step is completed, and the architecture doesn't define the ordering of the two. This means that we can observe en SError even though we've just completed a step, without receiving a debug exception. In that case the DBG_SPSR_SS bit will have flipped as the instruction executed. After handling the abort in handle_exit() we test to see if the bit is clear and we were single-stepping before deciding if we need to exit to user space. Acked-by: Marc Zyngier <marc.zyngier@arm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org>
-rw-r--r--arch/arm64/kvm/handle_exit.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/arm64/kvm/handle_exit.c b/arch/arm64/kvm/handle_exit.c
index 029c28dd25e9..304203fa9e33 100644
--- a/arch/arm64/kvm/handle_exit.c
+++ b/arch/arm64/kvm/handle_exit.c
@@ -28,6 +28,7 @@
#include <asm/kvm_emulate.h>
#include <asm/kvm_mmu.h>
#include <asm/kvm_psci.h>
+#include <asm/debug-monitors.h>
#define CREATE_TRACE_POINTS
#include "trace.h"
@@ -252,7 +253,12 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
return 1;
case ARM_EXCEPTION_EL1_SERROR:
kvm_inject_vabt(vcpu);
- return 1;
+ /* We may still need to return for single-step */
+ if (!(*vcpu_cpsr(vcpu) & DBG_SPSR_SS)
+ && kvm_arm_handle_step_debug(vcpu, run))
+ return 0;
+ else
+ return 1;
case ARM_EXCEPTION_TRAP:
return handle_trap_exceptions(vcpu, run);
case ARM_EXCEPTION_HYP_GONE: