Port our first function. As a number of arches don't do anything at this point they become nops and the call becomes optional. Signed-off-by: Alex Bennée --- include/accel/kvm/cpu-ops.h | 11 +++++++++++ include/system/kvm.h | 1 - target/i386/kvm/kvm_i386.h | 1 + accel/kvm/kvm-all.c | 7 ++++++- accel/tcg/cpu-exec.c | 2 +- target/arm/kvm.c | 3 ++- target/i386/kvm/kvm-cpu.c | 1 + target/i386/kvm/kvm.c | 2 +- target/loongarch/kvm/kvm.c | 4 ---- target/ppc/kvm.c | 4 ---- target/riscv/kvm/kvm-cpu.c | 4 ---- target/s390x/kvm/kvm.c | 4 ---- 12 files changed, 23 insertions(+), 21 deletions(-) diff --git a/include/accel/kvm/cpu-ops.h b/include/accel/kvm/cpu-ops.h index 662d0c553c7..2c04fa5adf5 100644 --- a/include/accel/kvm/cpu-ops.h +++ b/include/accel/kvm/cpu-ops.h @@ -13,10 +13,19 @@ #include "hw/core/cpu.h" #include "accel/accel-cpu-target.h" +struct kvm_run; + /** * struct KVMCPUOps - Target-specific per-vCPU operations for KVM + * + * @pre_run: Optional callback executed immediately prior to entering the + * KVM_RUN ioctl in the vCPU thread loop. Used by architectures + * that need to inject pending events (e.g. x86 NMI/SMI) or verify + * injected exceptions (e.g. ARM external data aborts). + * May be NULL if the target does not require pre-run handling. */ typedef struct KVMCPUOps { + void (*pre_run)(CPUState *cpu, struct kvm_run *run); } KVMCPUOps; #define TYPE_KVM_ACCEL_CPU "kvm-accel-cpu" @@ -25,6 +34,8 @@ typedef struct KVMCPUOps { * struct KVMAccelCPUClass - KVM-specific accelerator CPU class * * @parent_class: The parent #AccelCPUClass + * @cpu_ops: Target-specific KVM operations table. Must be non-NULL when + * KVM acceleration is initialized for the target CPU. */ typedef struct KVMAccelCPUClass { AccelCPUClass parent_class; diff --git a/include/system/kvm.h b/include/system/kvm.h index d29624034cb..e9d7b86ea4a 100644 --- a/include/system/kvm.h +++ b/include/system/kvm.h @@ -333,7 +333,6 @@ extern const KVMCapabilityInfo kvm_arch_required_capabilities[]; void kvm_arch_accel_class_init(ObjectClass *oc); -void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run); MemTxAttrs kvm_arch_post_run(CPUState *cpu, struct kvm_run *run); int kvm_arch_handle_exit(CPUState *cpu, struct kvm_run *run); diff --git a/target/i386/kvm/kvm_i386.h b/target/i386/kvm/kvm_i386.h index 2b653442f4d..218ae8f09ce 100644 --- a/target/i386/kvm/kvm_i386.h +++ b/target/i386/kvm/kvm_i386.h @@ -33,6 +33,7 @@ bool kvm_hyperv_expand_features(X86CPU *cpu, Error **errp); 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); 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 db8fba53f33..4dca5467f4a 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -55,6 +55,8 @@ #include "hw/core/boards.h" #include "system/stats.h" +#include "accel/accel-cpu-target.h" +#include "accel/kvm/cpu-ops.h" /* This check must be after config-host.h is included */ #ifdef CONFIG_EVENTFD @@ -3451,6 +3453,7 @@ out_unref: int kvm_cpu_exec(CPUState *cpu) { + const KVMCPUOps *ops = kvm_get_cpu_ops(cpu); struct kvm_run *run = cpu->kvm_run; int ret, run_ret; @@ -3474,7 +3477,9 @@ int kvm_cpu_exec(CPUState *cpu) } } - kvm_arch_pre_run(cpu, run); + if (ops->pre_run) { + ops->pre_run(cpu, run); + } /* Corresponding store-release is in cpu_exit. */ if (qatomic_load_acquire(&cpu->exit_request)) { trace_kvm_interrupt_exit_request(); diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c index 5b4bca5084f..4d2a0aefe89 100644 --- a/accel/tcg/cpu-exec.c +++ b/accel/tcg/cpu-exec.c @@ -758,7 +758,7 @@ void tcg_kick_vcpu_thread(CPUState *cpu) * Ensure cpu_exec will see the reason why the exit request was set. * FIXME: this is not always needed. Other accelerators instead * read interrupt_request and set exit_request on demand from the - * CPU thread; see kvm_arch_pre_run() for example. + * CPU thread; see KVMCPUOps::pre_run for example. */ qatomic_store_release(&cpu->exit_request, true); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 7a3c957c3a5..4475fd1a9d9 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -1377,7 +1377,7 @@ static bool kvm_arm_verify_ext_dabt_pending(ARMCPU *cpu) return false; } -void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) +static void arm_kvm_pre_run(CPUState *cs, struct kvm_run *run) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; @@ -2666,6 +2666,7 @@ void arm_gic_cap_kvm_probe(GICCapability *v2, GICCapability *v3) } static const KVMCPUOps arm_kvm_cpu_ops = { + .pre_run = arm_kvm_pre_run, }; 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 9de107a18d5..eab5ab46d45 100644 --- a/target/i386/kvm/kvm-cpu.c +++ b/target/i386/kvm/kvm-cpu.c @@ -235,6 +235,7 @@ static void kvm_cpu_instance_init(CPUState *cs) } static const KVMCPUOps x86_kvm_cpu_ops = { + .pre_run = x86_kvm_pre_run, }; 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 da922f72d71..e9bcda70dac 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -5898,7 +5898,7 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) return ret; } -void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) +void x86_kvm_pre_run(CPUState *cpu, struct kvm_run *run) { X86CPU *x86_cpu = X86_CPU(cpu); CPUX86State *env = &x86_cpu->env; diff --git a/target/loongarch/kvm/kvm.c b/target/loongarch/kvm/kvm.c index 4bc08f195ed..b8fb2094062 100644 --- a/target/loongarch/kvm/kvm.c +++ b/target/loongarch/kvm/kvm.c @@ -1517,10 +1517,6 @@ int kvm_arch_irqchip_create(KVMState *s) return kvm_check_extension(s, KVM_CAP_DEVICE_CTRL); } -void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) -{ -} - MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) { return MEMTXATTRS_UNSPECIFIED; diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 8e9328beeb9..17b16e33881 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -1336,10 +1336,6 @@ int kvmppc_set_interrupt(PowerPCCPU *cpu, int irq, int level) return 0; } -void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) -{ -} - MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) { return MEMTXATTRS_UNSPECIFIED; diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c index b3fa0548c8a..8575e673811 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -1640,10 +1640,6 @@ int kvm_arch_process_async_events(CPUState *cs) return 0; } -void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run) -{ -} - MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) { return MEMTXATTRS_UNSPECIFIED; diff --git a/target/s390x/kvm/kvm.c b/target/s390x/kvm/kvm.c index 69e49b7d151..827816e5b98 100644 --- a/target/s390x/kvm/kvm.c +++ b/target/s390x/kvm/kvm.c @@ -984,10 +984,6 @@ void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg) } } -void kvm_arch_pre_run(CPUState *cpu, struct kvm_run *run) -{ -} - MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run) { return MEMTXATTRS_UNSPECIFIED; -- 2.47.3