Skip to content

Commit d0d9612

Browse files
sean-jcbonzini
authored andcommitted
KVM: Use enum to track if cached PFN will be used in guest and/or host
Replace the guest_uses_pa and kernel_map booleans in the PFN cache code with a unified enum/bitmask. Using explicit names makes it easier to review and audit call sites. Opportunistically add a WARN to prevent passing garbage; instantating a cache without declaring its usage is either buggy or pointless. Signed-off-by: Sean Christopherson <seanjc@google.com> Signed-off-by: David Woodhouse <dwmw@amazon.co.uk> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Message-Id: <20220303154127.202856-2-dwmw2@infradead.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
1 parent 4a9e7b9 commit d0d9612

4 files changed

Lines changed: 24 additions & 18 deletions

File tree

arch/x86/kvm/xen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn)
3939
}
4040

4141
do {
42-
ret = kvm_gfn_to_pfn_cache_init(kvm, gpc, NULL, false, true,
42+
ret = kvm_gfn_to_pfn_cache_init(kvm, gpc, NULL, KVM_HOST_USES_PFN,
4343
gpa, PAGE_SIZE, false);
4444
if (ret)
4545
goto out;

include/linux/kvm_host.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,11 +1231,12 @@ void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
12311231
* @gpc: struct gfn_to_pfn_cache object.
12321232
* @vcpu: vCPU to be used for marking pages dirty and to be woken on
12331233
* invalidation.
1234-
* @guest_uses_pa: indicates that the resulting host physical PFN is used while
1235-
* @vcpu is IN_GUEST_MODE; invalidations of the cache from MMU
1236-
* notifiers (but not for KVM memslot changes!) will also force
1237-
* @vcpu to exit the guest to refresh the cache.
1238-
* @kernel_map: requests a kernel virtual mapping (kmap / memremap).
1234+
* @usage: indicates if the resulting host physical PFN is used while
1235+
* the @vcpu is IN_GUEST_MODE (in which case invalidation of
1236+
* the cache from MMU notifiers---but not for KVM memslot
1237+
* changes!---will also force @vcpu to exit the guest and
1238+
* refresh the cache); and/or if the PFN used directly
1239+
* by KVM (and thus needs a kernel virtual mapping).
12391240
* @gpa: guest physical address to map.
12401241
* @len: sanity check; the range being access must fit a single page.
12411242
* @dirty: mark the cache dirty immediately.
@@ -1250,9 +1251,8 @@ void kvm_vcpu_mark_page_dirty(struct kvm_vcpu *vcpu, gfn_t gfn);
12501251
* accessing the target page.
12511252
*/
12521253
int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
1253-
struct kvm_vcpu *vcpu, bool guest_uses_pa,
1254-
bool kernel_map, gpa_t gpa, unsigned long len,
1255-
bool dirty);
1254+
struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
1255+
gpa_t gpa, unsigned long len, bool dirty);
12561256

12571257
/**
12581258
* kvm_gfn_to_pfn_cache_check - check validity of a gfn_to_pfn_cache.

include/linux/kvm_types.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct kvm_memslots;
1818

1919
enum kvm_mr_change;
2020

21+
#include <linux/bits.h>
2122
#include <linux/types.h>
2223
#include <linux/spinlock_types.h>
2324

@@ -46,6 +47,12 @@ typedef u64 hfn_t;
4647

4748
typedef hfn_t kvm_pfn_t;
4849

50+
enum pfn_cache_usage {
51+
KVM_GUEST_USES_PFN = BIT(0),
52+
KVM_HOST_USES_PFN = BIT(1),
53+
KVM_GUEST_AND_HOST_USE_PFN = KVM_GUEST_USES_PFN | KVM_HOST_USES_PFN,
54+
};
55+
4956
struct gfn_to_hva_cache {
5057
u64 generation;
5158
gpa_t gpa;
@@ -64,11 +71,10 @@ struct gfn_to_pfn_cache {
6471
rwlock_t lock;
6572
void *khva;
6673
kvm_pfn_t pfn;
74+
enum pfn_cache_usage usage;
6775
bool active;
6876
bool valid;
6977
bool dirty;
70-
bool kernel_map;
71-
bool guest_uses_pa;
7278
};
7379

7480
#ifdef KVM_ARCH_NR_OBJS_PER_MEMORY_CACHE

virt/kvm/pfncache.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void gfn_to_pfn_cache_invalidate_start(struct kvm *kvm, unsigned long start,
4242
* If a guest vCPU could be using the physical address,
4343
* it needs to be forced out of guest mode.
4444
*/
45-
if (gpc->guest_uses_pa) {
45+
if (gpc->usage & KVM_GUEST_USES_PFN) {
4646
if (!evict_vcpus) {
4747
evict_vcpus = true;
4848
bitmap_zero(vcpu_bitmap, KVM_MAX_VCPUS);
@@ -224,7 +224,7 @@ int kvm_gfn_to_pfn_cache_refresh(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
224224
goto map_done;
225225
}
226226

227-
if (gpc->kernel_map) {
227+
if (gpc->usage & KVM_HOST_USES_PFN) {
228228
if (new_pfn == old_pfn) {
229229
new_khva = old_khva;
230230
old_pfn = KVM_PFN_ERR_FAULT;
@@ -304,19 +304,19 @@ EXPORT_SYMBOL_GPL(kvm_gfn_to_pfn_cache_unmap);
304304

305305

306306
int kvm_gfn_to_pfn_cache_init(struct kvm *kvm, struct gfn_to_pfn_cache *gpc,
307-
struct kvm_vcpu *vcpu, bool guest_uses_pa,
308-
bool kernel_map, gpa_t gpa, unsigned long len,
309-
bool dirty)
307+
struct kvm_vcpu *vcpu, enum pfn_cache_usage usage,
308+
gpa_t gpa, unsigned long len, bool dirty)
310309
{
310+
WARN_ON_ONCE(!usage || (usage & KVM_GUEST_AND_HOST_USE_PFN) != usage);
311+
311312
if (!gpc->active) {
312313
rwlock_init(&gpc->lock);
313314

314315
gpc->khva = NULL;
315316
gpc->pfn = KVM_PFN_ERR_FAULT;
316317
gpc->uhva = KVM_HVA_ERR_BAD;
317318
gpc->vcpu = vcpu;
318-
gpc->kernel_map = kernel_map;
319-
gpc->guest_uses_pa = guest_uses_pa;
319+
gpc->usage = usage;
320320
gpc->valid = false;
321321
gpc->active = true;
322322

0 commit comments

Comments
 (0)