arch/powerpc/kvm/book3s_pr_papr.c
Source file repositories/reference/linux-study-clean/arch/powerpc/kvm/book3s_pr_papr.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/kvm/book3s_pr_papr.c- Extension
.c- Size
- 12553 bytes
- Lines
- 497
- 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/anon_inodes.hlinux/uaccess.hasm/kvm_ppc.hasm/kvm_book3s.h
Detected Declarations
function Copyrightfunction kvmppc_h_pr_enterfunction kvmppc_h_pr_removefunction kvmppc_h_pr_bulk_removefunction kvmppc_h_pr_protectfunction kvmppc_h_pr_logical_ci_loadfunction kvmppc_h_pr_logical_ci_storefunction kvmppc_h_pr_set_modefunction kvmppc_h_pr_put_tcefunction kvmppc_h_pr_put_tce_indirectfunction kvmppc_h_pr_stuff_tcefunction kvmppc_h_pr_put_tcefunction kvmppc_h_pr_put_tce_indirectfunction kvmppc_h_pr_stuff_tcefunction kvmppc_h_pr_xics_hcallfunction kvmppc_h_prfunction kvmppc_hcall_impl_prfunction kvmppc_pr_init_default_hcalls
Annotated Snippet
if ((tsh & H_BULK_REMOVE_TYPE) == H_BULK_REMOVE_END) {
break; /* Exit success */
} else if ((tsh & H_BULK_REMOVE_TYPE) !=
H_BULK_REMOVE_REQUEST) {
ret = H_PARAMETER;
break; /* Exit fail */
}
tsh &= H_BULK_REMOVE_PTEX | H_BULK_REMOVE_FLAGS;
tsh |= H_BULK_REMOVE_RESPONSE;
if ((tsh & H_BULK_REMOVE_ANDCOND) &&
(tsh & H_BULK_REMOVE_AVPN)) {
tsh |= H_BULK_REMOVE_PARM;
kvmppc_set_gpr(vcpu, paramnr+(2*i), tsh);
ret = H_PARAMETER;
break; /* Exit fail */
}
pteg = get_pteg_addr(vcpu, tsh & H_BULK_REMOVE_PTEX);
if (copy_from_user(pte, (void __user *)pteg, sizeof(pte))) {
ret = H_FUNCTION;
break;
}
pte[0] = be64_to_cpu((__force __be64)pte[0]);
pte[1] = be64_to_cpu((__force __be64)pte[1]);
/* tsl = AVPN */
flags = (tsh & H_BULK_REMOVE_FLAGS) >> 26;
if ((pte[0] & HPTE_V_VALID) == 0 ||
((flags & H_AVPN) && (pte[0] & ~0x7fUL) != tsl) ||
((flags & H_ANDCOND) && (pte[0] & tsl) != 0)) {
tsh |= H_BULK_REMOVE_NOT_FOUND;
} else {
/* Splat the pteg in (userland) hpt */
if (copy_to_user((void __user *)pteg, &v, sizeof(v))) {
ret = H_FUNCTION;
break;
}
rb = compute_tlbie_rb(pte[0], pte[1],
tsh & H_BULK_REMOVE_PTEX);
vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
tsh |= H_BULK_REMOVE_SUCCESS;
tsh |= (pte[1] & (HPTE_R_C | HPTE_R_R)) << 43;
}
kvmppc_set_gpr(vcpu, paramnr+(2*i), tsh);
}
mutex_unlock(&vcpu->kvm->arch.hpt_mutex);
kvmppc_set_gpr(vcpu, 3, ret);
return EMULATE_DONE;
}
static int kvmppc_h_pr_protect(struct kvm_vcpu *vcpu)
{
unsigned long flags = kvmppc_get_gpr(vcpu, 4);
unsigned long pte_index = kvmppc_get_gpr(vcpu, 5);
unsigned long avpn = kvmppc_get_gpr(vcpu, 6);
unsigned long rb, pteg, r, v;
unsigned long pte[2];
long int ret;
pteg = get_pteg_addr(vcpu, pte_index);
mutex_lock(&vcpu->kvm->arch.hpt_mutex);
ret = H_FUNCTION;
if (copy_from_user(pte, (void __user *)pteg, sizeof(pte)))
goto done;
pte[0] = be64_to_cpu((__force __be64)pte[0]);
pte[1] = be64_to_cpu((__force __be64)pte[1]);
ret = H_NOT_FOUND;
if ((pte[0] & HPTE_V_VALID) == 0 ||
((flags & H_AVPN) && (pte[0] & ~0x7fUL) != avpn))
goto done;
v = pte[0];
r = pte[1];
r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_HI |
HPTE_R_KEY_LO);
r |= (flags << 55) & HPTE_R_PP0;
r |= (flags << 48) & HPTE_R_KEY_HI;
r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);
pte[1] = r;
rb = compute_tlbie_rb(v, r, pte_index);
vcpu->arch.mmu.tlbie(vcpu, rb, rb & 1 ? true : false);
pte[0] = (__force u64)cpu_to_be64(pte[0]);
Annotation
- Immediate include surface: `linux/anon_inodes.h`, `linux/uaccess.h`, `asm/kvm_ppc.h`, `asm/kvm_book3s.h`.
- Detected declarations: `function Copyright`, `function kvmppc_h_pr_enter`, `function kvmppc_h_pr_remove`, `function kvmppc_h_pr_bulk_remove`, `function kvmppc_h_pr_protect`, `function kvmppc_h_pr_logical_ci_load`, `function kvmppc_h_pr_logical_ci_store`, `function kvmppc_h_pr_set_mode`, `function kvmppc_h_pr_put_tce`, `function kvmppc_h_pr_put_tce_indirect`.
- Atlas domain: Architecture Layer / arch/powerpc.
- 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.