The most complex async handling is for x86 which checks for various exceptions and if the irqchip is not handled in the kernel for interrupts. Most of the others just reflect if cs->halted has been set. Signed-off-by: Alex Bennée --- include/accel/kvm/cpu-ops.h | 9 +++++++++ include/system/kvm.h | 2 -- target/i386/kvm/kvm_i386.h | 1 + accel/kvm/kvm-all.c | 2 +- target/arm/kvm.c | 5 ----- 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 | 5 ----- target/s390x/kvm/kvm.c | 3 ++- 11 files changed, 19 insertions(+), 17 deletions(-) diff --git a/include/accel/kvm/cpu-ops.h b/include/accel/kvm/cpu-ops.h index 8b2aabd3c2f..cbd3935ba4d 100644 --- a/include/accel/kvm/cpu-ops.h +++ b/include/accel/kvm/cpu-ops.h @@ -35,11 +35,20 @@ struct kvm_run; * (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. + * @process_async_events: Optional callback executed at the start of + * kvm_cpu_exec() while holding the BQL to process + * pending asynchronous events (such as interrupts, + * resets, or MCEs). Returns non-zero (typically + * cpu->halted) if the vCPU should not run and should + * return EXCP_HLT, or 0 if execution can proceed. + * May be NULL if the target does not require event + * processing before execution. */ 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); + int (*process_async_events)(CPUState *cpu); } KVMCPUOps; #define TYPE_KVM_ACCEL_CPU "kvm-accel-cpu" diff --git a/include/system/kvm.h b/include/system/kvm.h index 82d18d79dc0..8c705d21f79 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_process_async_events(CPUState *cpu); - int kvm_arch_get_registers(CPUState *cpu, Error **errp); typedef enum kvm_put_state { diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index 5bcc9b51214..bff587a56de 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -36,6 +36,7 @@ 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); +int x86_kvm_process_async_events(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 33fa47bddf0..e8a26a9f067 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -3459,7 +3459,7 @@ int kvm_cpu_exec(CPUState *cpu) trace_kvm_cpu_exec(); - if (kvm_arch_process_async_events(cpu)) { + if (ops->process_async_events && ops->process_async_events(cpu)) { return EXCP_HLT; } diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 914f8e3b089..06b133ebf53 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -1619,11 +1619,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cs) return true; } -int kvm_arch_process_async_events(CPUState *cs) -{ - return 0; -} - /** * kvm_arm_hw_debug_active: * @cpu: ARMCPU diff --git a/target/i386/kvm/kvm-cpu.c b/target/i386/kvm/kvm-cpu.c index 6b75eb038e1..163d60a1060 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c @@ -238,6 +238,7 @@ 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, + .process_async_events = x86_kvm_process_async_events, }; 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 dfc70eac3db..83c4451cf31 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -6040,7 +6040,7 @@ MemTxAttrs x86_kvm_post_run(CPUState *cpu, struct kvm_run *run) return cpu_get_mem_attrs(env); } -int kvm_arch_process_async_events(CPUState *cs) +int x86_kvm_process_async_events(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 b23031007c2..600903a2280 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -1517,7 +1517,7 @@ int kvm_arch_irqchip_create(KVMState *s) return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL); } -int kvm_arch_process_async_events(CPUState *cs) +static int loongarch_kvm_process_async_events(CPUState *cs) { return cs->halted; } @@ -1644,6 +1644,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc) static const KVMCPUOps loongarch_kvm_cpu_ops = { .handle_exit = loongarch_kvm_handle_exit, + .process_async_events = loongarch_kvm_process_async_events, }; 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 25aaefd7649..e52f0b84ee3 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1336,7 +1336,7 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) return 0; } -int kvm_arch_process_async_events(CPUState *cs) +static int ppc_kvm_process_async_events(CPUState *cs) { return cs->halted; } @@ -3074,6 +3074,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc) static const KVMCPUOps ppc_kvm_cpu_ops = { .handle_exit = ppc_kvm_handle_exit, + .process_async_events = ppc_kvm_process_async_events, }; 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 8944961a939..a5333083765 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -1635,11 +1635,6 @@ int kvm_arch_irqchip_create(KVMState *s) return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL); } -int kvm_arch_process_async_events(CPUState *cs) -{ - return 0; -} - bool kvm_arch_stop_on_emulation_error(CPUState *cs) { return true; diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index 967706a87e1..420703f7683 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -984,7 +984,7 @@ void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) } } -int kvm_arch_process_async_events(CPUState *cs) +static int s390x_kvm_process_async_events(CPUState *cs) { return cs->halted; } @@ -2651,6 +2651,7 @@ void kvm_arch_accel_class_init(ObjectClass *oc) static const KVMCPUOps s390x_kvm_cpu_ops = { .handle_exit = s390x_kvm_handle_exit, + .process_async_events = s390x_kvm_process_async_events, }; static void kvm_cpu_accel_class_init(ObjectClass *oc, const void *data) -- 2.47.3