This is the first mandatory operation although currently none of our x86 tests trip up this handling. Signed-off-by: Alex Bennée --- include/accel/kvm/cpu-ops.h | 6 ++++++ include/system/kvm.h | 2 -- target/i386/kvm/kvm_i386.h | 1 + accel/kvm/kvm-all.c | 4 ++-- target/arm/kvm.c | 3 ++- target/i386/kvm/kvm-cpu.c | 1 + target/i386/kvm/kvm.c | 2 +- target/loongarch/kvm/kvm.c | 3 ++- target/ppc/kvm.c | 3 ++- target/riscv/kvm/kvm-cpu.c | 3 ++- target/s390x/kvm/kvm.c | 3 ++- 11 files changed, 21 insertions(+), 10 deletions(-) diff --git a/include/accel/kvm/cpu-ops.h b/include/accel/kvm/cpu-ops.h index e74081eb133..8b2aabd3c2f 100644 --- a/include/accel/kvm/cpu-ops.h +++ b/include/accel/kvm/cpu-ops.h @@ -30,10 +30,16 @@ struct kvm_run; * #MemTxAttrs to use for handling MMIO exits. * May be NULL if the target does not require post-run handling, * in which case MEMTXATTRS_UNSPECIFIED is assumed. + * @handle_exit: Mandatory callback executed to handle target-specific VM + * exits from KVM_RUN that are not handled by common KVM code + * (or unhandled sub-cases of KVM_EXIT_SYSTEM_EVENT). + * Returns 0 to continue execution, or an EXCP_* code (or negative + * error code) to exit the CPU execution loop. */ typedef struct KVMCPUOps { void (*pre_run)(CPUState *cpu, struct kvm_run *run); MemTxAttrs (*post_run)(CPUState *cpu, struct kvm_run *run); + int (*handle_exit)(CPUState *cpu, struct kvm_run *run); } KVMCPUOps; #define TYPE_KVM_ACCEL_CPU "kvm-accel-cpu" diff --git a/include/system/kvm.h b/include/system/kvm.h index 82785d37600..82d18d79dc0 100644 --- a/include/system/kvm.h +++ b/include/system/kvm.h @@ -333,8 +333,6 @@ extern const KVMCapabilityInfo kvm_arch_required_capabilities[]; void kvm_arch_accel_class_init(ObjectClass *oc); -int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run); - int kvm_arch_process_async_events(CPUState *cpu); int kvm_arch_get_registers(CPUState *cpu, Error **errp); diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index 6fb1da6a40c..5bcc9b51214 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -35,6 +35,7 @@ int kvm_get_vm_type(MachineState *ms); void kvm_arch_reset_vcpu(X86CPU *cs); void x86_kvm_pre_run(CPUState *cpu, struct kvm_run *run); MemTxAttrs x86_kvm_post_run(CPUState *cpu, struct kvm_run *run); +int x86_kvm_handle_exit(CPUState *cs, struct kvm_run *run); 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 41229774068..33fa47bddf0 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3616,7 +3616,7 @@ int kvm_cpu_exec(CPUState *cpu) ret = 0; break; default: - ret = kvm_arch_handle_exit(cpu, run); + ret = ops->handle_exit(cpu, run); break; } break; @@ -3634,7 +3634,7 @@ int kvm_cpu_exec(CPUState *cpu) run->memory_fault.flags & KVM_MEMORY_EXIT_FLAG_PRIVATE); break; default: - ret = kvm_arch_handle_exit(cpu, run); + ret = ops->handle_exit(cpu, run); break; } } while (ret == 0); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index d5f9b7c088c..914f8e3b089 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -1590,7 +1590,7 @@ static bool kvm_arm_handle_debug(ARMCPU *cpu, return false; } -int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +static int arm_kvm_handle_exit(CPUState *cs, struct kvm_run *run) { ARMCPU *cpu = ARM_CPU(cs); int ret = 0; @@ -2668,6 +2668,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3) static const KVMCPUOps arm_kvm_cpu_ops = { .pre_run = arm_kvm_pre_run, .post_run = arm_kvm_post_run, + .handle_exit = arm_kvm_handle_exit, }; static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data) diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c index 64af85cd113..6b75eb038e1 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c @@ -237,6 +237,7 @@ static void kvm_cpu_instance_init(CPUState *cs) static const KVMCPUOps x86_kvm_cpu_ops = { .pre_run = x86_kvm_pre_run, .post_run = x86_kvm_post_run, + .handle_exit = x86_kvm_handle_exit, }; 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 a1b91d502f0..dfc70eac3db 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -6529,7 +6529,7 @@ static int kvm_handle_hypercall(X86CPU *cpu, struct kvm_run *run) #define VMX_INVALID_GUEST_STATE 0x80000021 -int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +int x86_kvm_handle_exit(CPUState *cs, struct kvm_run *run) { X86CPU *cpu = X86_CPU(cs); uint64_t code; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 192538c0aa9..b23031007c2 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -1590,7 +1590,7 @@ static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run) return false; } -int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +static int loongarch_kvm_handle_exit(CPUState *cs, struct kvm_run *run) { int ret = 0; CPULoongArchState *env = cpu_env(cs); @@ -1643,6 +1643,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc) } static const KVMCPUOps loongarch_kvm_cpu_ops = { + .handle_exit = loongarch_kvm_handle_exit, }; static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 5ef4722cd6f..25aaefd7649 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1653,7 +1653,7 @@ static int kvm_handle_debug(PowerPCCPU *cpu, struct kvm_run *run) return DEBUG_RETURN_GUEST; } -int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +static int ppc_kvm_handle_exit(CPUState *cs, struct kvm_run *run) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; @@ -3073,6 +3073,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc) } static const KVMCPUOps ppc_kvm_cpu_ops = { + .handle_exit = ppc_kvm_handle_exit, }; static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data) diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c index 9580b6c1b20..8944961a939 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -1787,7 +1787,7 @@ static bool kvm_riscv_handle_debug(CPUState *cs) return false; } -int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +static int riscv_kvm_handle_exit(CPUState *cs, struct kvm_run *run) { int ret = 0; switch (run->exit_reason) { @@ -2188,6 +2188,7 @@ void riscv_kvm_cpu_finalize_features(RISCVCPU *cpu, Error **errp) } static const KVMCPUOps riscv_kvm_cpu_ops = { + .handle_exit = riscv_kvm_handle_exit, }; static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data) diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index ad1145c4ec1..967706a87e1 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -1904,7 +1904,7 @@ static int kvm_arch_handle_debug_exit(S390CPU *cpu) return ret; } -int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) +static int s390x_kvm_handle_exit(CPUState *cs, struct kvm_run *run) { S390CPU *cpu = S390_CPU(cs); int ret = 0; @@ -2650,6 +2650,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc) } static const KVMCPUOps s390x_kvm_cpu_ops = { + .handle_exit = s390x_kvm_handle_exit, }; static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data) -- 2.47.3