diff options
| -rw-r--r-- | arch/powerpc/platforms/powernv/opal.c | 28 | 
1 files changed, 20 insertions, 8 deletions
| diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index 778a2793e75b..3697772e3759 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -102,13 +102,13 @@ int __init early_init_dt_scan_opal(unsigned long node,  int __init early_init_dt_scan_recoverable_ranges(unsigned long node,  				   const char *uname, int depth, void *data)  { -	unsigned long i, size; +	unsigned long i, psize, size;  	const __be32 *prop;  	if (depth != 1 || strcmp(uname, "ibm,opal") != 0)  		return 0; -	prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &size); +	prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &psize);  	if (!prop)  		return 1; @@ -116,6 +116,23 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,  	pr_debug("Found machine check recoverable ranges.\n");  	/* +	 * Calculate number of available entries. +	 * +	 * Each recoverable address range entry is (start address, len, +	 * recovery address), 2 cells each for start and recovery address, +	 * 1 cell for len, totalling 5 cells per entry. +	 */ +	mc_recoverable_range_len = psize / (sizeof(*prop) * 5); + +	/* Sanity check */ +	if (!mc_recoverable_range_len) +		return 1; + +	/* Size required to hold all the entries. */ +	size = mc_recoverable_range_len * +			sizeof(struct mcheck_recoverable_range); + +	/*  	 * Allocate a buffer to hold the MC recoverable ranges. We would be  	 * accessing them in real mode, hence it needs to be within  	 * RMO region. @@ -124,11 +141,7 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,  							ppc64_rma_size));  	memset(mc_recoverable_range, 0, size); -	/* -	 * Each recoverable address entry is an (start address,len, -	 * recover address) pair, * 2 cells each, totalling 4 cells per entry. -	 */ -	for (i = 0; i < size / (sizeof(*prop) * 5); i++) { +	for (i = 0; i < mc_recoverable_range_len; i++) {  		mc_recoverable_range[i].start_addr =  					of_read_number(prop + (i * 5) + 0, 2);  		mc_recoverable_range[i].end_addr = @@ -142,7 +155,6 @@ int __init early_init_dt_scan_recoverable_ranges(unsigned long node,  				mc_recoverable_range[i].end_addr,  				mc_recoverable_range[i].recover_addr);  	} -	mc_recoverable_range_len = i;  	return 1;  } | 
