arch/arm64/kvm/mmu.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/mmu.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/mmu.c- Extension
.c- Size
- 75532 bytes
- Lines
- 2792
- Domain
- Architecture Layer
- Bucket
- arch/arm64
- Inferred role
- Architecture Layer: implementation source
- Status
- source implementation candidate
Why This File Exists
CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/acpi.hlinux/mman.hlinux/kvm_host.hlinux/io.hlinux/hugetlb.hlinux/sched/signal.htrace/events/kvm.hasm/acpi.hasm/pgalloc.hasm/cacheflush.hasm/kvm_arm.hasm/kvm_mmu.hasm/kvm_pgtable.hasm/kvm_pkvm.hasm/kvm_asm.hasm/kvm_emulate.hasm/virt.htrace.h
Detected Declarations
struct hyp_shared_pfnstruct kvm_s2_fault_descstruct kvm_s2_fault_vma_infofunction __stage2_range_addr_endfunction stage2_range_addr_endfunction stage2_apply_rangefunction kvm_mmu_split_nr_page_tablesfunction need_split_memcache_topup_or_reschedfunction kvm_mmu_split_huge_pagesfunction memslot_is_loggingfunction kvm_arch_flush_remote_tlbsfunction kvm_arch_flush_remote_tlbs_rangefunction kvm_s2_free_pages_exactfunction stage2_free_unlinked_table_rcu_cbfunction stage2_free_unlinked_tablefunction kvm_host_get_pagefunction kvm_host_put_pagefunction kvm_s2_put_pagefunction kvm_host_page_countfunction kvm_host_pafunction clean_dcache_guest_pagefunction invalidate_icache_guest_pagefunction readsfunction kvm_stage2_unmap_rangefunction kvm_stage2_flush_rangefunction stage2_flush_memslotfunction stage2_flush_vmfunction free_hyp_pgdsfunction kvm_host_owns_hyp_mappingsfunction __create_hyp_mappingsfunction kvm_kaddr_to_physfunction share_pfn_hypfunction unshare_pfn_hypfunction kvm_share_hypfunction kvm_unshare_hypfunction create_hyp_mappingsfunction __hyp_alloc_private_va_rangefunction addressfunction __create_hyp_private_mappingfunction create_hyp_stackfunction create_hyp_io_mappingsfunction create_hyp_exec_mappingsfunction get_user_mapping_sizefunction kvm_init_ipa_rangefunction cond_reschedfunction kvm_stage2_destroyfunction kvm_init_stage2_mmufunction kvm_uninit_stage2_mmu
Annotated Snippet
struct hyp_shared_pfn {
u64 pfn;
int count;
struct rb_node node;
};
static DEFINE_MUTEX(hyp_shared_pfns_lock);
static struct rb_root hyp_shared_pfns = RB_ROOT;
static struct hyp_shared_pfn *find_shared_pfn(u64 pfn, struct rb_node ***node,
struct rb_node **parent)
{
struct hyp_shared_pfn *this;
*node = &hyp_shared_pfns.rb_node;
*parent = NULL;
while (**node) {
this = container_of(**node, struct hyp_shared_pfn, node);
*parent = **node;
if (this->pfn < pfn)
*node = &((**node)->rb_left);
else if (this->pfn > pfn)
*node = &((**node)->rb_right);
else
return this;
}
return NULL;
}
static int share_pfn_hyp(u64 pfn)
{
struct rb_node **node, *parent;
struct hyp_shared_pfn *this;
int ret = 0;
mutex_lock(&hyp_shared_pfns_lock);
this = find_shared_pfn(pfn, &node, &parent);
if (this) {
this->count++;
goto unlock;
}
this = kzalloc_obj(*this);
if (!this) {
ret = -ENOMEM;
goto unlock;
}
this->pfn = pfn;
this->count = 1;
rb_link_node(&this->node, parent, node);
rb_insert_color(&this->node, &hyp_shared_pfns);
ret = kvm_call_hyp_nvhe(__pkvm_host_share_hyp, pfn);
if (ret) {
rb_erase(&this->node, &hyp_shared_pfns);
kfree(this);
}
unlock:
mutex_unlock(&hyp_shared_pfns_lock);
return ret;
}
static int unshare_pfn_hyp(u64 pfn)
{
struct rb_node **node, *parent;
struct hyp_shared_pfn *this;
int ret = 0;
mutex_lock(&hyp_shared_pfns_lock);
this = find_shared_pfn(pfn, &node, &parent);
if (WARN_ON(!this)) {
ret = -ENOENT;
goto unlock;
}
if (this->count > 1) {
this->count--;
goto unlock;
}
ret = kvm_call_hyp_nvhe(__pkvm_host_unshare_hyp, pfn);
if (ret)
goto unlock;
rb_erase(&this->node, &hyp_shared_pfns);
kfree(this);
unlock:
mutex_unlock(&hyp_shared_pfns_lock);
Annotation
- Immediate include surface: `linux/acpi.h`, `linux/mman.h`, `linux/kvm_host.h`, `linux/io.h`, `linux/hugetlb.h`, `linux/sched/signal.h`, `trace/events/kvm.h`, `asm/acpi.h`.
- Detected declarations: `struct hyp_shared_pfn`, `struct kvm_s2_fault_desc`, `struct kvm_s2_fault_vma_info`, `function __stage2_range_addr_end`, `function stage2_range_addr_end`, `function stage2_apply_range`, `function kvm_mmu_split_nr_page_tables`, `function need_split_memcache_topup_or_resched`, `function kvm_mmu_split_huge_pages`, `function memslot_is_logging`.
- Atlas domain: Architecture Layer / arch/arm64.
- Implementation status: source implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- 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.