Commit 58952942 authored by Michael Holzheu's avatar Michael Holzheu Committed by Martin Schwidefsky

s390: Remove zfcpdump NR_CPUS dependency

Currently zfpcdump can only collect registers for up to CONFIG_NR_CPUS
CPUss. This dependency is not necessary. So remove it by dynamically
allocating the save area array.
Signed-off-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Reviewed-by: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 05e0baaf
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#ifndef _ASM_S390_IPL_H #ifndef _ASM_S390_IPL_H
#define _ASM_S390_IPL_H #define _ASM_S390_IPL_H
#include <asm/lowcore.h>
#include <asm/types.h> #include <asm/types.h>
#include <asm/cio.h> #include <asm/cio.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -88,6 +89,14 @@ extern u32 ipl_flags; ...@@ -88,6 +89,14 @@ extern u32 ipl_flags;
extern u32 dump_prefix_page; extern u32 dump_prefix_page;
extern unsigned int zfcpdump_prefix_array[]; extern unsigned int zfcpdump_prefix_array[];
struct dump_save_areas {
struct save_area **areas;
int count;
};
extern struct dump_save_areas dump_save_areas;
struct save_area *dump_save_area_create(int cpu);
extern void do_reipl(void); extern void do_reipl(void);
extern void do_halt(void); extern void do_halt(void);
extern void do_poff(void); extern void do_poff(void);
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#define raw_smp_processor_id() (S390_lowcore.cpu_nr) #define raw_smp_processor_id() (S390_lowcore.cpu_nr)
extern struct mutex smp_cpu_state_mutex; extern struct mutex smp_cpu_state_mutex;
extern struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
extern int __cpu_up(unsigned int cpu, struct task_struct *tidle); extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);
......
...@@ -22,6 +22,32 @@ ...@@ -22,6 +22,32 @@
#define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y))) #define PTR_SUB(x, y) (((char *) (x)) - ((unsigned long) (y)))
#define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y)))) #define PTR_DIFF(x, y) ((unsigned long)(((char *) (x)) - ((unsigned long) (y))))
struct dump_save_areas dump_save_areas;
/*
* Allocate and add a save area for a CPU
*/
struct save_area *dump_save_area_create(int cpu)
{
struct save_area **save_areas, *save_area;
save_area = kmalloc(sizeof(*save_area), GFP_KERNEL);
if (!save_area)
return NULL;
if (cpu + 1 > dump_save_areas.count) {
dump_save_areas.count = cpu + 1;
save_areas = krealloc(dump_save_areas.areas,
dump_save_areas.count * sizeof(void *),
GFP_KERNEL | __GFP_ZERO);
if (!save_areas) {
kfree(save_area);
return NULL;
}
dump_save_areas.areas = save_areas;
}
dump_save_areas.areas[cpu] = save_area;
return save_area;
}
/* /*
* Return physical address for virtual address * Return physical address for virtual address
...@@ -450,8 +476,8 @@ static int get_cpu_cnt(void) ...@@ -450,8 +476,8 @@ static int get_cpu_cnt(void)
{ {
int i, cpus = 0; int i, cpus = 0;
for (i = 0; zfcpdump_save_areas[i]; i++) { for (i = 0; i < dump_save_areas.count; i++) {
if (zfcpdump_save_areas[i]->pref_reg == 0) if (dump_save_areas.areas[i]->pref_reg == 0)
continue; continue;
cpus++; cpus++;
} }
...@@ -522,8 +548,8 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset) ...@@ -522,8 +548,8 @@ static void *notes_init(Elf64_Phdr *phdr, void *ptr, u64 notes_offset)
ptr = nt_prpsinfo(ptr); ptr = nt_prpsinfo(ptr);
for (i = 0; zfcpdump_save_areas[i]; i++) { for (i = 0; i < dump_save_areas.count; i++) {
sa = zfcpdump_save_areas[i]; sa = dump_save_areas.areas[i];
if (sa->pref_reg == 0) if (sa->pref_reg == 0)
continue; continue;
ptr = fill_cpu_elf_notes(ptr, sa); ptr = fill_cpu_elf_notes(ptr, sa);
......
...@@ -533,9 +533,6 @@ EXPORT_SYMBOL(smp_ctl_clear_bit); ...@@ -533,9 +533,6 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_CRASH_DUMP) #if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_CRASH_DUMP)
struct save_area *zfcpdump_save_areas[NR_CPUS + 1];
EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
static void __init smp_get_save_area(int cpu, u16 address) static void __init smp_get_save_area(int cpu, u16 address)
{ {
void *lc = pcpu_devices[0].lowcore; void *lc = pcpu_devices[0].lowcore;
...@@ -546,15 +543,9 @@ static void __init smp_get_save_area(int cpu, u16 address) ...@@ -546,15 +543,9 @@ static void __init smp_get_save_area(int cpu, u16 address)
if (!OLDMEM_BASE && (address == boot_cpu_address || if (!OLDMEM_BASE && (address == boot_cpu_address ||
ipl_info.type != IPL_TYPE_FCP_DUMP)) ipl_info.type != IPL_TYPE_FCP_DUMP))
return; return;
if (cpu >= NR_CPUS) { save_area = dump_save_area_create(cpu);
pr_warning("CPU %i exceeds the maximum %i and is excluded "
"from the dump\n", cpu, NR_CPUS - 1);
return;
}
save_area = kmalloc(sizeof(struct save_area), GFP_KERNEL);
if (!save_area) if (!save_area)
panic("could not allocate memory for save area\n"); panic("could not allocate memory for save area\n");
zfcpdump_save_areas[cpu] = save_area;
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
if (address == boot_cpu_address) { if (address == boot_cpu_address) {
/* Copy the registers of the boot cpu. */ /* Copy the registers of the boot cpu. */
......
...@@ -151,7 +151,7 @@ static int __init init_cpu_info(enum arch_id arch) ...@@ -151,7 +151,7 @@ static int __init init_cpu_info(enum arch_id arch)
/* get info for boot cpu from lowcore, stored in the HSA */ /* get info for boot cpu from lowcore, stored in the HSA */
sa = kmalloc(sizeof(*sa), GFP_KERNEL); sa = dump_save_area_create(0);
if (!sa) if (!sa)
return -ENOMEM; return -ENOMEM;
if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) { if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) {
...@@ -159,7 +159,6 @@ static int __init init_cpu_info(enum arch_id arch) ...@@ -159,7 +159,6 @@ static int __init init_cpu_info(enum arch_id arch)
kfree(sa); kfree(sa);
return -EIO; return -EIO;
} }
zfcpdump_save_areas[0] = sa;
return 0; return 0;
} }
...@@ -246,24 +245,25 @@ static int copy_lc(void __user *buf, void *sa, int sa_off, int len) ...@@ -246,24 +245,25 @@ static int copy_lc(void __user *buf, void *sa, int sa_off, int len)
static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
{ {
unsigned long end; unsigned long end;
int i = 0; int i;
if (count == 0) if (count == 0)
return 0; return 0;
end = start + count; end = start + count;
while (zfcpdump_save_areas[i]) { for (i = 0; i < dump_save_areas.count; i++) {
unsigned long cp_start, cp_end; /* copy range */ unsigned long cp_start, cp_end; /* copy range */
unsigned long sa_start, sa_end; /* save area range */ unsigned long sa_start, sa_end; /* save area range */
unsigned long prefix; unsigned long prefix;
unsigned long sa_off, len, buf_off; unsigned long sa_off, len, buf_off;
struct save_area *save_area = dump_save_areas.areas[i];
prefix = zfcpdump_save_areas[i]->pref_reg; prefix = save_area->pref_reg;
sa_start = prefix + sys_info.sa_base; sa_start = prefix + sys_info.sa_base;
sa_end = prefix + sys_info.sa_base + sys_info.sa_size; sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
if ((end < sa_start) || (start > sa_end)) if ((end < sa_start) || (start > sa_end))
goto next; continue;
cp_start = max(start, sa_start); cp_start = max(start, sa_start);
cp_end = min(end, sa_end); cp_end = min(end, sa_end);
...@@ -272,10 +272,8 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count) ...@@ -272,10 +272,8 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
len = cp_end - cp_start; len = cp_end - cp_start;
TRACE("copy_lc for: %lx\n", start); TRACE("copy_lc for: %lx\n", start);
if (copy_lc(buf + buf_off, zfcpdump_save_areas[i], sa_off, len)) if (copy_lc(buf + buf_off, save_area, sa_off, len))
return -EFAULT; return -EFAULT;
next:
i++;
} }
return 0; return 0;
} }
...@@ -637,8 +635,8 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr, ...@@ -637,8 +635,8 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr,
hdr->num_pages = mem_size / PAGE_SIZE; hdr->num_pages = mem_size / PAGE_SIZE;
hdr->tod = get_tod_clock(); hdr->tod = get_tod_clock();
get_cpu_id(&hdr->cpu_id); get_cpu_id(&hdr->cpu_id);
for (i = 0; zfcpdump_save_areas[i]; i++) { for (i = 0; i < dump_save_areas.count; i++) {
prefix = zfcpdump_save_areas[i]->pref_reg; prefix = dump_save_areas.areas[i]->pref_reg;
hdr->real_cpu_cnt++; hdr->real_cpu_cnt++;
if (!prefix) if (!prefix)
continue; continue;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment