From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from e36.co.us.ibm.com (e36.co.us.ibm.com [32.97.110.154]) (using TLSv1 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 0F2F11A0387 for ; Tue, 27 Oct 2015 06:53:14 +1100 (AEDT) Received: from localhost by e36.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Mon, 26 Oct 2015 13:53:12 -0600 Received: from b03cxnp08026.gho.boulder.ibm.com (b03cxnp08026.gho.boulder.ibm.com [9.17.130.18]) by d03dlp01.boulder.ibm.com (Postfix) with ESMTP id 9F21A1FF004A for ; Mon, 26 Oct 2015 13:41:22 -0600 (MDT) Received: from d03av03.boulder.ibm.com (d03av03.boulder.ibm.com [9.17.195.169]) by b03cxnp08026.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id t9QJq5HP5636518 for ; Mon, 26 Oct 2015 12:52:05 -0700 Received: from d03av03.boulder.ibm.com (localhost [127.0.0.1]) by d03av03.boulder.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id t9QJrAPi029139 for ; Mon, 26 Oct 2015 13:53:10 -0600 Subject: Re: [PATCH] powerpc/pseries: Verify CPU doesn't exist before adding To: Denis Kirjanov References: <562A7255.7010607@linux.vnet.ibm.com> Cc: "linuxppc-dev@lists.ozlabs.org" From: Nathan Fontenot Message-ID: <562E84A5.9000802@linux.vnet.ibm.com> Date: Mon, 26 Oct 2015 14:53:09 -0500 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8 List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , On 10/25/2015 11:30 AM, Denis Kirjanov wrote: > On 10/23/15, Nathan Fontenot 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. Triggering the oops manually may be a bit trickier than just writing to the sysfs file. First, make sure you are writing the drc index of a cpu that is already present. You can see a list of present cpus with 'lsslot -c cpu'. You may be able to trigger the oops by just writing the drc index to the sysfs file but will likely get -EINVAL since the probe code tries to acquire the cpu from firmware and call configure-connector, both of which will likely fail before we try to online the cpu and see the BUG_ON. For a kvm guest, you should be able to generate the oops by killing the rtas_errd daemon, do a cpu hotplug add from the host, then reboot the guest. If the rtas_errd daemon is set to autostart you should see the oops at boot, otherwise you can manually start rtas_errd and see the oops. For a Power LPAR, the process would be much trickier. You would have to do some hacking to the drmgr command (which write the drc index to the probe file) to trick it into trying to add the same cpu twice when invoking cpu hotplug from the HMC. Hope that helps. -Nathan > > Thanks! >> >> Signed-off-by: Nathan Fontenot >> --- >> 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 >