Skip to content

Commit f42e289

Browse files
sean-jcbonzini
authored andcommitted
KVM: Add support for read-only usage of gfn_to_page()
Rework gfn_to_page() to support read-only accesses so that it can be used by arm64 to get MTE tags out of guest memory. Opportunistically rewrite the comment to be even more stern about using gfn_to_page(), as there are very few scenarios where requiring a struct page is actually the right thing to do (though there are such scenarios). Add a FIXME to call out that KVM probably should be pinning pages, not just getting pages. Tested-by: Alex Bennée <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Tested-by: Dmitry Osipenko <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]> Message-ID: <[email protected]>
1 parent ce6bf70 commit f42e289

File tree

2 files changed

+14
-8
lines changed

2 files changed

+14
-8
lines changed

include/linux/kvm_host.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1213,7 +1213,12 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
12131213
int kvm_prefetch_pages(struct kvm_memory_slot *slot, gfn_t gfn,
12141214
struct page **pages, int nr_pages);
12151215

1216-
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
1216+
struct page *__gfn_to_page(struct kvm *kvm, gfn_t gfn, bool write);
1217+
static inline struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
1218+
{
1219+
return __gfn_to_page(kvm, gfn, true);
1220+
}
1221+
12171222
unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
12181223
unsigned long gfn_to_hva_prot(struct kvm *kvm, gfn_t gfn, bool *writable);
12191224
unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn);

virt/kvm/kvm_main.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3132,25 +3132,26 @@ int kvm_prefetch_pages(struct kvm_memory_slot *slot, gfn_t gfn,
31323132
EXPORT_SYMBOL_GPL(kvm_prefetch_pages);
31333133

31343134
/*
3135-
* Do not use this helper unless you are absolutely certain the gfn _must_ be
3136-
* backed by 'struct page'. A valid example is if the backing memslot is
3137-
* controlled by KVM. Note, if the returned page is valid, it's refcount has
3138-
* been elevated by gfn_to_pfn().
3135+
* Don't use this API unless you are absolutely, positively certain that KVM
3136+
* needs to get a struct page, e.g. to pin the page for firmware DMA.
3137+
*
3138+
* FIXME: Users of this API likely need to FOLL_PIN the page, not just elevate
3139+
* its refcount.
31393140
*/
3140-
struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn)
3141+
struct page *__gfn_to_page(struct kvm *kvm, gfn_t gfn, bool write)
31413142
{
31423143
struct page *refcounted_page = NULL;
31433144
struct kvm_follow_pfn kfp = {
31443145
.slot = gfn_to_memslot(kvm, gfn),
31453146
.gfn = gfn,
3146-
.flags = FOLL_WRITE,
3147+
.flags = write ? FOLL_WRITE : 0,
31473148
.refcounted_page = &refcounted_page,
31483149
};
31493150

31503151
(void)kvm_follow_pfn(&kfp);
31513152
return refcounted_page;
31523153
}
3153-
EXPORT_SYMBOL_GPL(gfn_to_page);
3154+
EXPORT_SYMBOL_GPL(__gfn_to_page);
31543155

31553156
int __kvm_vcpu_map(struct kvm_vcpu *vcpu, gfn_t gfn, struct kvm_host_map *map,
31563157
bool writable)

0 commit comments

Comments
 (0)