On Thu, 2018-02-15 at 21:27 -0600, Nathan Fontenot wrote: > 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>
Works for me. Reviewed-by: Cyril Bur <cyril...@gmail.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; >