Really only x86 is doing much complicated, everyone else defaults to
stop.
Signed-off-by: Alex Bennée <[email protected]>
---
include/accel/kvm/cpu-ops.h | 7 +++++++
include/system/kvm.h | 2 --
target/i386/kvm/kvm_i386.h | 1 +
accel/kvm/kvm-all.c | 8 +++++++-
target/arm/kvm.c | 5 -----
target/i386/kvm/kvm-cpu.c | 1 +
target/i386/kvm/kvm.c | 2 +-
target/loongarch/kvm/kvm.c | 5 -----
target/ppc/kvm.c | 5 -----
target/riscv/kvm/kvm-cpu.c | 5 -----
target/s390x/kvm/kvm.c | 5 -----
11 files changed, 17 insertions(+), 29 deletions(-)
diff --git a/include/accel/kvm/cpu-ops.h b/include/accel/kvm/cpu-ops.h
index 23a83eee6ed..c2ae74f2b87 100644
--- a/include/accel/kvm/cpu-ops.h
+++ b/include/accel/kvm/cpu-ops.h
@@ -95,6 +95,12 @@ struct kvm_run;
* Returns 0 on success, or a negative errno on failure.
* @remove_all_hw_breakpoints: Optional callback to remove all architecture-
* specific hardware breakpoints and watchpoints.
+ * @stop_on_emulation_error: Optional callback executed when KVM encounters an
+ * internal emulation failure (such as
+ * KVM_INTERNAL_ERROR_EMULATION) to decide whether
+ * execution should stop.
+ * Returns true to stop the VM, or false to dump
state
+ * and continue. If NULL, defaults to true.
*/
typedef struct KVMCPUOps {
int (*pre_create_vcpu)(CPUState *cpu, Error **errp);
@@ -115,6 +121,7 @@ typedef struct KVMCPUOps {
int (*remove_hw_breakpoint)(CPUState *cpu, vaddr addr, vaddr len,
GdbBreakpointType type);
void (*remove_all_hw_breakpoints)(CPUState *cpu);
+ bool (*stop_on_emulation_error)(CPUState *cpu);
} KVMCPUOps;
#define TYPE_KVM_ACCEL_CPU "kvm-accel-cpu"
diff --git a/include/system/kvm.h b/include/system/kvm.h
index 1a52e7e5261..719ae1c71fb 100644
--- a/include/system/kvm.h
+++ b/include/system/kvm.h
@@ -387,8 +387,6 @@ struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState
*cpu,
int kvm_sw_breakpoints_active(CPUState *cpu);
-bool kvm_arch_stop_on_emulation_error(CPUState *cpu);
-
int kvm_vm_check_extension(KVMState *s, unsigned int extension);
#define kvm_vm_enable_cap(s, capability, cap_flags, ...) \
diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h
index e2ae601100c..9d4be604443 100644
--- a/target/i386/kvm/kvm_i386.h
+++ b/target/i386/kvm/kvm_i386.h
@@ -51,6 +51,7 @@ int x86_kvm_insert_hw_breakpoint(CPUState *cs, vaddr addr,
vaddr len,
int x86_kvm_remove_hw_breakpoint(CPUState *cs, vaddr addr, vaddr len,
GdbBreakpointType type);
void x86_kvm_remove_all_hw_breakpoints(CPUState *cs);
+bool x86_kvm_stop_on_emulation_error(CPUState *cs);
void kvm_arch_after_reset_vcpu(X86CPU *cpu);
void kvm_arch_do_init_vcpu(X86CPU *cs);
uint32_t kvm_arch_get_supported_cpuid(KVMState *env, uint32_t function,
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 5b96fac513e..62ebb3458c8 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3183,8 +3183,14 @@ static int kvm_handle_internal_error(CPUState *cpu,
struct kvm_run *run)
i, (uint64_t)run->internal.data[i]);
}
if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) {
+ const KVMCPUOps *ops = kvm_get_cpu_ops(cpu);
+ bool stop = true;
+
fprintf(stderr, "emulation failure\n");
- if (!kvm_arch_stop_on_emulation_error(cpu)) {
+ if (ops && ops->stop_on_emulation_error) {
+ stop = ops->stop_on_emulation_error(cpu);
+ }
+ if (!stop) {
cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
return EXCP_INTERRUPT;
}
diff --git a/target/arm/kvm.c b/target/arm/kvm.c
index 5c0ccfc11cd..ed99699098c 100644
--- a/target/arm/kvm.c
+++ b/target/arm/kvm.c
@@ -1609,11 +1609,6 @@ static int arm_kvm_handle_exit(CPUState *cs, struct
kvm_run *run)
return ret;
}
-bool kvm_arch_stop_on_emulation_error(CPUState *cs)
-{
- return true;
-}
-
/**
* kvm_arm_hw_debug_active:
* @cpu: ARMCPU
diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c
index baaee0c7e71..c9340183eaf 100644
--- a/target/i386/kvm/kvm-cpu.c
+++ b/target/i386/kvm/kvm-cpu.c
@@ -251,6 +251,7 @@ static const KVMCPUOps x86_kvm_cpu_ops = {
.insert_hw_breakpoint = x86_kvm_insert_hw_breakpoint,
.remove_hw_breakpoint = x86_kvm_remove_hw_breakpoint,
.remove_all_hw_breakpoints = x86_kvm_remove_all_hw_breakpoints,
+ .stop_on_emulation_error = x86_kvm_stop_on_emulation_error,
};
static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 78c06a07bd6..e419af944cb 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -6661,7 +6661,7 @@ int x86_kvm_handle_exit(CPUState *cs, struct kvm_run *run)
return ret;
}
-bool kvm_arch_stop_on_emulation_error(CPUState *cs)
+bool x86_kvm_stop_on_emulation_error(CPUState *cs)
{
X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env;
diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c
index b15f60bd2c3..fd0f3a82a6b 100644
--- a/target/loongarch/kvm/kvm.c
+++ b/target/loongarch/kvm/kvm.c
@@ -1513,11 +1513,6 @@ static int loongarch_kvm_process_async_events(CPUState
*cs)
return cs->halted;
}
-bool kvm_arch_stop_on_emulation_error(CPUState *cs)
-{
- return true;
-}
-
static void loongarch_kvm_update_guest_debug(CPUState *cpu,
struct kvm_guest_debug *dbg)
{
diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
index 548bf3e00ad..f5f2f82a4d8 100644
--- a/target/ppc/kvm.c
+++ b/target/ppc/kvm.c
@@ -2840,11 +2840,6 @@ int kvmppc_load_htab_chunk(QEMUFile *f, int fd, uint32_t
index,
return 0;
}
-bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
-{
- return true;
-}
-
void kvm_arch_init_irq_routing(KVMState *s)
{
}
diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c
index aeb049c0c71..6a88fe761c0 100644
--- a/target/riscv/kvm/kvm-cpu.c
+++ b/target/riscv/kvm/kvm-cpu.c
@@ -1621,11 +1621,6 @@ int kvm_arch_irqchip_create(KVMState *s)
return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL);
}
-bool kvm_arch_stop_on_emulation_error(CPUState *cs)
-{
- return true;
-}
-
static void kvm_riscv_handle_sbi_dbcn(CPUState *cs, struct kvm_run *run)
{
const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c
index ccdc85900ba..e0373d05515 100644
--- a/target/s390x/kvm/kvm.c
+++ b/target/s390x/kvm/kvm.c
@@ -1935,11 +1935,6 @@ static int s390x_kvm_handle_exit(CPUState *cs, struct
kvm_run *run)
return ret;
}
-bool kvm_arch_stop_on_emulation_error(CPUState *cpu)
-{
- return true;
-}
-
void kvm_s390_enable_css_support(S390CPU *cpu)
{
int r;
--
2.47.3