arch/arm64/kvm/nested.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/nested.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/nested.c- Extension
.c- Size
- 50910 bytes
- Lines
- 2023
- 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.
- 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/bitfield.hlinux/kvm.hlinux/kvm_host.hasm/fixmap.hasm/kvm_arm.hasm/kvm_emulate.hasm/kvm_mmu.hasm/kvm_nested.hasm/sysreg.hsys_regs.h
Detected Declarations
struct vncr_tlbstruct s2_walk_infostruct s1e2_tlbi_scopefunction kvm_init_nestedfunction init_nested_s2_mmufunction kvm_vcpu_init_nestedfunction compute_fscfunction esr_s2_faultfunction get_ia_sizefunction check_base_s2_limitsfunction check_output_sizefunction read_guest_s2_descfunction swap_guest_s2_descfunction walk_nested_s2_pgdfunction has_tgran_2function fallback_tgran2_shiftfunction vtcr_to_tg0_pgshiftfunction vtcr_to_tg0_pgsizefunction setup_s2_walkfunction kvm_walk_nested_s2function ttl_to_sizefunction pgshift_level_to_ttlfunction get_guest_mapping_ttlfunction compute_tlb_inval_rangefunction kvm_s2_mmu_iterate_by_vmidfunction kvm_init_nested_s2_mmufunction kvm_vcpu_load_hw_mmufunction this_cpu_reset_vncr_fixmapfunction kvm_vcpu_put_hw_mmufunction kvm_s2_handle_perm_faultfunction kvm_inject_s2_faultfunction get_asid_by_regimefunction invalidate_vncrfunction yetfunction kvm_for_each_vncr_tlbfunction invalidate_vncr_vafunction kvm_for_each_vncr_tlbfunction compute_s1_tlbi_rangefunction kvm_handle_s1e2_tlbifunction kvm_nested_s2_wpfunction kvm_nested_s2_unmapfunction kvm_nested_s2_flushfunction kvm_arch_flush_shadow_allfunction typefunction read_vncr_el2function kvm_translate_vncrfunction scoped_guardfunction inject_vncr_perm
Annotated Snippet
struct vncr_tlb {
/* The guest's VNCR_EL2 */
u64 gva;
struct s1_walk_info wi;
struct s1_walk_result wr;
u64 hpa;
/* -1 when not mapped on a CPU */
int cpu;
/*
* true if the TLB is valid. Can only be changed with the
* mmu_lock held.
*/
bool valid;
};
/*
* Ratio of live shadow S2 MMU per vcpu. This is a trade-off between
* memory usage and potential number of different sets of S2 PTs in
* the guests. Running out of S2 MMUs only affects performance (we
* will invalidate them more often).
*/
#define S2_MMU_PER_VCPU 2
void kvm_init_nested(struct kvm *kvm)
{
kvm->arch.nested_mmus = NULL;
kvm->arch.nested_mmus_size = 0;
atomic_set(&kvm->arch.vncr_map_count, 0);
}
static int init_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
{
/*
* We only initialise the IPA range on the canonical MMU, which
* defines the contract between KVM and userspace on where the
* "hardware" is in the IPA space. This affects the validity of MMIO
* exits forwarded to userspace, for example.
*
* For nested S2s, we use the PARange as exposed to the guest, as it
* is allowed to use it at will to expose whatever memory map it
* wants to its own guests as it would be on real HW.
*/
return kvm_init_stage2_mmu(kvm, mmu, kvm_get_pa_bits(kvm));
}
int kvm_vcpu_init_nested(struct kvm_vcpu *vcpu)
{
struct kvm *kvm = vcpu->kvm;
struct kvm_s2_mmu *tmp;
int num_mmus, ret = 0;
if (test_bit(KVM_ARM_VCPU_HAS_EL2_E2H0, kvm->arch.vcpu_features) &&
!cpus_have_final_cap(ARM64_HAS_HCR_NV1))
return -EINVAL;
if (!vcpu->arch.ctxt.vncr_array)
vcpu->arch.ctxt.vncr_array = (u64 *)__get_free_page(GFP_KERNEL_ACCOUNT |
__GFP_ZERO);
if (!vcpu->arch.ctxt.vncr_array)
return -ENOMEM;
/*
* Let's treat memory allocation failures as benign: If we fail to
* allocate anything, return an error and keep the allocated array
* alive. Userspace may try to recover by initializing the vcpu
* again, and there is no reason to affect the whole VM for this.
*/
num_mmus = atomic_read(&kvm->online_vcpus) * S2_MMU_PER_VCPU;
if (num_mmus > kvm->arch.nested_mmus_size) {
tmp = kvcalloc(num_mmus, sizeof(*tmp), GFP_KERNEL_ACCOUNT);
if (!tmp)
return -ENOMEM;
write_lock(&kvm->mmu_lock);
if (kvm->arch.nested_mmus_size) {
memcpy(tmp, kvm->arch.nested_mmus,
size_mul(sizeof(*tmp), kvm->arch.nested_mmus_size));
for (int i = 0; i < kvm->arch.nested_mmus_size; i++)
tmp[i].pgt->mmu = &tmp[i];
}
swap(kvm->arch.nested_mmus, tmp);
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/kvm.h`, `linux/kvm_host.h`, `asm/fixmap.h`, `asm/kvm_arm.h`, `asm/kvm_emulate.h`, `asm/kvm_mmu.h`, `asm/kvm_nested.h`.
- Detected declarations: `struct vncr_tlb`, `struct s2_walk_info`, `struct s1e2_tlbi_scope`, `function kvm_init_nested`, `function init_nested_s2_mmu`, `function kvm_vcpu_init_nested`, `function compute_fsc`, `function esr_s2_fault`, `function get_ia_size`, `function check_base_s2_limits`.
- Atlas domain: Architecture Layer / arch/arm64.
- 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.