Skip to content

Commit 96316a0

Browse files
sean-jcbonzini
authored andcommitted
KVM: x86/mmu: Drop @slot param from exported/external page-track APIs
Refactor KVM's exported/external page-track, a.k.a. write-track, APIs to take only the gfn and do the required memslot lookup in KVM proper. Forcing users of the APIs to get the memslot unnecessarily bleeds KVM internals into KVMGT and complicates usage of the APIs. No functional change intended. 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-28-seanjc@google.com Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 427c76a commit 96316a0

File tree

5 files changed

+80
-58
lines changed

5 files changed

+80
-58
lines changed

arch/x86/include/asm/kvm_page_track.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,6 @@
44

55
#include <linux/kvm_types.h>
66

7-
void kvm_write_track_add_gfn(struct kvm *kvm,
8-
struct kvm_memory_slot *slot, gfn_t gfn);
9-
void kvm_write_track_remove_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
10-
gfn_t gfn);
11-
127
#ifdef CONFIG_KVM_EXTERNAL_WRITE_TRACKING
138
/*
149
* The notifier represented by @kvm_page_track_notifier_node is linked into
@@ -55,6 +50,8 @@ kvm_page_track_register_notifier(struct kvm *kvm,
5550
void
5651
kvm_page_track_unregister_notifier(struct kvm *kvm,
5752
struct kvm_page_track_notifier_node *n);
53+
int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn);
54+
int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn);
5855
#else
5956
/*
6057
* Allow defining a node in a structure even if page tracking is disabled, e.g.

arch/x86/kvm/mmu/mmu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ static void account_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
831831

832832
/* the non-leaf shadow pages are keeping readonly. */
833833
if (sp->role.level > PG_LEVEL_4K)
834-
return kvm_write_track_add_gfn(kvm, slot, gfn);
834+
return __kvm_write_track_add_gfn(kvm, slot, gfn);
835835

836836
kvm_mmu_gfn_disallow_lpage(slot, gfn);
837837

@@ -877,7 +877,7 @@ static void unaccount_shadowed(struct kvm *kvm, struct kvm_mmu_page *sp)
877877
slots = kvm_memslots_for_spte_role(kvm, sp->role);
878878
slot = __gfn_to_memslot(slots, gfn);
879879
if (sp->role.level > PG_LEVEL_4K)
880-
return kvm_write_track_remove_gfn(kvm, slot, gfn);
880+
return __kvm_write_track_remove_gfn(kvm, slot, gfn);
881881

882882
kvm_mmu_gfn_allow_lpage(slot, gfn);
883883
}

arch/x86/kvm/mmu/page_track.c

Lines changed: 63 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,8 @@ static void update_gfn_write_track(struct kvm_memory_slot *slot, gfn_t gfn,
7474
slot->arch.gfn_write_track[index] += count;
7575
}
7676

77-
/*
78-
* add guest page to the tracking pool so that corresponding access on that
79-
* page will be intercepted.
80-
*
81-
* @kvm: the guest instance we are interested in.
82-
* @slot: the @gfn belongs to.
83-
* @gfn: the guest page.
84-
*/
85-
void kvm_write_track_add_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
86-
gfn_t gfn)
77+
void __kvm_write_track_add_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
78+
gfn_t gfn)
8779
{
8880
lockdep_assert_held_write(&kvm->mmu_lock);
8981

@@ -104,18 +96,9 @@ void kvm_write_track_add_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
10496
if (kvm_mmu_slot_gfn_write_protect(kvm, slot, gfn, PG_LEVEL_4K))
10597
kvm_flush_remote_tlbs(kvm);
10698
}
107-
EXPORT_SYMBOL_GPL(kvm_write_track_add_gfn);
10899

