Some versions of QEMU will produce an ibm,dynamic-reconfiguration-memory node with a ibm,dynamic-memory property that is zero-filled. This causes the drmem code to oops trying to parse this property.
The fix for this is to validate that the property does contain LMB entries before trying to parse it and bail if the count is zero. Oops: Kernel access of bad area, sig: 11 [#1] SMP NR_CPUS=2048 NUMA pSeries Modules linked in: Supported: Yes CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.12.14-11.2-default #1 task: c00000007e639680 task.stack: c00000007e648000 NIP: c000000000c709a4 LR: c000000000c70998 CTR: 0000000000000000 REGS: c00000007e64b8d0 TRAP: 0300 Not tainted (4.12.14-11.2-default) MSR: 800000010280b033 <SF,VEC,VSX,EE,FP,ME,IR,DR,RI,LE,TM[E]> CR: 84000248 XER: 00000000 CFAR: c00000000067018c DAR: 0000000000000010 DSISR: 42000000 SOFTE: 1 GPR00: c000000000c70998 c00000007e64bb50 c000000001157b00 0000000000000000 GPR04: c00000007e64bb70 0000000000000000 000000000000002f 0000000000000022 GPR08: 0000000000000003 c000000006f63fac c000000006f63fb0 000000000000001e GPR12: 0000000000000000 c00000000fa80000 c00000000000dca8 0000000000000000 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR20: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR24: c000000000cccb98 c000000000c636f0 c000000000c56cd0 0000000000000007 GPR28: c000000000cccba8 c00000007ffffc30 c00000007e64bbf0 0000000000000010 NIP [c000000000c709a4] read_drconf_v1_cell+0x54/0x9c LR [c000000000c70998] read_drconf_v1_cell+0x48/0x9c Call Trace: [c00000007e64bb50] [c000000000c56cd0] __param_initcall_debug+0x0/0x28 (unreliable) [c00000007e64bb90] [c000000000c70e24] drmem_init+0x144/0x2f8 [c00000007e64bc40] [c00000000000d034] do_one_initcall+0x64/0x1d0 [c00000007e64bd00] [c000000000c643d0] kernel_init_freeable+0x298/0x38c [c00000007e64bdc0] [c00000000000dcc4] kernel_init+0x24/0x160 [c00000007e64be30] [c00000000000b428] ret_from_kernel_thread+0x5c/0xb4 Instruction dump: 7c9e2378 60000000 e9429050 e93e0000 7c240b78 7c7f1b78 f9240021 e86a0002 4804e41d 60000000 e9210020 39490004 <f87f0000> f9410020 39490010 7d004c2c The ibm,dynamic-reconfiguration-memory device tree property generated that causes this: ibm,dynamic-reconfiguration-memory { ibm,lmb-size = <0x0 0x10000000>; ibm,memory-flags-mask = <0xff>; ibm,dynamic-memory = <0x0 0x0 0x0 0x0 0x0 0x0>; linux,phandle = <0x7e57eed8>; ibm,associativity-lookup-arrays = <0x1 0x4 0x0 0x0 0x0 0x0>; ibm,memory-preservation-time = <0x0>; }; Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com> --- arch/powerpc/mm/drmem.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/powerpc/mm/drmem.c b/arch/powerpc/mm/drmem.c index 1604110c4238..916844f99c64 100644 --- a/arch/powerpc/mm/drmem.c +++ b/arch/powerpc/mm/drmem.c @@ -216,6 +216,8 @@ static void __init __walk_drmem_v1_lmbs(const __be32 *prop, const __be32 *usm, u32 i, n_lmbs; n_lmbs = of_read_number(prop++, 1); + if (n_lmbs == 0) + return; for (i = 0; i < n_lmbs; i++) { read_drconf_v1_cell(&lmb, &prop); @@ -245,6 +247,8 @@ static void __init __walk_drmem_v2_lmbs(const __be32 *prop, const __be32 *usm, u32 i, j, lmb_sets; lmb_sets = of_read_number(prop++, 1); + if (lmb_sets == 0) + return; for (i = 0; i < lmb_sets; i++) { read_drconf_v2_cell(&dr_cell, &prop); @@ -354,6 +358,8 @@ static void __init init_drmem_v1_lmbs(const __be32 *prop) struct drmem_lmb *lmb; drmem_info->n_lmbs = of_read_number(prop++, 1); + if (drmem_info->n_lmbs == 0) + return; drmem_info->lmbs = kcalloc(drmem_info->n_lmbs, sizeof(*lmb), GFP_KERNEL); @@ -373,6 +379,8 @@ static void __init init_drmem_v2_lmbs(const __be32 *prop) int lmb_index; lmb_sets = of_read_number(prop++, 1); + if (lmb_sets == 0) + return; /* first pass, calculate the number of LMBs */ p = prop;