diff options
Diffstat (limited to 'drivers/s390/char/zcore.c')
| -rw-r--r-- | drivers/s390/char/zcore.c | 86 | 
1 files changed, 30 insertions, 56 deletions
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c index 794820a123d..1884653e447 100644 --- a/drivers/s390/char/zcore.c +++ b/drivers/s390/char/zcore.c @@ -17,6 +17,8 @@  #include <linux/miscdevice.h>  #include <linux/debugfs.h>  #include <linux/module.h> +#include <linux/memblock.h> +  #include <asm/asm-offsets.h>  #include <asm/ipl.h>  #include <asm/sclp.h> @@ -151,7 +153,7 @@ static int __init init_cpu_info(enum arch_id arch)  	/* 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)  		return -ENOMEM;  	if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) { @@ -159,7 +161,6 @@ static int __init init_cpu_info(enum arch_id arch)  		kfree(sa);  		return -EIO;  	} -	zfcpdump_save_areas[0] = sa;  	return 0;  } @@ -246,24 +247,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)  {  	unsigned long end; -	int i = 0; +	int i;  	if (count == 0)  		return 0;  	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 sa_start, sa_end; /* save area range */  		unsigned long prefix;  		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_end = prefix + sys_info.sa_base + sys_info.sa_size;  		if ((end < sa_start) || (start > sa_end)) -			goto next; +			continue;  		cp_start = max(start, sa_start);  		cp_end = min(end, sa_end); @@ -272,10 +274,8 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)  		len = cp_end - cp_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; -next: -		i++;  	}  	return 0;  } @@ -330,9 +330,9 @@ static ssize_t zcore_read(struct file *file, char __user *buf, size_t count,  	mem_offs = 0;  	/* Copy from HSA data */ -	if (*ppos < (ZFCPDUMP_HSA_SIZE + HEADER_SIZE)) { -		size = min((count - hdr_count), (size_t) (ZFCPDUMP_HSA_SIZE -			   - mem_start)); +	if (*ppos < sclp_get_hsa_size() + HEADER_SIZE) { +		size = min((count - hdr_count), +			   (size_t) (sclp_get_hsa_size() - mem_start));  		rc = memcpy_hsa_user(buf + hdr_count, mem_start, size);  		if (rc)  			goto fail; @@ -413,33 +413,24 @@ static ssize_t zcore_memmap_read(struct file *filp, char __user *buf,  				 size_t count, loff_t *ppos)  {  	return simple_read_from_buffer(buf, count, ppos, filp->private_data, -				       MEMORY_CHUNKS * CHUNK_INFO_SIZE); +				       memblock.memory.cnt * CHUNK_INFO_SIZE);  }  static int zcore_memmap_open(struct inode *inode, struct file *filp)  { -	int i; +	struct memblock_region *reg;  	char *buf; -	struct mem_chunk *chunk_array; +	int i = 0; -	chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk), -			      GFP_KERNEL); -	if (!chunk_array) -		return -ENOMEM; -	detect_memory_layout(chunk_array, 0); -	buf = kzalloc(MEMORY_CHUNKS * CHUNK_INFO_SIZE, GFP_KERNEL); +	buf = kzalloc(memblock.memory.cnt * CHUNK_INFO_SIZE, GFP_KERNEL);  	if (!buf) { -		kfree(chunk_array);  		return -ENOMEM;  	} -	for (i = 0; i < MEMORY_CHUNKS; i++) { -		sprintf(buf + (i * CHUNK_INFO_SIZE), "%016llx %016llx ", -			(unsigned long long) chunk_array[i].addr, -			(unsigned long long) chunk_array[i].size); -		if (chunk_array[i].size == 0) -			break; +	for_each_memblock(memory, reg) { +		sprintf(buf + (i++ * CHUNK_INFO_SIZE), "%016llx %016llx ", +			(unsigned long long) reg->base, +			(unsigned long long) reg->size);  	} -	kfree(chunk_array);  	filp->private_data = buf;  	return nonseekable_open(inode, filp);  } @@ -492,7 +483,7 @@ static ssize_t zcore_hsa_read(struct file *filp, char __user *buf,  	static char str[18];  	if (hsa_available) -		snprintf(str, sizeof(str), "%lx\n", ZFCPDUMP_HSA_SIZE); +		snprintf(str, sizeof(str), "%lx\n", sclp_get_hsa_size());  	else  		snprintf(str, sizeof(str), "0\n");  	return simple_read_from_buffer(buf, count, ppos, str, strlen(str)); @@ -586,38 +577,21 @@ static int __init sys_info_init(enum arch_id arch, unsigned long mem_end)  static int __init check_sdias(void)  { -	int rc, act_hsa_size; - -	rc = sclp_sdias_blk_count(); -	if (rc < 0) { +	if (!sclp_get_hsa_size()) {  		TRACE("Could not determine HSA size\n"); -		return rc; -	} -	act_hsa_size = (rc - 1) * PAGE_SIZE; -	if (act_hsa_size < ZFCPDUMP_HSA_SIZE) { -		TRACE("HSA size too small: %i\n", act_hsa_size); -		return -EINVAL; +		return -ENODEV;  	}  	return 0;  }  static int __init get_mem_info(unsigned long *mem, unsigned long *end)  { -	int i; -	struct mem_chunk *chunk_array; +	struct memblock_region *reg; -	chunk_array = kzalloc(MEMORY_CHUNKS * sizeof(struct mem_chunk), -			      GFP_KERNEL); -	if (!chunk_array) -		return -ENOMEM; -	detect_memory_layout(chunk_array, 0); -	for (i = 0; i < MEMORY_CHUNKS; i++) { -		if (chunk_array[i].size == 0) -			break; -		*mem += chunk_array[i].size; -		*end = max(*end, chunk_array[i].addr + chunk_array[i].size); +	for_each_memblock(memory, reg) { +		*mem += reg->size; +		*end = max_t(unsigned long, *end, reg->base + reg->size);  	} -	kfree(chunk_array);  	return 0;  } @@ -637,8 +611,8 @@ static void __init zcore_header_init(int arch, struct zcore_header *hdr,  	hdr->num_pages = mem_size / PAGE_SIZE;  	hdr->tod = get_tod_clock();  	get_cpu_id(&hdr->cpu_id); -	for (i = 0; zfcpdump_save_areas[i]; i++) { -		prefix = zfcpdump_save_areas[i]->pref_reg; +	for (i = 0; i < dump_save_areas.count; i++) { +		prefix = dump_save_areas.areas[i]->pref_reg;  		hdr->real_cpu_cnt++;  		if (!prefix)  			continue; @@ -664,7 +638,7 @@ static int __init zcore_reipl_init(void)  	ipl_block = (void *) __get_free_page(GFP_KERNEL);  	if (!ipl_block)  		return -ENOMEM; -	if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE) +	if (ipib_info.ipib < sclp_get_hsa_size())  		rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);  	else  		rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);  | 
