virt/kvm/pfncache.c
Source file repositories/reference/linux-study-clean/virt/kvm/pfncache.c
File Facts
- System
- Linux kernel
- Corpus path
virt/kvm/pfncache.c- Extension
.c- Size
- 12125 bytes
- Lines
- 485
- Domain
- Kernel Services
- Bucket
- virt
- Inferred role
- Kernel Services: implementation source
- Status
- source implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kvm_host.hlinux/kvm.hlinux/highmem.hlinux/module.hlinux/errno.hkvm_mm.h
Detected Declarations
function gfn_to_pfn_cache_invalidate_startfunction kvm_gpc_is_valid_lenfunction kvm_gpc_checkfunction gpc_unmapfunction mmu_notifier_retry_cachefunction hva_to_pfn_retryfunction __kvm_gpc_refreshfunction kvm_gpc_refreshfunction kvm_gpc_initfunction __kvm_gpc_activatefunction kvm_gpc_activatefunction kvm_gpc_activate_hvafunction kvm_gpc_deactivate
Annotated Snippet
if (new_pfn != KVM_PFN_ERR_FAULT) {
/*
* Keep the mapping if the previous iteration reused
* the existing mapping and didn't create a new one.
*/
if (new_khva != old_khva)
gpc_unmap(new_pfn, new_khva);
kvm_release_page_unused(page);
cond_resched();
}
new_pfn = hva_to_pfn(&kfp);
if (is_error_noslot_pfn(new_pfn))
goto out_error;
/*
* Obtain a new kernel mapping if KVM itself will access the
* pfn. Note, kmap() and memremap() can both sleep, so this
* too must be done outside of gpc->lock!
*/
if (new_pfn == gpc->pfn)
new_khva = old_khva;
else
new_khva = gpc_map(new_pfn);
if (!new_khva) {
kvm_release_page_unused(page);
goto out_error;
}
write_lock_irq(&gpc->lock);
/*
* Other tasks must wait for _this_ refresh to complete before
* attempting to refresh.
*/
WARN_ON_ONCE(gpc->valid);
} while (mmu_notifier_retry_cache(gpc->kvm, mmu_seq));
gpc->valid = true;
gpc->pfn = new_pfn;
gpc->khva = new_khva + offset_in_page(gpc->uhva);
/*
* Put the reference to the _new_ page. The page is now tracked by the
* cache and can be safely migrated, swapped, etc... as the cache will
* invalidate any mappings in response to relevant mmu_notifier events.
*/
kvm_release_page_clean(page);
return 0;
out_error:
write_lock_irq(&gpc->lock);
return -EFAULT;
}
static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long uhva)
{
unsigned long page_offset;
bool unmap_old = false;
unsigned long old_uhva;
kvm_pfn_t old_pfn;
bool hva_change = false;
void *old_khva;
int ret;
/* Either gpa or uhva must be valid, but not both */
if (WARN_ON_ONCE(kvm_is_error_gpa(gpa) == kvm_is_error_hva(uhva)))
return -EINVAL;
lockdep_assert_held(&gpc->refresh_lock);
write_lock_irq(&gpc->lock);
if (!gpc->active) {
ret = -EINVAL;
goto out_unlock;
}
old_pfn = gpc->pfn;
old_khva = (void *)PAGE_ALIGN_DOWN((uintptr_t)gpc->khva);
old_uhva = PAGE_ALIGN_DOWN(gpc->uhva);
if (kvm_is_error_gpa(gpa)) {
page_offset = offset_in_page(uhva);
Annotation
- Immediate include surface: `linux/kvm_host.h`, `linux/kvm.h`, `linux/highmem.h`, `linux/module.h`, `linux/errno.h`, `kvm_mm.h`.
- Detected declarations: `function gfn_to_pfn_cache_invalidate_start`, `function kvm_gpc_is_valid_len`, `function kvm_gpc_check`, `function gpc_unmap`, `function mmu_notifier_retry_cache`, `function hva_to_pfn_retry`, `function __kvm_gpc_refresh`, `function kvm_gpc_refresh`, `function kvm_gpc_init`, `function __kvm_gpc_activate`.
- Atlas domain: Kernel Services / virt.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.