Doing a QOM cast each time we need KVMCPUOps is overkill, especially considering it is a single static assignment when we configure the accelerator. Cache the value on kvm_init_vcpu and use it. We also assert that anytime the system asks for KVMCPUOps it should be at a point we can honour the request. Signed-off-by: Alex Bennée --- include/accel/kvm/cpu-ops.h | 13 +++++++++---- include/hw/core/cpu.h | 3 +++ accel/kvm/kvm-all.c | 4 ++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/include/accel/kvm/cpu-ops.h b/include/accel/kvm/cpu-ops.h index d43bc845ad5..075bac1d494 100644 --- a/include/accel/kvm/cpu-ops.h +++ b/include/accel/kvm/cpu-ops.h @@ -156,11 +156,16 @@ DECLARE_CLASS_CHECKERS(KVMAccelCPUClass, KVM_ACCEL_CPU, TYPE_KVM_ACCEL_CPU) */ static inline const KVMCPUOps *kvm_get_cpu_ops(const CPUState *cpu) { - if (cpu->cc->accel_cpu) { - KVMAccelCPUClass *kacc = KVM_ACCEL_CPU_CLASS(cpu->cc->accel_cpu); - return kacc->cpu_ops; + if (cpu) { + if (cpu->kvm_cpu_ops) { + return cpu->kvm_cpu_ops; + } + if (cpu->cc->accel_cpu) { + KVMAccelCPUClass *kacc = KVM_ACCEL_CPU_CLASS(cpu->cc->accel_cpu); + return kacc->cpu_ops; + } } - return NULL; + g_assert_not_reached(); } #endif /* ACCEL_KVM_CPU_OPS_H */ diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index 456154df6f6..1e164036286 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -473,6 +473,8 @@ struct qemu_work_item; * ring is enabled. * @kvm_fetch_index: Keeps the index that we last fetched from the per-vCPU * dirty ring structure. + * @kvm_cpu_ops: Cached pointer to the KVMCPUOps table to avoid QOM lookups + * in the run loop. * * @neg_align: The CPUState is the common part of a concrete ArchCPU * which is allocated when an individual CPU instance is created. As @@ -554,6 +556,7 @@ struct CPUState { uint32_t kvm_fetch_index; uint64_t dirty_pages; int kvm_vcpu_stats_fd; + const struct KVMCPUOps *kvm_cpu_ops; /* Use by accel-block: CPU is executing an ioctl() */ QemuLockCnt in_ioctl_lock; diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 5189cdc6a01..041113ed9b5 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -746,6 +746,9 @@ int kvm_init_vcpu(CPUState *cpu, Error **errp) KVMState *s = kvm_state; int ret; + assert(ops); + cpu->kvm_cpu_ops = ops; + trace_kvm_init_vcpu(cpu->cpu_index, kvm_vcpu_id(cpu)); if (ops->pre_create_vcpu) { @@ -4111,6 +4114,7 @@ int kvm_on_sigbus(int code, void *addr) * we can only get action optional here. */ assert(code != BUS_MCEERR_AR); + assert(first_cpu); ops = kvm_get_cpu_ops(first_cpu); if (ops && ops->on_sigbus_vcpu) { ops->on_sigbus_vcpu(first_cpu, code, addr); -- 2.47.3