arch/s390/kernel/diag/diag.c
Source file repositories/reference/linux-study-clean/arch/s390/kernel/diag/diag.c
File Facts
- System
- Linux kernel
- Corpus path
arch/s390/kernel/diag/diag.c- Extension
.c- Size
- 9216 bytes
- Lines
- 325
- Domain
- Architecture Layer
- Bucket
- arch/s390
- Inferred role
- Architecture Layer: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- 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/export.hlinux/init.hlinux/cpu.hlinux/seq_file.hlinux/debugfs.hlinux/vmalloc.hasm/asm-extable.hasm/diag.hasm/trace/diag.hasm/sections.hasm/asm.h../entry.h
Detected Declarations
struct diag_statstruct diag_descfunction show_diag_statfunction for_each_online_cpufunction for_each_online_cpufunction show_diag_stat_stopfunction show_diag_stat_initfunction diag_stat_incfunction diag_stat_inc_norecursionfunction diag0cfunction diag14function __diag204function diag204function diag210function diag8cfunction diag224function diag26cfunction diag49cmodule init show_diag_stat_initexport diag_stat_incexport diag_stat_inc_norecursionexport diag14export diag204export diag210export diag8cexport diag224export diag26cexport diag49c
Annotated Snippet
device_initcall(show_diag_stat_init);
void diag_stat_inc(enum diag_stat_enum nr)
{
this_cpu_inc(diag_stat.counter[nr]);
trace_s390_diagnose(diag_map[nr].code);
}
EXPORT_SYMBOL(diag_stat_inc);
void notrace diag_stat_inc_norecursion(enum diag_stat_enum nr)
{
this_cpu_inc(diag_stat.counter[nr]);
trace_s390_diagnose_norecursion(diag_map[nr].code);
}
EXPORT_SYMBOL(diag_stat_inc_norecursion);
/*
* Diagnose 0c: Pseudo Timer
*/
void diag0c(struct hypfs_diag0c_entry *data)
{
diag_stat_inc(DIAG_STAT_X00C);
diag_amode31_ops.diag0c(virt_to_phys(data));
}
/*
* Diagnose 14: Input spool file manipulation
*
* The subcode parameter determines the type of the first parameter rx.
* Currently used are the following 3 subcommands:
* 0x0: Read the Next Spool File Buffer (Data Record)
* 0x28: Position a Spool File to the Designated Record
* 0xfff: Retrieve Next File Descriptor
*
* For subcommands 0x0 and 0xfff, the value of the first parameter is
* a virtual address of a memory buffer and needs virtual to physical
* address translation. For other subcommands the rx parameter is not
* a virtual address.
*/
int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode)
{
diag_stat_inc(DIAG_STAT_X014);
switch (subcode) {
case 0x0:
case 0xfff:
rx = virt_to_phys((void *)rx);
break;
default:
/* Do nothing */
break;
}
return diag_amode31_ops.diag14(rx, ry1, subcode);
}
EXPORT_SYMBOL(diag14);
#define DIAG204_BUSY_RC 8
static inline int __diag204(unsigned long *subcode, unsigned long size, void *addr)
{
union register_pair rp = { .even = *subcode, .odd = size };
asm_inline volatile(
" diag %[addr],%[rp],0x204\n"
"0: nopr %%r7\n"
EX_TABLE(0b,0b)
: [rp] "+&d" (rp.pair) : [addr] "d" (addr) : "memory");
*subcode = rp.even;
return rp.odd;
}
/**
* diag204() - Issue diagnose 204 call.
* @subcode: Subcode of diagnose 204 to be executed.
* @size: Size of area in pages which @area points to, if given.
* @addr: Vmalloc'ed memory area where the result is written to.
*
* Execute diagnose 204 with the given subcode and write the result to the
* memory area specified with @addr. For subcodes which do not write a
* result to memory both @size and @addr must be zero. If @addr is
* specified it must be page aligned and must have been allocated with
* vmalloc(). Conversion to real / physical addresses will be handled by
* this function if required.
*/
int diag204(unsigned long subcode, unsigned long size, void *addr)
{
if (addr) {
if (WARN_ON_ONCE(!is_vmalloc_addr(addr)))
return -EINVAL;
if (WARN_ON_ONCE(!IS_ALIGNED((unsigned long)addr, PAGE_SIZE)))
return -EINVAL;
Annotation
- Immediate include surface: `linux/export.h`, `linux/init.h`, `linux/cpu.h`, `linux/seq_file.h`, `linux/debugfs.h`, `linux/vmalloc.h`, `asm/asm-extable.h`, `asm/diag.h`.
- Detected declarations: `struct diag_stat`, `struct diag_desc`, `function show_diag_stat`, `function for_each_online_cpu`, `function for_each_online_cpu`, `function show_diag_stat_stop`, `function show_diag_stat_init`, `function diag_stat_inc`, `function diag_stat_inc_norecursion`, `function diag0c`.
- Atlas domain: Architecture Layer / arch/s390.
- Implementation status: integration 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.