Skip to content

Commit 9eb8ca0

Browse files
dmatlackbonzini
authored andcommitted
KVM: Obey kvm.halt_poll_ns in VMs not using KVM_CAP_HALT_POLL
Obey kvm.halt_poll_ns in VMs not using KVM_CAP_HALT_POLL on every halt, rather than just sampling the module parameter when the VM is first created. This restore the original behavior of kvm.halt_poll_ns for VMs that have not opted into KVM_CAP_HALT_POLL. Notably, this change restores the ability for admins to disable or change the maximum halt-polling time system wide for VMs not using KVM_CAP_HALT_POLL. Reported-by: Christian Borntraeger <borntraeger@de.ibm.com> Fixes: acd0578 ("kvm: add capability for halt polling") Signed-off-by: David Matlack <dmatlack@google.com> Message-Id: <20221117001657.1067231-4-dmatlack@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 175d5dc commit 9eb8ca0

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

include/linux/kvm_host.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,7 @@ struct kvm {
776776
struct srcu_struct srcu;
777777
struct srcu_struct irq_srcu;
778778
pid_t userspace_pid;
779+
bool override_halt_poll_ns;
779780
unsigned int max_halt_poll_ns;
780781
u32 dirty_ring_size;
781782
bool vm_bugged;

virt/kvm/kvm_main.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,8 +1198,6 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
11981198
goto out_err_no_arch_destroy_vm;
11991199
}
12001200

1201-
kvm->max_halt_poll_ns = halt_poll_ns;
1202-
12031201
r = kvm_arch_init_vm(kvm, type);
12041202
if (r)
12051203
goto out_err_no_arch_destroy_vm;
@@ -3482,7 +3480,20 @@ static inline void update_halt_poll_stats(struct kvm_vcpu *vcpu, ktime_t start,
34823480

34833481
static unsigned int kvm_vcpu_max_halt_poll_ns(struct kvm_vcpu *vcpu)
34843482
{
3485-
return READ_ONCE(vcpu->kvm->max_halt_poll_ns);
3483+
struct kvm *kvm = vcpu->kvm;
3484+
3485+
if (kvm->override_halt_poll_ns) {
3486+
/*
3487+
* Ensure kvm->max_halt_poll_ns is not read before
3488+
* kvm->override_halt_poll_ns.
3489+
*
3490+
* Pairs with the smp_wmb() when enabling KVM_CAP_HALT_POLL.
3491+
*/
3492+
smp_rmb();
3493+
return READ_ONCE(kvm->max_halt_poll_ns);
3494+
}
3495+
3496+
return READ_ONCE(halt_poll_ns);
34863497
}
34873498

34883499
/*
@@ -4592,6 +4603,16 @@ static int kvm_vm_ioctl_enable_cap_generic(struct kvm *kvm,
45924603
return -EINVAL;
45934604

45944605
kvm->max_halt_poll_ns = cap->args[0];
4606+
4607+
/*
4608+
* Ensure kvm->override_halt_poll_ns does not become visible
4609+
* before kvm->max_halt_poll_ns.
4610+
*
4611+
* Pairs with the smp_rmb() in kvm_vcpu_max_halt_poll_ns().
4612+
*/
4613+
smp_wmb();
4614+
kvm->override_halt_poll_ns = true;
4615+
45954616
return 0;
45964617
}
45974618
case KVM_CAP_DIRTY_LOG_RING:

0 commit comments

Comments
 (0)