/* * Create ELF notes for one CPU */ static void add_elf_notes(int cpu) { struct save_area *sa = (void *) 4608 + store_prefix(); void *ptr; memcpy((void *) (4608UL + sa->pref_reg), sa, sizeof(*sa)); ptr = (u64 *) per_cpu_ptr(crash_notes, cpu); ptr = fill_cpu_elf_notes(ptr, sa); memset(ptr, 0, sizeof(struct elf_note)); }
static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { if (ipl_info.type != IPL_TYPE_FCP_DUMP) return; if (cpu >= NR_CPUS) { pr_warning("CPU %i exceeds the maximum %i and is excluded from " "the dump\n", cpu, NR_CPUS - 1); return; } zfcpdump_save_areas[cpu] = kmalloc(sizeof(struct save_area), GFP_KERNEL); while (raw_sigp(phy_cpu, sigp_stop_and_store_status) == sigp_busy) cpu_relax(); memcpy_real(zfcpdump_save_areas[cpu], (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE, sizeof(struct save_area)); }
/* * Store status of next available physical CPU */ static int store_status_next(int start_cpu, int this_cpu) { struct save_area_s390x *sa = (void *) 4608 + store_prefix(); int cpu, rc; for (cpu = start_cpu; cpu < 65536; cpu++) { if (cpu == this_cpu) continue; do { rc = raw_sigp(cpu, sigp_stop_and_store_status); } while (rc == sigp_busy); if (rc != sigp_order_code_accepted) continue; if (sa->pref_reg) return cpu; } return -1; }