arch/arm64/kvm/hyp/nvhe/psci-relay.c
Source file repositories/reference/linux-study-clean/arch/arm64/kvm/hyp/nvhe/psci-relay.c
File Facts
- System
- Linux kernel
- Corpus path
arch/arm64/kvm/hyp/nvhe/psci-relay.c- Extension
.c- Size
- 8685 bytes
- Lines
- 322
- 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
asm/kvm_asm.hasm/kvm_hyp.hasm/kvm_hypevents.hasm/kvm_mmu.hlinux/kvm_host.huapi/linux/psci.hnvhe/arm-smccc.hnvhe/memory.hnvhe/trap_handler.h
Detected Declarations
struct psci_boot_argsfunction is_psci_0_1_callfunction is_psci_0_2_callfunction psci_callfunction psci_forwardfunction find_cpu_idfunction try_acquire_boot_argsfunction release_boot_argsfunction psci_cpu_onfunction psci_cpu_suspendfunction psci_system_suspendfunction __kvm_host_psci_cpu_entryfunction __kvm_host_psci_cpu_on_entryfunction __kvm_host_psci_cpu_resume_entryfunction psci_0_1_handlerfunction psci_0_2_handlerfunction psci_1_0_handlerfunction kvm_host_psci_handler
Annotated Snippet
struct psci_boot_args {
atomic_t lock;
unsigned long pc;
unsigned long r0;
};
#define PSCI_BOOT_ARGS_UNLOCKED 0
#define PSCI_BOOT_ARGS_LOCKED 1
#define PSCI_BOOT_ARGS_INIT \
((struct psci_boot_args){ \
.lock = ATOMIC_INIT(PSCI_BOOT_ARGS_UNLOCKED), \
})
static DEFINE_PER_CPU(struct psci_boot_args, cpu_on_args) = PSCI_BOOT_ARGS_INIT;
static DEFINE_PER_CPU(struct psci_boot_args, suspend_args) = PSCI_BOOT_ARGS_INIT;
#define is_psci_0_1(what, func_id) \
(kvm_host_psci_config.psci_0_1_ ## what ## _implemented && \
(func_id) == kvm_host_psci_config.function_ids_0_1.what)
static bool is_psci_0_1_call(u64 func_id)
{
return (is_psci_0_1(cpu_suspend, func_id) ||
is_psci_0_1(cpu_on, func_id) ||
is_psci_0_1(cpu_off, func_id) ||
is_psci_0_1(migrate, func_id));
}
static bool is_psci_0_2_call(u64 func_id)
{
/* SMCCC reserves IDs 0x00-1F with the given 32/64-bit base for PSCI. */
return (PSCI_0_2_FN(0) <= func_id && func_id <= PSCI_0_2_FN(31)) ||
(PSCI_0_2_FN64(0) <= func_id && func_id <= PSCI_0_2_FN64(31));
}
static unsigned long psci_call(unsigned long fn, unsigned long arg0,
unsigned long arg1, unsigned long arg2)
{
struct arm_smccc_res res;
hyp_smccc_1_1_smc(fn, arg0, arg1, arg2, &res);
return res.a0;
}
static unsigned long psci_forward(struct kvm_cpu_context *host_ctxt)
{
return psci_call(cpu_reg(host_ctxt, 0), cpu_reg(host_ctxt, 1),
cpu_reg(host_ctxt, 2), cpu_reg(host_ctxt, 3));
}
static unsigned int find_cpu_id(u64 mpidr)
{
unsigned int i;
/* Reject invalid MPIDRs */
if (mpidr & ~MPIDR_HWID_BITMASK)
return INVALID_CPU_ID;
for (i = 0; i < NR_CPUS; i++) {
if (cpu_logical_map(i) == mpidr)
return i;
}
return INVALID_CPU_ID;
}
static __always_inline bool try_acquire_boot_args(struct psci_boot_args *args)
{
return atomic_cmpxchg_acquire(&args->lock,
PSCI_BOOT_ARGS_UNLOCKED,
PSCI_BOOT_ARGS_LOCKED) ==
PSCI_BOOT_ARGS_UNLOCKED;
}
static __always_inline void release_boot_args(struct psci_boot_args *args)
{
atomic_set_release(&args->lock, PSCI_BOOT_ARGS_UNLOCKED);
}
static int psci_cpu_on(u64 func_id, struct kvm_cpu_context *host_ctxt)
{
DECLARE_REG(u64, mpidr, host_ctxt, 1);
DECLARE_REG(unsigned long, pc, host_ctxt, 2);
DECLARE_REG(unsigned long, r0, host_ctxt, 3);
unsigned int cpu_id;
struct psci_boot_args *boot_args;
struct kvm_nvhe_init_params *init_params;
int ret;
Annotation
- Immediate include surface: `asm/kvm_asm.h`, `asm/kvm_hyp.h`, `asm/kvm_hypevents.h`, `asm/kvm_mmu.h`, `linux/kvm_host.h`, `uapi/linux/psci.h`, `nvhe/arm-smccc.h`, `nvhe/memory.h`.
- Detected declarations: `struct psci_boot_args`, `function is_psci_0_1_call`, `function is_psci_0_2_call`, `function psci_call`, `function psci_forward`, `function find_cpu_id`, `function try_acquire_boot_args`, `function release_boot_args`, `function psci_cpu_on`, `function psci_cpu_suspend`.
- 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.