Skip to content

Commit f22b1e8

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86/mmu: Handle KVM bookkeeping in page-track APIs, not callers
Get/put references to KVM when a page-track notifier is (un)registered instead of relying on the caller to do so. Forcing the caller to do the bookkeeping is unnecessary and adds one more thing for users to get wrong, e.g. see commit 9ed1fde ("drm/i915/gvt: Get reference to KVM iff attachment to VM is successful"). Reviewed-by: Yan Zhao <yan.y.zhao@intel.com> Tested-by: Yongwei Ma <yongwei.ma@intel.com> Link: https://lore.kernel.org/r/20230729013535.1070024-29-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 96316a0 commit f22b1e8

File tree

3 files changed

+24
-22
lines changed

3 files changed

+24
-22
lines changed

arch/x86/include/asm/kvm_page_track.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,11 @@ struct kvm_page_track_notifier_node {
4444
struct kvm_page_track_notifier_node *node);
4545
};
4646

47-
void
48-
kvm_page_track_register_notifier(struct kvm *kvm,
49-
struct kvm_page_track_notifier_node *n);
50-
void
51-
kvm_page_track_unregister_notifier(struct kvm *kvm,
52-
struct kvm_page_track_notifier_node *n);
47+
int kvm_page_track_register_notifier(struct kvm *kvm,
48+
struct kvm_page_track_notifier_node *n);
49+
void kvm_page_track_unregister_notifier(struct kvm *kvm,
50+
struct kvm_page_track_notifier_node *n);
51+
5352
int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn);
5453
int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn);
5554
#else

arch/x86/kvm/mmu/page_track.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -157,27 +157,31 @@ int kvm_page_track_init(struct kvm *kvm)
157157
* register the notifier so that event interception for the tracked guest
158158
* pages can be received.
159159
*/
160-
void
161-
kvm_page_track_register_notifier(struct kvm *kvm,
162-
struct kvm_page_track_notifier_node *n)
160+
int kvm_page_track_register_notifier(struct kvm *kvm,
161+
struct kvm_page_track_notifier_node *n)
163162
{
164163
struct kvm_page_track_notifier_head *head;
165164

165+
if (!kvm || kvm->mm != current->mm)
166+
return -ESRCH;
167+
168+
kvm_get_kvm(kvm);
169+
166170
head = &kvm->arch.track_notifier_head;
167171

168172
write_lock(&kvm->mmu_lock);
169173
hlist_add_head_rcu(&n->node, &head->track_notifier_list);
170174
write_unlock(&kvm->mmu_lock);
175+
return 0;
171176
}
172177
EXPORT_SYMBOL_GPL(kvm_page_track_register_notifier);
173178

174179
/*
175180
* stop receiving the event interception. It is the opposed operation of
176181
* kvm_page_track_register_notifier().
177182
*/
178-
void
179-
kvm_page_track_unregister_notifier(struct kvm *kvm,
180-
struct kvm_page_track_notifier_node *n)
183+
void kvm_page_track_unregister_notifier(struct kvm *kvm,
184+
struct kvm_page_track_notifier_node *n)
181185
{
182186
struct kvm_page_track_notifier_head *head;
183187

@@ -187,6 +191,8 @@ kvm_page_track_unregister_notifier(struct kvm *kvm,
187191
hlist_del_rcu(&n->node);
188192
write_unlock(&kvm->mmu_lock);
189193
synchronize_srcu(&head->track_srcu);
194+
195+
kvm_put_kvm(kvm);
190196
}
191197
EXPORT_SYMBOL_GPL(kvm_page_track_unregister_notifier);
192198

drivers/gpu/drm/i915/gvt/kvmgt.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -654,21 +654,19 @@ static bool __kvmgt_vgpu_exist(struct intel_vgpu *vgpu)
654654
static int intel_vgpu_open_device(struct vfio_device *vfio_dev)
655655
{
656656
struct intel_vgpu *vgpu = vfio_dev_to_vgpu(vfio_dev);
657-
658-
if (!vgpu->vfio_device.kvm ||
659-
vgpu->vfio_device.kvm->mm != current->mm) {
660-
gvt_vgpu_err("KVM is required to use Intel vGPU\n");
661-
return -ESRCH;
662-
}
657+
int ret;
663658

664659
if (__kvmgt_vgpu_exist(vgpu))
665660
return -EEXIST;
666661

667662
vgpu->track_node.track_write = kvmgt_page_track_write;
668663
vgpu->track_node.track_remove_region = kvmgt_page_track_remove_region;
669-
kvm_get_kvm(vgpu->vfio_device.kvm);
670-
kvm_page_track_register_notifier(vgpu->vfio_device.kvm,
671-
&vgpu->track_node);
664+
ret = kvm_page_track_register_notifier(vgpu->vfio_device.kvm,
665+
&vgpu->track_node);
666+
if (ret) {
667+
gvt_vgpu_err("KVM is required to use Intel vGPU\n");
668+
return ret;
669+
}
672670

673671
set_bit(INTEL_VGPU_STATUS_ATTACHED, vgpu->status);
674672

@@ -703,7 +701,6 @@ static void intel_vgpu_close_device(struct vfio_device *vfio_dev)
703701

704702
kvm_page_track_unregister_notifier(vgpu->vfio_device.kvm,
705703
&vgpu->track_node);
706-
kvm_put_kvm(vgpu->vfio_device.kvm);
707704

708705
kvmgt_protect_table_destroy(vgpu);
709706
gvt_cache_destroy(vgpu);

0 commit comments

Comments
 (0)