From fe6737c5ba1aed024b91f7797bcfaf54f157c02c Mon Sep 17 00:00:00 2001 From: Fuad Tabba Date: Thu, 29 Sep 2022 09:43:35 +0100 Subject: [PATCH] ANDROID: KVM: arm64: Introduce gfn_to_memslot_prot() Returns the memslot and whether it's writable without requiring a userspace address at the host. The userspace address isn't needed to get this information. Future patches, where the userspace address might not be known, would need access to the memslot and whether it's writeable. No functional change intended. Bug: 357781595 Change-Id: I490c6d41b19825e0a8d05e3a5af660ce31a894d4 Signed-off-by: Fuad Tabba --- include/linux/kvm_host.h | 1 + virt/kvm/kvm_main.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 45be36e5285f..783956133723 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -1305,6 +1305,7 @@ int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc, int kvm_clear_guest(struct kvm *kvm, gpa_t gpa, unsigned long len); struct kvm_memory_slot *gfn_to_memslot(struct kvm *kvm, gfn_t gfn); +struct kvm_memory_slot *gfn_to_memslot_prot(struct kvm *kvm, gfn_t gfn, bool *writable); bool kvm_is_visible_gfn(struct kvm *kvm, gfn_t gfn); bool kvm_vcpu_is_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn); unsigned long kvm_host_page_size(struct kvm_vcpu *vcpu, gfn_t gfn); diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 6ca7a1045bbb..7ae70cd8370b 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2673,6 +2673,28 @@ static bool memslot_is_readonly(const struct kvm_memory_slot *slot) return slot->flags & KVM_MEM_READONLY; } +/* + * Return the memslot of a @gfn and the R/W attribute if slot is valid, or NULL + * if slot is not valid. + * + * @slot: the kvm_memory_slot which contains @gfn + * @gfn: the gfn to be translated + * @writable: used to return the read/write attribute of the @slot if the hva + * is valid and @writable is not NULL + */ +struct kvm_memory_slot *gfn_to_memslot_prot(struct kvm *kvm, gfn_t gfn, bool *writable) +{ + struct kvm_memory_slot *slot = gfn_to_memslot(kvm, gfn); + + if (!slot || slot->flags & KVM_MEMSLOT_INVALID) + return NULL; + + if (writable) + *writable = !memslot_is_readonly(slot); + + return slot; +} + static unsigned long __gfn_to_hva_many(const struct kvm_memory_slot *slot, gfn_t gfn, gfn_t *nr_pages, bool write) {