Just as in kvm-all.c, introduce per-vcpu QemuLockCnt to keep track when vcpus are executing an ioctl. Keep a per-vcpu lock to minimize cache line bouncing. The kvm listener will then use the lock to prevent new ioctls from running when modifying memslots. Signed-off-by: David Hildenbrand <david@xxxxxxxxxx> Signed-off-by: Emanuele Giuseppe Esposito <eesposit@xxxxxxxxxx> --- accel/kvm/kvm-all.c | 14 ++++++++++++++ hw/core/cpu-common.c | 2 ++ include/hw/core/cpu.h | 3 +++ 3 files changed, 19 insertions(+) diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 099d7bda56..48cdf1fecd 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -2811,6 +2811,18 @@ static void kvm_eat_signals(CPUState *cpu) } while (sigismember(&chkset, SIG_IPI)); } +static void kvm_cpu_set_in_ioctl(CPUState *cpu, bool in_ioctl) +{ + if (unlikely(qemu_mutex_iothread_locked())) { + return; + } + if (in_ioctl) { + qemu_lockcnt_inc(&cpu->in_ioctl_lock); + } else { + qemu_lockcnt_dec(&cpu->in_ioctl_lock); + } +} + static void kvm_set_in_ioctl(bool in_ioctl) { if (likely(qemu_mutex_iothread_locked())) { @@ -3049,7 +3061,9 @@ int kvm_vcpu_ioctl(CPUState *cpu, int type, ...) va_end(ap); trace_kvm_vcpu_ioctl(cpu->cpu_index, type, arg); + kvm_cpu_set_in_ioctl(cpu, true); ret = ioctl(cpu->kvm_fd, type, arg); + kvm_cpu_set_in_ioctl(cpu, false); if (ret == -1) { ret = -errno; } diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index f9fdd46b9d..8d6a4b1b65 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -237,6 +237,7 @@ static void cpu_common_initfn(Object *obj) cpu->nr_threads = 1; qemu_mutex_init(&cpu->work_mutex); + qemu_lockcnt_init(&cpu->in_ioctl_lock); QSIMPLEQ_INIT(&cpu->work_list); QTAILQ_INIT(&cpu->breakpoints); QTAILQ_INIT(&cpu->watchpoints); @@ -248,6 +249,7 @@ static void cpu_common_finalize(Object *obj) { CPUState *cpu = CPU(obj); + qemu_lockcnt_destroy(&cpu->in_ioctl_lock); qemu_mutex_destroy(&cpu->work_mutex); } diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h index f9b58773f7..07852b2a3c 100644 --- a/include/hw/core/cpu.h +++ b/include/hw/core/cpu.h @@ -397,6 +397,9 @@ struct CPUState { uint32_t kvm_fetch_index; uint64_t dirty_pages; + /* kvm only for now: CPU is in kvm_vcpu_ioctl() (esp. KVM_RUN) */ + QemuLockCnt in_ioctl_lock; + /* Used for events with 'vcpu' and *without* the 'disabled' properties */ DECLARE_BITMAP(trace_dstate_delayed, CPU_TRACE_DSTATE_MAX_EVENTS); DECLARE_BITMAP(trace_dstate, CPU_TRACE_DSTATE_MAX_EVENTS); -- 2.31.1