提交 7226bc2e 编写于 作者: A Alex Bennée 提交者: Christoffer Dall

kvm: arm64: handle single-stepping trapped instructions

If we are using guest debug to single-step the guest, we need to ensure
that we exit after emulating the instruction. This only affects
instructions completely emulated by the kernel. For instructions
emulated in userspace, we need to exit and return to complete the
emulation.

The kvm_arm_handle_step_debug() helper sets up the necessary exit
state if needed.
Signed-off-by: NAlex Bennée <alex.bennee@linaro.org>
Reviewed-by: NJulien Thierry <julien.thierry@arm.com>
Signed-off-by: NChristoffer Dall <christoffer.dall@linaro.org>
上级 696673d1
...@@ -186,6 +186,40 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu) ...@@ -186,6 +186,40 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
return arm_exit_handlers[hsr_ec]; return arm_exit_handlers[hsr_ec];
} }
/*
* We may be single-stepping an emulated instruction. If the emulation
* has been completed in the kernel, we can return to userspace with a
* KVM_EXIT_DEBUG, otherwise userspace needs to complete its
* emulation first.
*/
static int handle_trap_exceptions(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
int handled;
/*
* See ARM ARM B1.14.1: "Hyp traps on instructions
* that fail their condition code check"
*/
if (!kvm_condition_valid(vcpu)) {
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
handled = 1;
} else {
exit_handle_fn exit_handler;
exit_handler = kvm_get_exit_handler(vcpu);
handled = exit_handler(vcpu, run);
}
/*
* kvm_arm_handle_step_debug() sets the exit_reason on the kvm_run
* structure if we need to return to userspace.
*/
if (handled > 0 && kvm_arm_handle_step_debug(vcpu, run))
handled = 0;
return handled;
}
/* /*
* Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on * Return > 0 to return to guest, < 0 on error, 0 (and set exit_reason) on
* proper exit to userspace. * proper exit to userspace.
...@@ -193,8 +227,6 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu) ...@@ -193,8 +227,6 @@ static exit_handle_fn kvm_get_exit_handler(struct kvm_vcpu *vcpu)
int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
int exception_index) int exception_index)
{ {
exit_handle_fn exit_handler;
if (ARM_SERROR_PENDING(exception_index)) { if (ARM_SERROR_PENDING(exception_index)) {
u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu)); u8 hsr_ec = ESR_ELx_EC(kvm_vcpu_get_hsr(vcpu));
...@@ -222,18 +254,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, ...@@ -222,18 +254,7 @@ int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
kvm_inject_vabt(vcpu); kvm_inject_vabt(vcpu);
return 1; return 1;
case ARM_EXCEPTION_TRAP: case ARM_EXCEPTION_TRAP:
/* return handle_trap_exceptions(vcpu, run);
* See ARM ARM B1.14.1: "Hyp traps on instructions
* that fail their condition code check"
*/
if (!kvm_condition_valid(vcpu)) {
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
return 1;
}
exit_handler = kvm_get_exit_handler(vcpu);
return exit_handler(vcpu, run);
case ARM_EXCEPTION_HYP_GONE: case ARM_EXCEPTION_HYP_GONE:
/* /*
* EL2 has been reset to the hyp-stub. This happens when a guest * EL2 has been reset to the hyp-stub. This happens when a guest
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册