Skip to content

Commit

Permalink
KVM: x86: Take KVM's SRCU lock only if steal time update is needed
Browse files Browse the repository at this point in the history
Enter a SRCU critical section for a memslots lookup during steal time
update if and only if a steal time update is actually needed.  Taking
the lock can be avoided if steal time is disabled by the guest, or if
KVM knows it has already flagged the vCPU as being preempted.

Reword the comment to be more precise as to exactly why memslots will
be queried.

Signed-off-by: Sean Christopherson <seanjc@google.com>
Message-Id: <20210123000334.3123628-3-seanjc@google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Sean Christopherson authored and Paolo Bonzini committed Feb 4, 2021
1 parent 19979fb commit 15b51dc
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions arch/x86/kvm/x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -4014,39 +4014,41 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu)
{
struct kvm_host_map map;
struct kvm_steal_time *st;
int idx;

if (!(vcpu->arch.st.msr_val & KVM_MSR_ENABLED))
return;

if (vcpu->arch.st.preempted)
return;

/*
* Take the srcu lock as memslots will be accessed to check the gfn
* cache generation against the memslots generation.
*/
idx = srcu_read_lock(&vcpu->kvm->srcu);

if (kvm_map_gfn(vcpu, vcpu->arch.st.msr_val >> PAGE_SHIFT, &map,
&vcpu->arch.st.cache, true))
return;
goto out;

st = map.hva +
offset_in_page(vcpu->arch.st.msr_val & KVM_STEAL_VALID_BITS);

st->preempted = vcpu->arch.st.preempted = KVM_VCPU_PREEMPTED;

kvm_unmap_gfn(vcpu, &map, &vcpu->arch.st.cache, true, true);

out:
srcu_read_unlock(&vcpu->kvm->srcu, idx);
}

void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
{
int idx;

if (vcpu->preempted && !vcpu->arch.guest_state_protected)
vcpu->arch.preempted_in_kernel = !kvm_x86_ops.get_cpl(vcpu);

/*
* kvm_memslots() will be called by
* kvm_write_guest_offset_cached() so take the srcu lock.
*/
idx = srcu_read_lock(&vcpu->kvm->srcu);
kvm_steal_time_set_preempted(vcpu);
srcu_read_unlock(&vcpu->kvm->srcu, idx);
kvm_x86_ops.vcpu_put(vcpu);
vcpu->arch.last_host_tsc = rdtsc();
/*
Expand Down

0 comments on commit 15b51dc

Please sign in to comment.