arch/powerpc/kernel/rtas.c
Source file repositories/reference/linux-study-clean/arch/powerpc/kernel/rtas.c
File Facts
- System
- Linux kernel
- Corpus path
arch/powerpc/kernel/rtas.c- Extension
.c- Size
- 58431 bytes
- Lines
- 2134
- Domain
- Architecture Layer
- Bucket
- arch/powerpc
- Inferred role
- Architecture Layer: syscall or user/kernel boundary
- Status
- core 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.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- 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/bsearch.hlinux/capability.hlinux/delay.hlinux/export.hlinux/init.hlinux/kconfig.hlinux/kernel.hlinux/lockdep.hlinux/memblock.hlinux/mutex.hlinux/nospec.hlinux/of.hlinux/of_fdt.hlinux/reboot.hlinux/sched.hlinux/security.hlinux/slab.hlinux/spinlock.hlinux/stdarg.hlinux/syscalls.hlinux/types.hlinux/uaccess.hlinux/xarray.hasm/delay.hasm/firmware.hasm/interrupt.hasm/machdep.hasm/mmu.hasm/page.hasm/rtas-work-area.hasm/rtas.hasm/time.h
Detected Declarations
syscall rtasstruct rtas_filterstruct rtas_functionfunction rtas_function_tokenfunction rtas_function_cmpfunction rtas_token_to_function_xarray_initfunction for_each_rtas_functionfunction sys_rtasfunction for_each_rtas_functionfunction __do_enter_rtasfunction __do_enter_rtas_tracefunction do_enter_rtasfunction call_rtas_display_statusfunction call_rtas_display_status_delayfunction udbg_init_rtas_panelfunction rtas_progressfunction rtas_tokenfunction rtas_get_error_log_maxfunction init_error_log_maxfunction errorfunction init_error_log_maxfunction rtas_call_unlockedfunction token_is_restricted_errinjctfunction rtas_callfunction rtas_busy_delay_timefunction rtas_busy_delayfunction rtas_busy_delayfunction rtas_error_rcfunction rtas_get_power_levelfunction rtas_set_power_levelfunction rtas_get_sensorfunction rtas_get_sensor_fastfunction rtas_indicator_presentfunction rtas_set_indicatorfunction rtas_set_indicator_fastfunction rtas_ibm_suspend_mefunction rtas_restartfunction rtas_power_offfunction rtas_haltfunction rtas_os_termfunction rtas_activate_firmwarefunction get_pseries_errorlogfunction in_rmo_buffunction block_rtas_callfunction rtas_function_table_initfunction for_each_property_of_nodefunction rtas_initializefunction early_init_dt_scan_rtas
Annotated Snippet
SYSCALL_DEFINE1(rtas, struct rtas_args __user *, uargs)
{
const struct rtas_function *func;
struct pin_cookie cookie;
struct rtas_args args;
unsigned long flags;
char *buff_copy, *errbuf = NULL;
int nargs, nret, token;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (!rtas.entry)
return -EINVAL;
if (copy_from_user(&args, uargs, 3 * sizeof(u32)) != 0)
return -EFAULT;
nargs = be32_to_cpu(args.nargs);
nret = be32_to_cpu(args.nret);
token = be32_to_cpu(args.token);
if (nargs >= ARRAY_SIZE(args.args)
|| nret > ARRAY_SIZE(args.args)
|| nargs + nret > ARRAY_SIZE(args.args))
return -EINVAL;
nargs = array_index_nospec(nargs, ARRAY_SIZE(args.args));
nret = array_index_nospec(nret, ARRAY_SIZE(args.args) - nargs);
/* Copy in args. */
if (copy_from_user(args.args, uargs->args,
nargs * sizeof(rtas_arg_t)) != 0)
return -EFAULT;
/*
* If this token doesn't correspond to a function the kernel
* understands, you're not allowed to call it.
*/
func = rtas_token_to_function_untrusted(token);
if (!func)
return -EINVAL;
args.rets = &args.args[nargs];
memset(args.rets, 0, nret * sizeof(rtas_arg_t));
if (block_rtas_call(func, nargs, &args))
return -EINVAL;
if (token_is_restricted_errinjct(token)) {
int err;
err = security_locked_down(LOCKDOWN_RTAS_ERROR_INJECTION);
if (err)
return err;
}
/* Need to handle ibm,suspend_me call specially */
if (token == rtas_function_token(RTAS_FN_IBM_SUSPEND_ME)) {
/*
* rtas_ibm_suspend_me assumes the streamid handle is in cpu
* endian, or at least the hcall within it requires it.
*/
int rc = 0;
u64 handle = ((u64)be32_to_cpu(args.args[0]) << 32)
| be32_to_cpu(args.args[1]);
rc = rtas_syscall_dispatch_ibm_suspend_me(handle);
if (rc == -EAGAIN)
args.rets[0] = cpu_to_be32(RTAS_NOT_SUSPENDABLE);
else if (rc == -EIO)
args.rets[0] = cpu_to_be32(-1);
else if (rc)
return rc;
goto copy_return;
}
buff_copy = get_errorlog_buffer();
/*
* If this function has a mutex assigned to it, we must
* acquire it to avoid interleaving with any kernel-based uses
* of the same function. Kernel-based sequences acquire the
* appropriate mutex explicitly.
*/
if (func->lock)
mutex_lock(func->lock);
raw_spin_lock_irqsave(&rtas_lock, flags);
cookie = lockdep_pin_lock(&rtas_lock);
Annotation
- Immediate include surface: `linux/bsearch.h`, `linux/capability.h`, `linux/delay.h`, `linux/export.h`, `linux/init.h`, `linux/kconfig.h`, `linux/kernel.h`, `linux/lockdep.h`.
- Detected declarations: `syscall rtas`, `struct rtas_filter`, `struct rtas_function`, `function rtas_function_token`, `function rtas_function_cmp`, `function rtas_token_to_function_xarray_init`, `function for_each_rtas_function`, `function sys_rtas`, `function for_each_rtas_function`, `function __do_enter_rtas`.
- Atlas domain: Architecture Layer / arch/powerpc.
- Implementation status: core 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.