arch/powerpc/kvm/book3s_hv_nested.c
Source file repositories/reference/linux-study-clean/arch/powerpc/kvm/book3s_hv_nested.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/kvm/book3s_hv_nested.c- Extension
.c- Size
- 45814 bytes
- Lines
- 1715
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- 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/kernel.hlinux/kvm_host.hlinux/llist.hlinux/pgtable.hasm/kvm_ppc.hasm/kvm_book3s.hasm/mmu.hasm/pgalloc.hasm/pte-walk.hasm/reg.hasm/plpar_wrappers.hasm/firmware.h
Detected Declarations
function kvmhv_save_hv_regsfunction byteswap_pt_regsfunction byteswap_hv_regsfunction save_hv_return_statefunction restore_hv_regsfunction kvmhv_restore_hv_return_statefunction kvmhv_nested_mmio_neededfunction kvmppc_complete_mmio_loadfunction kvmhv_read_guest_state_and_regsfunction kvmhv_write_guest_state_and_regsfunction load_l2_hv_regsfunction kvmhv_enter_nested_guestfunction kvmhv_nested_initfunction kvmhv_nested_exitfunction kvmhv_flush_lpidfunction kvmhv_set_ptbl_entryfunction kvmhv_set_nested_ptblfunction kvmhv_set_partition_tablefunction kvmhv_copy_tofrom_guest_nestedfunction kvmhv_update_ptbl_cachefunction kvmhv_vm_nested_initfunction __prealloc_nestedfunction __add_nestedfunction __remove_nestedfunction kvmhv_release_nestedfunction kvmhv_remove_nestedfunction kvmhv_release_all_nestedfunction kvmhv_flush_nestedfunction kvmhv_put_nestedfunction kvmhv_n_rmap_is_equalfunction kvmhv_insert_nest_rmapfunction kvmhv_update_nest_rmap_rcfunction kvmhv_update_nest_rmap_rc_listfunction kvmhv_remove_nest_rmapfunction kvmhv_remove_nest_rmap_listfunction for_each_nest_rmap_safefunction kvmhv_remove_nest_rmap_rangefunction kvmhv_free_memslot_nest_rmapfunction kvmhv_invalidate_shadow_ptefunction get_ricfunction get_prsfunction get_rfunction get_lpidfunction get_isfunction get_apfunction get_epnfunction kvmhv_emulate_tlbie_tlb_addrfunction kvmhv_emulate_tlbie_lpid
Annotated Snippet
if (rc != H_SUCCESS) {
pr_err("kvm-hv: Could not configure parent hypervisor capabilities (rc=%ld)",
rc);
return -ENODEV;
}
static_branch_enable(&__kvmhv_is_nestedv2);
return 0;
}
pr_info("kvm-hv: nestedv2 get capabilities hcall failed, falling back to nestedv1 (rc=%ld)\n",
rc);
/* Partition table entry is 1<<4 bytes in size, hence the 4. */
ptb_order = KVM_MAX_NESTED_GUESTS_SHIFT + 4;
/* Minimum partition table size is 1<<12 bytes */
if (ptb_order < 12)
ptb_order = 12;
pseries_partition_tb = kmalloc(sizeof(struct patb_entry) << ptb_order,
GFP_KERNEL);
if (!pseries_partition_tb) {
pr_err("kvm-hv: failed to allocated nested partition table\n");
return -ENOMEM;
}
ptcr = __pa(pseries_partition_tb) | (ptb_order - 12);
rc = plpar_hcall_norets(H_SET_PARTITION_TABLE, ptcr);
if (rc != H_SUCCESS) {
pr_err("kvm-hv: Parent hypervisor does not support nesting (rc=%ld)\n",
rc);
kfree(pseries_partition_tb);
pseries_partition_tb = NULL;
return -ENODEV;
}
return 0;
}
void kvmhv_nested_exit(void)
{
/*
* N.B. the kvmhv_on_pseries() test is there because it enables
* the compiler to remove the call to plpar_hcall_norets()
* when CONFIG_PPC_PSERIES=n.
*/
if (kvmhv_on_pseries() && pseries_partition_tb) {
plpar_hcall_norets(H_SET_PARTITION_TABLE, 0);
kfree(pseries_partition_tb);
pseries_partition_tb = NULL;
}
}
void kvmhv_flush_lpid(u64 lpid)
{
long rc;
if (!kvmhv_on_pseries()) {
radix__flush_all_lpid(lpid);
return;
}
if (!firmware_has_feature(FW_FEATURE_RPT_INVALIDATE))
rc = plpar_hcall_norets(H_TLB_INVALIDATE, H_TLBIE_P1_ENC(2, 0, 1),
lpid, TLBIEL_INVAL_SET_LPID);
else
rc = pseries_rpt_invalidate(lpid, H_RPTI_TARGET_CMMU,
H_RPTI_TYPE_NESTED |
H_RPTI_TYPE_TLB | H_RPTI_TYPE_PWC |
H_RPTI_TYPE_PAT,
H_RPTI_PAGE_ALL, 0, -1UL);
if (rc)
pr_err("KVM: TLB LPID invalidation hcall failed, rc=%ld\n", rc);
}
void kvmhv_set_ptbl_entry(u64 lpid, u64 dw0, u64 dw1)
{
if (!kvmhv_on_pseries()) {
mmu_partition_table_set_entry(lpid, dw0, dw1, true);
return;
}
if (kvmhv_is_nestedv1()) {
pseries_partition_tb[lpid].patb0 = cpu_to_be64(dw0);
pseries_partition_tb[lpid].patb1 = cpu_to_be64(dw1);
/* L0 will do the necessary barriers */
kvmhv_flush_lpid(lpid);
}
if (kvmhv_is_nestedv2())
kvmhv_nestedv2_set_ptbl_entry(lpid, dw0, dw1);
}
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/kvm_host.h`, `linux/llist.h`, `linux/pgtable.h`, `asm/kvm_ppc.h`, `asm/kvm_book3s.h`, `asm/mmu.h`, `asm/pgalloc.h`.
- Detected declarations: `function kvmhv_save_hv_regs`, `function byteswap_pt_regs`, `function byteswap_hv_regs`, `function save_hv_return_state`, `function restore_hv_regs`, `function kvmhv_restore_hv_return_state`, `function kvmhv_nested_mmio_needed`, `function kvmppc_complete_mmio_load`, `function kvmhv_read_guest_state_and_regs`, `function kvmhv_write_guest_state_and_regs`.
- Atlas domain: Architecture Layer / arch/powerpc.
- 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.