Skip to content

Commit 9f87791

Browse files
sean-jcdwmw2
authored andcommitted
KVM: Drop KVM's API to allow temporarily unmapping gfn=>pfn cache
Drop kvm_gpc_unmap() as it has no users and unclear requirements. The API was added as part of the original gfn_to_pfn_cache support, but its sole usage[*] was never merged. Fold the guts of kvm_gpc_unmap() into the deactivate path and drop the API. Omit acquiring refresh_lock as as concurrent calls to kvm_gpc_deactivate() are not allowed (this is not enforced, e.g. via lockdep. due to it being called during vCPU destruction). If/when temporary unmapping makes a comeback, the desirable behavior is likely to restrict temporary unmapping to vCPU-exclusive mappings and require the vcpu->mutex be held to serialize unmap. Use of the refresh_lock to protect unmapping was somewhat specuatively added by commit 93984f1 ("KVM: Fully serialize gfn=>pfn cache refresh via mutex") to guard against concurrent unmaps, but the primary use case of the temporary unmap, nested virtualization[*], doesn't actually need or want concurrent unmaps. [*] https://lore.kernel.org/all/[email protected] Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: David Woodhouse <[email protected]>
1 parent 0318f20 commit 9f87791

File tree

2 files changed

+16
-40
lines changed

2 files changed

+16
-40
lines changed

include/linux/kvm_host.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1333,18 +1333,6 @@ bool kvm_gpc_check(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long len);
13331333
*/
13341334
int kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long len);
13351335

1336-
/**
1337-
* kvm_gpc_unmap - temporarily unmap a gfn_to_pfn_cache.
1338-
*
1339-
* @kvm: pointer to kvm instance.
1340-
* @gpc: struct gfn_to_pfn_cache object.
1341-
*
1342-
* This unmaps the referenced page. The cache is left in the invalid state
1343-
* but at least the mapping from GPA to userspace HVA will remain cached
1344-
* and can be reused on a subsequent refresh.
1345-
*/
1346-
void kvm_gpc_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc);
1347-
13481336
/**
13491337
* kvm_gpc_deactivate - deactivate and unlink a gfn_to_pfn_cache.
13501338
*

virt/kvm/pfncache.c

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -333,33 +333,6 @@ int kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long len)
333333
}
334334
EXPORT_SYMBOL_GPL(kvm_gpc_refresh);
335335

336-
void kvm_gpc_unmap(struct kvm *kvm, struct gfn_to_pfn_cache *gpc)
337-
{
338-
void *old_khva;
339-
kvm_pfn_t old_pfn;
340-
341-
mutex_lock(&gpc->refresh_lock);
342-
write_lock_irq(&gpc->lock);
343-
344-
gpc->valid = false;
345-
346-
old_khva = gpc->khva - offset_in_page(gpc->khva);
347-
old_pfn = gpc->pfn;
348-
349-
/*
350-
* We can leave the GPA → uHVA map cache intact but the PFN
351-
* lookup will need to be redone even for the same page.
352-
*/
353-
gpc->khva = NULL;
354-
gpc->pfn = KVM_PFN_ERR_FAULT;
355-
356-
write_unlock_irq(&gpc->lock);
357-
mutex_unlock(&gpc->refresh_lock);
358-
359-
gpc_unmap_khva(old_pfn, old_khva);
360-
}
361-
EXPORT_SYMBOL_GPL(kvm_gpc_unmap);
362-
363336
void kvm_gpc_init(struct gfn_to_pfn_cache *gpc, struct kvm *kvm,
364337
struct kvm_vcpu *vcpu, enum pfn_cache_usage usage)
365338
{
@@ -405,6 +378,8 @@ EXPORT_SYMBOL_GPL(kvm_gpc_activate);
405378
void kvm_gpc_deactivate(struct gfn_to_pfn_cache *gpc)
406379
{
407380
struct kvm *kvm = gpc->kvm;
381+
kvm_pfn_t old_pfn;
382+
void *old_khva;
408383

409384
if (gpc->active) {
410385
/*
@@ -414,13 +389,26 @@ void kvm_gpc_deactivate(struct gfn_to_pfn_cache *gpc)
414389
*/
415390
write_lock_irq(&gpc->lock);
416391
gpc->active = false;
392+
gpc->valid = false;
393+
394+
/*
395+
* Leave the GPA => uHVA cache intact, it's protected by the
396+
* memslot generation. The PFN lookup needs to be redone every
397+
* time as mmu_notifier protection is lost when the cache is
398+
* removed from the VM's gpc_list.
399+
*/
400+
old_khva = gpc->khva - offset_in_page(gpc->khva);
401+
gpc->khva = NULL;
402+
403+
old_pfn = gpc->pfn;
404+
gpc->pfn = KVM_PFN_ERR_FAULT;
417405
write_unlock_irq(&gpc->lock);
418406

419407
spin_lock(&kvm->gpc_lock);
420408
list_del(&gpc->list);
421409
spin_unlock(&kvm->gpc_lock);
422410

423-
kvm_gpc_unmap(kvm, gpc);
411+
gpc_unmap_khva(old_pfn, old_khva);
424412
}
425413
}
426414
EXPORT_SYMBOL_GPL(kvm_gpc_deactivate);

0 commit comments

Comments
 (0)