arch/powerpc/kvm/book3s_64_mmu_host.c
Source file repositories/reference/linux-study-clean/arch/powerpc/kvm/book3s_64_mmu_host.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/kvm/book3s_64_mmu_host.c- Extension
.c- Size
- 10174 bytes
- Lines
- 408
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/kvm_host.hlinux/pkeys.hasm/kvm_ppc.hasm/kvm_book3s.hasm/book3s/64/mmu-hash.hasm/machdep.hasm/mmu_context.hasm/hw_irq.htrace_pr.hbook3s.h
Detected Declarations
function Copyrightfunction kvmppc_sid_hashfunction kvmppc_mmu_map_pagefunction kvmppc_mmu_unmap_pagefunction kvmppc_mmu_next_segmentfunction kvmppc_mmu_map_segmentfunction kvmppc_mmu_flush_segmentfunction kvmppc_mmu_flush_segmentsfunction kvmppc_mmu_destroy_prfunction kvmppc_mmu_init_pr
Annotated Snippet
if (mmu_hash_ops.hpte_remove(hpteg) < 0) {
r = -1;
goto out_unlock;
}
ret = mmu_hash_ops.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
hpsize, hpsize, MMU_SEGSIZE_256M);
if (ret == -1) {
/* If we couldn't map a primary PTE, try a secondary */
hash = ~hash;
vflags ^= HPTE_V_SECONDARY;
attempt++;
goto map_again;
} else if (ret < 0) {
r = -EIO;
goto out_unlock;
} else {
trace_kvm_book3s_64_mmu_map(rflags, hpteg,
vpn, hpaddr, orig_pte);
/*
* The mmu_hash_ops code may give us a secondary entry even
* though we asked for a primary. Fix up.
*/
if ((ret & _PTEIDX_SECONDARY) && !(vflags & HPTE_V_SECONDARY)) {
hash = ~hash;
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
}
cpte->slot = hpteg + (ret & 7);
cpte->host_vpn = vpn;
cpte->pte = *orig_pte;
cpte->pfn = pfn;
cpte->pagesize = hpsize;
kvmppc_mmu_hpte_cache_map(vcpu, cpte);
cpte = NULL;
}
out_unlock:
/* FIXME: Don't unconditionally pass unused=false. */
kvm_release_faultin_page(kvm, page, false,
orig_pte->may_write && writable);
spin_unlock(&kvm->mmu_lock);
if (cpte)
kvmppc_mmu_hpte_cache_free(cpte);
out:
return r;
}
void kvmppc_mmu_unmap_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *pte)
{
u64 mask = 0xfffffffffULL;
u64 vsid;
vcpu->arch.mmu.esid_to_vsid(vcpu, pte->eaddr >> SID_SHIFT, &vsid);
if (vsid & VSID_64K)
mask = 0xffffffff0ULL;
kvmppc_mmu_pte_vflush(vcpu, pte->vpage, mask);
}
static struct kvmppc_sid_map *create_sid_map(struct kvm_vcpu *vcpu, u64 gvsid)
{
unsigned long vsid_bits = VSID_BITS_65_256M;
struct kvmppc_sid_map *map;
struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
u16 sid_map_mask;
static int backwards_map;
if (kvmppc_get_msr(vcpu) & MSR_PR)
gvsid |= VSID_PR;
/* We might get collisions that trap in preceding order, so let's
map them differently */
sid_map_mask = kvmppc_sid_hash(vcpu, gvsid);
if (backwards_map)
sid_map_mask = SID_MAP_MASK - sid_map_mask;
map = &to_book3s(vcpu)->sid_map[sid_map_mask];
/* Make sure we're taking the other map next time */
backwards_map = !backwards_map;
/* Uh-oh ... out of mappings. Let's flush! */
if (vcpu_book3s->proto_vsid_next == vcpu_book3s->proto_vsid_max) {
vcpu_book3s->proto_vsid_next = vcpu_book3s->proto_vsid_first;
memset(vcpu_book3s->sid_map, 0,
Annotation
- Immediate include surface: `linux/kvm_host.h`, `linux/pkeys.h`, `asm/kvm_ppc.h`, `asm/kvm_book3s.h`, `asm/book3s/64/mmu-hash.h`, `asm/machdep.h`, `asm/mmu_context.h`, `asm/hw_irq.h`.
- Detected declarations: `function Copyright`, `function kvmppc_sid_hash`, `function kvmppc_mmu_map_page`, `function kvmppc_mmu_unmap_page`, `function kvmppc_mmu_next_segment`, `function kvmppc_mmu_map_segment`, `function kvmppc_mmu_flush_segment`, `function kvmppc_mmu_flush_segments`, `function kvmppc_mmu_destroy_pr`, `function kvmppc_mmu_init_pr`.
- 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.