Claudio Fontana <cfont...@suse.de> writes:
> 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(). My ultra-modern gcc10 gentoo box is quick to point out: 64.c.o -c ../../target/arm/kvm64.c ../../target/arm/kvm64.c: In function ‘kvm_inject_arm_sea’: ../../target/arm/kvm64.c:947:15: error: unused variable ‘cc’ [-Werror=unused-variable] 947 | CPUClass *cc = CPU_GET_CLASS(c); | ^~ ../../target/arm/kvm64.c: In function ‘kvm_arm_handle_debug’: ../../target/arm/kvm64.c:1494:15: error: unused variable ‘cc’ [-Werror=unused-variable] 1494 | CPUClass *cc = CPU_GET_CLASS(cs); | ^~ cc1: all warnings being treated as errors > > Signed-off-by: Claudio Fontana <cfont...@suse.de> > Cc: Peter Maydell <peter.mayd...@linaro.org> > Reviewed-by: Alex Bennée <alex.ben...@linaro.org> > Reviewed-by: Philippe Mathieu-Daudé <phi...@redhat.com> > --- > target/arm/helper.c | 4 ++++ > target/arm/kvm64.c | 4 ++-- > 2 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/target/arm/helper.c b/target/arm/helper.c > index 38cd35c049..bebaabf525 100644 > --- a/target/arm/helper.c > +++ b/target/arm/helper.c > @@ -9895,6 +9895,10 @@ static void handle_semihosting(CPUState *cs) > * Do any appropriate logging, handle PSCI calls, and then hand off > * to the AArch64-entry or AArch32-entry function depending on the > * 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) > { > diff --git a/target/arm/kvm64.c b/target/arm/kvm64.c > index f74bac2457..2b17e4203d 100644 > --- a/target/arm/kvm64.c > +++ b/target/arm/kvm64.c > @@ -960,7 +960,7 @@ static void kvm_inject_arm_sea(CPUState *c) > > 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 | \ > @@ -1545,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.target_el = 1; > qemu_mutex_lock_iothread(); > - cc->do_interrupt(cs); > + arm_cpu_do_interrupt(cs); > qemu_mutex_unlock_iothread(); > > return false; -- Alex Bennée