[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v13 08/22] target/arm: do not use cc->do_interrupt for KVM direct

From: Claudio Fontana
Subject: [PATCH v13 08/22] target/arm: do not use cc->do_interrupt for KVM directly
Date: Sat, 23 Jan 2021 13:23:45 +0100

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>
Cc: Peter Maydell <peter.maydell@linaro.org>
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>
 target/arm/helper.c | 4 ++++
 target/arm/kvm64.c  | 6 ++----
 2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/target/arm/helper.c b/target/arm/helper.c
index d2ead3fcbd..e42b94ce96 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -9960,6 +9960,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..3728b3a336 100644
--- a/target/arm/kvm64.c
+++ b/target/arm/kvm64.c
@@ -944,7 +944,6 @@ static void kvm_inject_arm_sea(CPUState *c)
     ARMCPU *cpu = ARM_CPU(c);
     CPUARMState *env = &cpu->env;
-    CPUClass *cc = CPU_GET_CLASS(c);
     uint32_t esr;
     bool same_el;
@@ -960,7 +959,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 | \
@@ -1491,7 +1490,6 @@ bool kvm_arm_handle_debug(CPUState *cs, struct 
kvm_debug_exit_arch *debug_exit)
     int hsr_ec = syn_get_ec(debug_exit->hsr);
     ARMCPU *cpu = ARM_CPU(cs);
-    CPUClass *cc = CPU_GET_CLASS(cs);
     CPUARMState *env = &cpu->env;
     /* Ensure PC is synchronised */
@@ -1545,7 +1543,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;
-    cc->do_interrupt(cs);
+    arm_cpu_do_interrupt(cs);
     return false;

reply via email to

[Prev in Thread] Current Thread [Next in Thread]