109-
/*
110-
* remove the guest page from the tracking pool which stops the interception
111-
* of corresponding access on that page.
112-
*
113-
* @kvm: the guest instance we are interested in.
114-
* @slot: the @gfn belongs to.
115-
* @gfn: the guest page.
116-
*/
117-
void kvm_write_track_remove_gfn(struct kvm *kvm,
118-
struct kvm_memory_slot *slot, gfn_t gfn)
100+
void __kvm_write_track_remove_gfn(struct kvm *kvm,
101+
struct kvm_memory_slot *slot, gfn_t gfn)
119102
{
120103
lockdep_assert_held_write(&kvm->mmu_lock);
121104

@@ -133,7 +116,6 @@ void kvm_write_track_remove_gfn(struct kvm *kvm,
133116
*/
134117
kvm_mmu_gfn_allow_lpage(slot, gfn);
135118
}
136-
EXPORT_SYMBOL_GPL(kvm_write_track_remove_gfn);
137119

138120
/*
139121
* check if the corresponding access on the specified guest page is tracked.
@@ -257,4 +239,63 @@ void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot)
257239
srcu_read_unlock(&head->track_srcu, idx);
258240
}
259241

242+
/*
243+
* add guest page to the tracking pool so that corresponding access on that
244+
* page will be intercepted.
245+
*
246+
* @kvm: the guest instance we are interested in.
247+
* @gfn: the guest page.
248+
*/
249+
int kvm_write_track_add_gfn(struct kvm *kvm, gfn_t gfn)
250+
{
251+
struct kvm_memory_slot *slot;
252+
int idx;
253+
254+
idx = srcu_read_lock(&kvm->srcu);
255+
256+
slot = gfn_to_memslot(kvm, gfn);
257+
if (!slot) {
258+
srcu_read_unlock(&kvm->srcu, idx);
259+
return -EINVAL;
260+
}
261+
262+
write_lock(&kvm->mmu_lock);
263+
__kvm_write_track_add_gfn(kvm, slot, gfn);
264+
write_unlock(&kvm->mmu_lock);
265+
266+
srcu_read_unlock(&kvm->srcu, idx);
267+
268+
return 0;
269+
}
270+
EXPORT_SYMBOL_GPL(kvm_write_track_add_gfn);
271+
272+
/*
273+
* remove the guest page from the tracking pool which stops the interception
274+
* of corresponding access on that page.
275+
*
276+
* @kvm: the guest instance we are interested in.
277+
* @gfn: the guest page.
278+
*/
279+
int kvm_write_track_remove_gfn(struct kvm *kvm, gfn_t gfn)
280+
{
281+
struct kvm_memory_slot *slot;
282+
int idx;
283+
284+
idx = srcu_read_lock(&kvm->srcu);
285+
286+
slot = gfn_to_memslot(kvm, gfn);
287+
if (!slot) {
288+
srcu_read_unlock(&kvm->srcu, idx);
289+
return -EINVAL;
290+
}
291+
292+
write_lock(&kvm->mmu_lock);
293+
__kvm_write_track_remove_gfn(kvm, slot, gfn);
294+
write_unlock(&kvm->mmu_lock);
295+
296+
srcu_read_unlock(&kvm->srcu, idx);
297+
298+
return 0;
299+
}
300+
EXPORT_SYMBOL_GPL(kvm_write_track_remove_gfn);
260301
#endif

arch/x86/kvm/mmu/page_track.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ int kvm_page_track_create_memslot(struct kvm *kvm,
1515
struct kvm_memory_slot *slot,
1616
unsigned long npages);
1717

18+
void __kvm_write_track_add_gfn(struct kvm *kvm, struct kvm_memory_slot *slot,
19+
gfn_t gfn);
20+
void __kvm_write_track_remove_gfn(struct kvm *kvm,
21+
struct kvm_memory_slot *slot, gfn_t gfn);
22+
1823
bool kvm_gfn_is_write_tracked(struct kvm *kvm,
1924
const struct kvm_memory_slot *slot, gfn_t gfn);
2025

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

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,56 +1546,35 @@ static struct mdev_driver intel_vgpu_mdev_driver = {
15461546

15471547
int intel_gvt_page_track_add(struct intel_vgpu *info, u64 gfn)
15481548
{
1549-
struct kvm *kvm = info->vfio_device.kvm;
1550-
struct kvm_memory_slot *slot;
1551-
int idx;
1549+
int r;
15521550

15531551
if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, info->status))
15541552
return -ESRCH;
15551553

15561554
if (kvmgt_gfn_is_write_protected(info, gfn))
15571555
return 0;
15581556

1559-
idx = srcu_read_lock(&kvm->srcu);
1560-
slot = gfn_to_memslot(kvm, gfn);
1561-
if (!slot) {
1562-
srcu_read_unlock(&kvm->srcu, idx);
1563-
return -EINVAL;
1564-
}
1565-
1566-
write_lock(&kvm->mmu_lock);
1567-
kvm_write_track_add_gfn(kvm, slot, gfn);
1568-
write_unlock(&kvm->mmu_lock);
1569-
1570-
srcu_read_unlock(&kvm->srcu, idx);
1557+
r = kvm_write_track_add_gfn(info->vfio_device.kvm, gfn);
1558+
if (r)
1559+
return r;
15711560

15721561
kvmgt_protect_table_add(info, gfn);
15731562
return 0;
15741563
}
15751564

15761565
int intel_gvt_page_track_remove(struct intel_vgpu *info, u64 gfn)
15771566
{
1578-
struct kvm *kvm = info->vfio_device.kvm;
1579-
struct kvm_memory_slot *slot;
1580-
int idx;
1567+
int r;
15811568

15821569
if (!test_bit(INTEL_VGPU_STATUS_ATTACHED, info->status))
15831570
return -ESRCH;
15841571

15851572
if (!kvmgt_gfn_is_write_protected(info, gfn))
15861573
return 0;
15871574

1588-
idx = srcu_read_lock(&kvm->srcu);
1589-
slot = gfn_to_memslot(kvm, gfn);
1590-
if (!slot) {
1591-
srcu_read_unlock(&kvm->srcu, idx);
1592-
return -EINVAL;
1593-
}
1594-
1595-
write_lock(&kvm->mmu_lock);
1596-
kvm_write_track_remove_gfn(kvm, slot, gfn);
1597-
write_unlock(&kvm->mmu_lock);
1598-
srcu_read_unlock(&kvm->srcu, idx);
1575+
r = kvm_write_track_remove_gfn(info->vfio_device.kvm, gfn);
1576+
if (r)
1577+
return r;
15991578

16001579
kvmgt_protect_table_del(info, gfn);
16011580
return 0;

0 commit comments

Comments
 (0)