arch/s390/kernel/crash_dump.c

Source file repositories/reference/linux-study-clean/arch/s390/kernel/crash_dump.c

File Facts

System
Linux kernel
Corpus path
arch/s390/kernel/crash_dump.c
Extension
.c
Size
17648 bytes
Lines
708
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.

Dependency Surface

Detected Declarations

Annotated Snippet

struct save_area {
	struct list_head list;
	u64 psw[2];
	u64 ctrs[16];
	u64 gprs[16];
	u32 acrs[16];
	u64 fprs[16];
	u32 fpc;
	u32 prefix;
	u32 todpreg;
	u64 timer;
	u64 todcmp;
	u64 vxrs_low[16];
	__vector128 vxrs_high[16];
};

static LIST_HEAD(dump_save_areas);

/*
 * Allocate a save area
 */
struct save_area * __init save_area_alloc(bool is_boot_cpu)
{
	struct save_area *sa;

	sa = memblock_alloc_or_panic(sizeof(*sa), 8);

	if (is_boot_cpu)
		list_add(&sa->list, &dump_save_areas);
	else
		list_add_tail(&sa->list, &dump_save_areas);
	return sa;
}

/*
 * Return the address of the save area for the boot CPU
 */
struct save_area * __init save_area_boot_cpu(void)
{
	return list_first_entry_or_null(&dump_save_areas, struct save_area, list);
}

/*
 * Copy CPU registers into the save area
 */
void __init save_area_add_regs(struct save_area *sa, void *regs)
{
	struct lowcore *lc;

	lc = (struct lowcore *)(regs - __LC_FPREGS_SAVE_AREA);
	memcpy(&sa->psw, &lc->psw_save_area, sizeof(sa->psw));
	memcpy(&sa->ctrs, &lc->cregs_save_area, sizeof(sa->ctrs));
	memcpy(&sa->gprs, &lc->gpregs_save_area, sizeof(sa->gprs));
	memcpy(&sa->acrs, &lc->access_regs_save_area, sizeof(sa->acrs));
	memcpy(&sa->fprs, &lc->floating_pt_save_area, sizeof(sa->fprs));
	memcpy(&sa->fpc, &lc->fpt_creg_save_area, sizeof(sa->fpc));
	memcpy(&sa->prefix, &lc->prefixreg_save_area, sizeof(sa->prefix));
	memcpy(&sa->todpreg, &lc->tod_progreg_save_area, sizeof(sa->todpreg));
	memcpy(&sa->timer, &lc->cpu_timer_save_area, sizeof(sa->timer));
	memcpy(&sa->todcmp, &lc->clock_comp_save_area, sizeof(sa->todcmp));
}

/*
 * Copy vector registers into the save area
 */
void __init save_area_add_vxrs(struct save_area *sa, __vector128 *vxrs)
{
	int i;

	/* Copy lower halves of vector registers 0-15 */
	for (i = 0; i < 16; i++)
		sa->vxrs_low[i] = vxrs[i].low;
	/* Copy vector registers 16-31 */
	memcpy(sa->vxrs_high, vxrs + 16, 16 * sizeof(__vector128));
}

static size_t copy_oldmem_iter(struct iov_iter *iter, unsigned long src, size_t count)
{
	size_t len, copied, res = 0;

	while (count) {
		if (!oldmem_data.start && src < sclp.hsa_size) {
			/* Copy from zfcp/nvme dump HSA area */
			len = min(count, sclp.hsa_size - src);
			copied = memcpy_hsa_iter(iter, src, len);
		} else {
			/* Check for swapped kdump oldmem areas */
			if (oldmem_data.start && src - oldmem_data.start < oldmem_data.size) {
				src -= oldmem_data.start;
				len = min(count, oldmem_data.size - src);

Annotation

Implementation Notes