mirror of https://gitee.com/openkylin/qemu.git
target/arm: do not use cc->do_interrupt for KVM directly
cc->do_interrupt is in theory a TCG callback used in accel/tcg only, to prepare the emulated architecture to take an interrupt as defined in the hardware specifications, but in reality the _do_interrupt style of functions in targets are also occasionally reused by KVM to prepare the architecture state in a similar way where userspace code has identified that it needs to deliver an exception to the guest. In the case of ARM, that includes: 1) the vcpu thread got a SIGBUS indicating a memory error, and we need to deliver a Synchronous External Abort to the guest to let it know about the error. 2) the kernel told us about a debug exception (breakpoint, watchpoint) but it is not for one of QEMU's own gdbstub breakpoints/watchpoints so it must be a breakpoint the guest itself has set up, therefore we need to deliver it to the guest. So in order to reuse code, the same arm_do_interrupt function is used. This is all fine, but we need to avoid calling it using the callback registered in CPUClass, since that one is now TCG-only. Fortunately this is easily solved by replacing calls to CPUClass::do_interrupt() with explicit calls to arm_do_interrupt(). Signed-off-by: Claudio Fontana <cfontana@suse.de> Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Cc: Peter Maydell <peter.maydell@linaro.org> Message-Id: <20210204163931.7358-9-cfontana@suse.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
e9ce43e97a
commit
853bfef4e6
|
@ -9969,6 +9969,10 @@ static void handle_semihosting(CPUState *cs)
|
||||||
* Do any appropriate logging, handle PSCI calls, and then hand off
|
* Do any appropriate logging, handle PSCI calls, and then hand off
|
||||||
* to the AArch64-entry or AArch32-entry function depending on the
|
* to the AArch64-entry or AArch32-entry function depending on the
|
||||||
* target exception level's register width.
|
* target exception level's register width.
|
||||||
|
*
|
||||||
|
* Note: this is used for both TCG (as the do_interrupt tcg op),
|
||||||
|
* and KVM to re-inject guest debug exceptions, and to
|
||||||
|
* inject a Synchronous-External-Abort.
|
||||||
*/
|
*/
|
||||||
void arm_cpu_do_interrupt(CPUState *cs)
|
void arm_cpu_do_interrupt(CPUState *cs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -946,7 +946,6 @@ static void kvm_inject_arm_sea(CPUState *c)
|
||||||
{
|
{
|
||||||
ARMCPU *cpu = ARM_CPU(c);
|
ARMCPU *cpu = ARM_CPU(c);
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
CPUClass *cc = CPU_GET_CLASS(c);
|
|
||||||
uint32_t esr;
|
uint32_t esr;
|
||||||
bool same_el;
|
bool same_el;
|
||||||
|
|
||||||
|
@ -962,7 +961,7 @@ static void kvm_inject_arm_sea(CPUState *c)
|
||||||
|
|
||||||
env->exception.syndrome = esr;
|
env->exception.syndrome = esr;
|
||||||
|
|
||||||
cc->do_interrupt(c);
|
arm_cpu_do_interrupt(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
|
#define AARCH64_CORE_REG(x) (KVM_REG_ARM64 | KVM_REG_SIZE_U64 | \
|
||||||
|
@ -1493,7 +1492,6 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
|
||||||
{
|
{
|
||||||
int hsr_ec = syn_get_ec(debug_exit->hsr);
|
int hsr_ec = syn_get_ec(debug_exit->hsr);
|
||||||
ARMCPU *cpu = ARM_CPU(cs);
|
ARMCPU *cpu = ARM_CPU(cs);
|
||||||
CPUClass *cc = CPU_GET_CLASS(cs);
|
|
||||||
CPUARMState *env = &cpu->env;
|
CPUARMState *env = &cpu->env;
|
||||||
|
|
||||||
/* Ensure PC is synchronised */
|
/* Ensure PC is synchronised */
|
||||||
|
@ -1547,7 +1545,7 @@ bool kvm_arm_handle_debug(CPUState *cs, struct kvm_debug_exit_arch *debug_exit)
|
||||||
env->exception.vaddress = debug_exit->far;
|
env->exception.vaddress = debug_exit->far;
|
||||||
env->exception.target_el = 1;
|
env->exception.target_el = 1;
|
||||||
qemu_mutex_lock_iothread();
|
qemu_mutex_lock_iothread();
|
||||||
cc->do_interrupt(cs);
|
arm_cpu_do_interrupt(cs);
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue