On 10/23/15, Nathan Fontenot <nf...@linux.vnet.ibm.com> wrote: > When DLPAR adding a CPU we should verify that the CPU does not already > exist. Failure to do so can generate a kernel oops; > > [ 9.465585] kernel BUG at arch/powerpc/platforms/pseries/dlpar.c:382! > [ 9.465796] Oops: Exception in kernel mode, sig: 5 [#1] > > This oops can be generated by causing a probe to be performed on a cpu > by writing to the sysfs cpu probe file (/sys/devices/system/cpu/probe). > This patch adds a check for the existence of cpu prior to probing the cpu > so userspace doing the wrong thing won't trigger a BUG_ON().
Hi Nathan, Can you please tell how to trigger the oops manually since I've tried to write a core number to the probe file, but with no luck. Always get -EINVAL. Thanks! > > Signed-off-by: Nathan Fontenot <nf...@linux.vnet.ibm.com> > --- > arch/powerpc/platforms/pseries/dlpar.c | 43 > +++++++++++++++++++++++++++++--- > 1 file changed, 39 insertions(+), 4 deletions(-) > > diff --git a/arch/powerpc/platforms/pseries/dlpar.c > b/arch/powerpc/platforms/pseries/dlpar.c > index f244dcb..fe6320d 100644 > --- a/arch/powerpc/platforms/pseries/dlpar.c > +++ b/arch/powerpc/platforms/pseries/dlpar.c > @@ -381,6 +381,32 @@ out: > > } > > +static bool dlpar_cpu_exists(struct device_node *parent, u32 drc_index) > +{ > + struct device_node *child = NULL; > + u32 my_drc_index; > + bool found; > + int rc; > + > + /* Assume cpu doesn't exist */ > + found = false; > + > + for_each_child_of_node(parent, child) { > + rc = of_property_read_u32(child, "ibm,my-drc-index", > + &my_drc_index); > + if (rc) > + continue; > + > + if (my_drc_index == drc_index) { > + of_node_put(child); > + found = true; > + break; > + } > + } > + > + return found; > +} > + > static ssize_t dlpar_cpu_probe(const char *buf, size_t count) > { > struct device_node *dn, *parent; > @@ -391,14 +417,23 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t > count) > if (rc) > return -EINVAL; > > - rc = dlpar_acquire_drc(drc_index); > - if (rc) > - return -EINVAL; > - > parent = of_find_node_by_path("/cpus"); > if (!parent) > return -ENODEV; > > + if (dlpar_cpu_exists(parent, drc_index)) { > + of_node_put(parent); > + printk(KERN_WARNING "CPU with drc index %x already exists\n", > + drc_index); > + return -EINVAL; > + } > + > + rc = dlpar_acquire_drc(drc_index); > + if (rc) { > + of_node_put(parent); > + return -EINVAL; > + } > + > dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent); > of_node_put(parent); > if (!dn) { > > _______________________________________________ > Linuxppc-dev mailing list > Linuxppc-dev@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/linuxppc-dev _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev