arch/arm64/kvm/psci.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/psci.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/psci.c- Extension
.c- Size
- 13095 bytes
- Lines
- 508
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/arm-smccc.hlinux/preempt.hlinux/kvm_host.hlinux/uaccess.hlinux/wait.hasm/cputype.hasm/kvm_emulate.hkvm/arm_psci.hkvm/arm_hypercalls.h
Detected Declarations
function Copyrightfunction kvm_psci_vcpu_suspendfunction kvm_psci_valid_affinityfunction kvm_psci_vcpu_onfunction kvm_psci_vcpu_affinity_infofunction kvm_prepare_system_eventfunction kvm_psci_system_offfunction kvm_psci_system_off2function kvm_psci_system_resetfunction kvm_psci_system_reset2function kvm_psci_system_suspendfunction kvm_psci_narrow_to_32bitfunction kvm_psci_check_allowed_functionfunction kvm_psci_0_2_callfunction kvm_psci_1_x_callfunction kvm_psci_0_1_callfunction kvm_psci_call
Annotated Snippet
if ((mpidr & target_affinity_mask) == target_affinity) {
matching_cpus++;
if (!kvm_arm_vcpu_stopped(tmp))
return PSCI_0_2_AFFINITY_LEVEL_ON;
}
}
if (!matching_cpus)
return PSCI_RET_INVALID_PARAMS;
return PSCI_0_2_AFFINITY_LEVEL_OFF;
}
static void kvm_prepare_system_event(struct kvm_vcpu *vcpu, u32 type, u64 flags)
{
unsigned long i;
struct kvm_vcpu *tmp;
/*
* The KVM ABI specifies that a system event exit may call KVM_RUN
* again and may perform shutdown/reboot at a later time that when the
* actual request is made. Since we are implementing PSCI and a
* caller of PSCI reboot and shutdown expects that the system shuts
* down or reboots immediately, let's make sure that VCPUs are not run
* after this call is handled and before the VCPUs have been
* re-initialized.
*/
kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
spin_lock(&tmp->arch.mp_state_lock);
WRITE_ONCE(tmp->arch.mp_state.mp_state, KVM_MP_STATE_STOPPED);
spin_unlock(&tmp->arch.mp_state_lock);
}
kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP);
memset(&vcpu->run->system_event, 0, sizeof(vcpu->run->system_event));
vcpu->run->system_event.type = type;
vcpu->run->system_event.ndata = 1;
vcpu->run->system_event.data[0] = flags;
vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
}
static void kvm_psci_system_off(struct kvm_vcpu *vcpu)
{
kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_SHUTDOWN, 0);
}
static void kvm_psci_system_off2(struct kvm_vcpu *vcpu)
{
kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_SHUTDOWN,
KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2);
}
static void kvm_psci_system_reset(struct kvm_vcpu *vcpu)
{
kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET, 0);
}
static void kvm_psci_system_reset2(struct kvm_vcpu *vcpu)
{
kvm_prepare_system_event(vcpu, KVM_SYSTEM_EVENT_RESET,
KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2);
}
static void kvm_psci_system_suspend(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
memset(&run->system_event, 0, sizeof(vcpu->run->system_event));
run->system_event.type = KVM_SYSTEM_EVENT_SUSPEND;
run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
}
static void kvm_psci_narrow_to_32bit(struct kvm_vcpu *vcpu)
{
int i;
/*
* Zero the input registers' upper 32 bits. They will be fully
* zeroed on exit, so we're fine changing them in place.
*/
for (i = 1; i < 4; i++)
vcpu_set_reg(vcpu, i, lower_32_bits(vcpu_get_reg(vcpu, i)));
}
static unsigned long kvm_psci_check_allowed_function(struct kvm_vcpu *vcpu, u32 fn)
{
/*
* Prevent 32 bit guests from calling 64 bit PSCI functions.
*/
if ((fn & PSCI_0_2_64BIT) && vcpu_mode_is_32bit(vcpu))
Annotation
- Immediate include surface: `linux/arm-smccc.h`, `linux/preempt.h`, `linux/kvm_host.h`, `linux/uaccess.h`, `linux/wait.h`, `asm/cputype.h`, `asm/kvm_emulate.h`, `kvm/arm_psci.h`.
- Detected declarations: `function Copyright`, `function kvm_psci_vcpu_suspend`, `function kvm_psci_valid_affinity`, `function kvm_psci_vcpu_on`, `function kvm_psci_vcpu_affinity_info`, `function kvm_prepare_system_event`, `function kvm_psci_system_off`, `function kvm_psci_system_off2`, `function kvm_psci_system_reset`, `function kvm_psci_system_reset2`.
- 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.