[PATCH 1/4] drmgr/pci: Enable in-kernel functionality to update device tree

14 views
Skip to first unread message

Haren Myneni

<haren@linux.ibm.com>
unread,
Aug 13, 2024, 5:40:39 PM8/13/24
to powerpc-utils-devel@googlegroups.com, hbabu@us.ibm.com, Haren Myneni
drmgr updates the device tree by writing to /proc/ppc64/ofdt. Also
invokes configure_connector RTAS call to retrieve new device nodes
for IO ADD. But this functionality need /dev/mem access which is
restricted under system lockdown.

The kernel updates provided a sysfs file (/sys/kernel/dlpar) that
will allow drmgr command invoke the following interfaces to update
the device tree.

dt add index <DRC index> ---> To add new device nodes to the device
tree which is used for IO ADD.

dt remove index <DRC index> ---> To remove device nodes for IO
REMOVE

This patch checks the kernel interface for the availability of
device tree update feature and adds do_dt_kernel_dlpar() to invoke
the above kernel interfaces.

Signed-off-by: Haren Myneni <ha...@linux.ibm.com>
---
src/drmgr/common.c | 6 ++++++
src/drmgr/common_pci.c | 29 +++++++++++++++++++++++++++++
src/drmgr/dr.h | 1 +
3 files changed, 36 insertions(+)

diff --git a/src/drmgr/common.c b/src/drmgr/common.c
index bfec0b9..70f4dfd 100644
--- a/src/drmgr/common.c
+++ b/src/drmgr/common.c
@@ -1504,6 +1504,12 @@ int kernel_dlpar_exists(void)
if (strstr(buf, "cpu"))
return 1;
break;
+ case DRC_TYPE_PCI:
+ case DRC_TYPE_PHB:
+ case DRC_TYPE_SLOT:
+ if (strstr(buf, "dt"))
+ return 1;
+ break;
default:
return 0;
}
diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index 759589a..109e0d2 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -1619,3 +1619,32 @@ int disable_hp_children(char *drc_name)
}
return 0;
}
+
+/*
+ * kernel interface to update device tree nodes.
+ * dlpar dt [add|remove] index <#drc index>
+ */
+int do_dt_kernel_dlpar(uint32_t index, int action)
+{
+ char cmdbuf[256];
+ int offset;
+
+ offset = sprintf(cmdbuf, "%s ", "dt");
+
+ switch (action) {
+ case ADD:
+ offset += sprintf(cmdbuf + offset, "add ");
+ break;
+ case REMOVE:
+ offset += sprintf(cmdbuf + offset, "remove ");
+ break;
+ default:
+ /* Should not happen */
+ say(ERROR, "Invalid action type specified\n");
+ return -EINVAL;
+ }
+
+ offset += sprintf(cmdbuf + offset, "index 0x%x", index);
+
+ return do_kernel_dlpar(cmdbuf, offset);
+}
diff --git a/src/drmgr/dr.h b/src/drmgr/dr.h
index 60c31c4..72ede55 100644
--- a/src/drmgr/dr.h
+++ b/src/drmgr/dr.h
@@ -188,4 +188,5 @@ static inline int do_kernel_dlpar(const char *cmd, int len)
{
return do_kernel_dlpar_common(cmd, len, 0);
}
+int do_dt_kernel_dlpar(uint32_t, int);
#endif
--
2.43.5

Haren Myneni

<haren@linux.ibm.com>
unread,
Aug 13, 2024, 5:40:42 PM8/13/24
to powerpc-utils-devel@googlegroups.com, hbabu@us.ibm.com, Haren Myneni
Use the following kernel interfaces for PHB device type to update
the device tree if this feature is enabled in the kernel.

dt add index <DRC index> --> for IO add
dt remove index <DRC index> --> for IO remove

Signed-off-by: Haren Myneni <ha...@linux.ibm.com>
---
src/drmgr/common_pci.c | 29 +++++++++++++++++++++-------
src/drmgr/drslot_chrp_phb.c | 38 ++++++++++++++++++++-----------------
2 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/src/drmgr/common_pci.c b/src/drmgr/common_pci.c
index 109e0d2..683d72d 100644
--- a/src/drmgr/common_pci.c
+++ b/src/drmgr/common_pci.c
@@ -1390,7 +1390,6 @@ print_node_list(struct dr_node *first_node)
static int
acquire_hp_resource(struct dr_connector *drc, char *of_path)
{
- struct of_node *new_nodes;
int state;
int rc;

@@ -1429,12 +1428,21 @@ acquire_hp_resource(struct dr_connector *drc, char *of_path)
}

if (state == PRESENT) {
- new_nodes = configure_connector(drc->index);
- if (new_nodes == NULL)
- return -1;
+ /*
+ * Use kernel DLPAR interface if it is enabled
+ */
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(drc->index, ADD);
+ } else {
+ struct of_node *new_nodes;
+
+ new_nodes = configure_connector(drc->index);
+ if (new_nodes == NULL)
+ return -1;

- rc = add_device_tree_nodes(of_path, new_nodes);
- free_of_node(new_nodes);
+ rc = add_device_tree_nodes(of_path, new_nodes);
+ free_of_node(new_nodes);
+ }
if (rc) {
say(ERROR, "add nodes failed for 0x%x\n", drc->index);
return rc;
@@ -1490,7 +1498,14 @@ release_hp_resource(struct dr_node *node)
{
int rc;

- rc = remove_device_tree_nodes(node->ofdt_path);
+ /*
+ * Use kernel DLPAR interface if it is enabled
+ */
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(node->drc_index, REMOVE);
+ else
+ rc = remove_device_tree_nodes(node->ofdt_path);
+
if (rc) {
say(ERROR, "failed to remove kernel nodes for index 0x%x\n",
node->drc_index);
diff --git a/src/drmgr/drslot_chrp_phb.c b/src/drmgr/drslot_chrp_phb.c
index 220d844..5bf3030 100644
--- a/src/drmgr/drslot_chrp_phb.c
+++ b/src/drmgr/drslot_chrp_phb.c
@@ -108,17 +108,16 @@ release_phb(struct dr_node *phb)
{
int rc;

- rc = remove_device_tree_nodes(phb->ofdt_path);
- if (rc)
- return rc;
-
- if (phb->phb_ic_ofdt_path[0] != '\0') {
- rc = remove_device_tree_nodes(phb->phb_ic_ofdt_path);
- if (rc)
- return rc;
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(phb->drc_index, REMOVE);
+ else {
+ rc = remove_device_tree_nodes(phb->ofdt_path);
+ if (!rc && (phb->phb_ic_ofdt_path[0] != '\0'))
+ rc = remove_device_tree_nodes(phb->phb_ic_ofdt_path);
}

- rc = release_drc(phb->drc_index, PHB_DEV);
+ if (!rc)
+ rc = release_drc(phb->drc_index, PHB_DEV);

return rc;
}
@@ -390,7 +389,6 @@ phb_remove_error:
static int acquire_phb(char *drc_name, struct dr_node **phb)
{
struct dr_connector drc;
- struct of_node *of_nodes;
char path[DR_PATH_MAX];
int rc;

@@ -405,14 +403,20 @@ static int acquire_phb(char *drc_name, struct dr_node **phb)
if (rc)
return rc;

- of_nodes = configure_connector(drc.index);
- if (of_nodes == NULL) {
- release_drc(drc.index, PHB_DEV);
- return -1;
- }
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(drc.index, ADD);
+ } else {
+ struct of_node *of_nodes;

- rc = add_device_tree_nodes(path, of_nodes);
- free_of_node(of_nodes);
+ of_nodes = configure_connector(drc.index);
+ if (of_nodes == NULL) {
+ release_drc(drc.index, PHB_DEV);
+ return -1;
+ }
+
+ rc = add_device_tree_nodes(path, of_nodes);
+ free_of_node(of_nodes);
+ }
if (rc) {
say(ERROR, "add_device_tree_nodes failed at %s\n", path);
release_drc(drc.index, PHB_DEV);
--
2.43.5

Haren Myneni

<haren@linux.ibm.com>
unread,
Aug 13, 2024, 5:40:43 PM8/13/24
to powerpc-utils-devel@googlegroups.com, hbabu@us.ibm.com, Haren Myneni
Use the following kernel interfaces for PCI device type to update
the device tree if this feature is enabled in the kernel.

dt add index <DRC index> --> for IO add
dt remove index <DRC index> --> for IO remove

Signed-off-by: Haren Myneni <ha...@linux.ibm.com>
---
src/drmgr/drslot_chrp_pci.c | 32 ++++++++++++++++++++++----------
1 file changed, 22 insertions(+), 10 deletions(-)

diff --git a/src/drmgr/drslot_chrp_pci.c b/src/drmgr/drslot_chrp_pci.c
index ed420d7..66ac5ae 100644
--- a/src/drmgr/drslot_chrp_pci.c
+++ b/src/drmgr/drslot_chrp_pci.c
@@ -377,7 +377,6 @@ static int add_work(struct dr_node *node, bool partner_device)
/* on when */
int iso_state = ISOLATE; /* Tells us isolation state after */
int rc;
- struct of_node *new_nodes;/* nodes returned from configure_connector */

/*
* Already checked the card presence for the original device
@@ -445,16 +444,26 @@ static int add_work(struct dr_node *node, bool partner_device)
* the return status requires a message, print it out
* and exit, otherwise, add the nodes to the OF tree.
*/
- new_nodes = configure_connector(node->drc_index);
- if (new_nodes == NULL) {
- rtas_set_indicator(ISOLATION_STATE, node->drc_index, ISOLATE);
- set_power(node->drc_power, POWER_OFF);
- return -1;
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(node->drc_index, ADD);
+ } else {
+ struct of_node *new_nodes; /* nodes returned from */
+ /* configure_connector */
+
+ new_nodes = configure_connector(node->drc_index);
+ if (new_nodes == NULL) {
+ rtas_set_indicator(ISOLATION_STATE, node->drc_index,
+ ISOLATE);
+ set_power(node->drc_power, POWER_OFF);
+ return -1;
+ }
+
+ say(DEBUG, "Adding %s to %s\n", new_nodes->name,
+ node->ofdt_path);
+ rc = add_device_tree_nodes(node->ofdt_path, new_nodes);
+ free_of_node(new_nodes);
}

- say(DEBUG, "Adding %s to %s\n", new_nodes->name, node->ofdt_path);
- rc = add_device_tree_nodes(node->ofdt_path, new_nodes);
- free_of_node(new_nodes);
if (rc) {
say(DEBUG, "add_device_tree_nodes failed at %s\n",
node->ofdt_path);
@@ -786,7 +795,10 @@ static int remove_work(struct dr_node *node, bool partner_device)
* the device tree.
*/
for (child = node->children; child; child = child->next) {
- rc = remove_device_tree_nodes(child->ofdt_path);
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(child->drc_index, REMOVE);
+ else
+ rc = remove_device_tree_nodes(child->ofdt_path);
if (rc) {
say(ERROR, "%s", sw_error);
rtas_set_indicator(ISOLATION_STATE, node->drc_index,
--
2.43.5

Haren Myneni

<haren@linux.ibm.com>
unread,
Aug 13, 2024, 5:40:45 PM8/13/24
to powerpc-utils-devel@googlegroups.com, hbabu@us.ibm.com, Haren Myneni
Use the following kernel interfaces for SLOT device type to update
the device tree if this feature is enabled in the kernel.

dt add index <DRC index> --> for IO add
dt remove index <DRC index> --> for IO remove

Signed-off-by: Haren Myneni <ha...@linux.ibm.com>
---
src/drmgr/drslot_chrp_slot.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/drmgr/drslot_chrp_slot.c b/src/drmgr/drslot_chrp_slot.c
index 0966c25..180b108 100644
--- a/src/drmgr/drslot_chrp_slot.c
+++ b/src/drmgr/drslot_chrp_slot.c
@@ -71,7 +71,10 @@ release_slot(struct dr_node *slot)
if (rc)
return rc;

- rc = remove_device_tree_nodes(slot->ofdt_path);
+ if (kernel_dlpar_exists())
+ rc = do_dt_kernel_dlpar(slot->drc_index, REMOVE);
+ else
+ rc = remove_device_tree_nodes(slot->ofdt_path);
if (rc) {
acquire_drc(slot->drc_index);
return rc;
@@ -160,7 +163,6 @@ static int
acquire_slot(char *drc_name, struct dr_node **slot)
{
struct dr_connector drc;
- struct of_node *of_nodes;
char path[DR_PATH_MAX];
int rc;

@@ -180,14 +182,21 @@ acquire_slot(char *drc_name, struct dr_node **slot)
if (rc)
return rc;

- of_nodes = configure_connector(drc.index);
- if (of_nodes == NULL) {
- release_drc(drc.index, PCI_DLPAR_DEV);
- return -1;
+ if (kernel_dlpar_exists()) {
+ rc = do_dt_kernel_dlpar(drc.index, ADD);
+ } else {
+ struct of_node *of_nodes;
+
+ of_nodes = configure_connector(drc.index);
+ if (of_nodes == NULL) {
+ release_drc(drc.index, PCI_DLPAR_DEV);
+ return -1;
+ }
+
+ rc = add_device_tree_nodes(path, of_nodes);
+ free_of_node(of_nodes);
}

- rc = add_device_tree_nodes(path, of_nodes);
- free_of_node(of_nodes);
if (rc) {
say(ERROR, "add_device_tree_nodes failed at %s\n", path);
release_drc(drc.index, PCI_DLPAR_DEV);
--
2.43.5

Tyrel Datwyler

<tyreld@linux.ibm.com>
unread,
Sep 27, 2024, 5:55:56 PM9/27/24
to Haren Myneni, powerpc-utils-devel@googlegroups.com, hbabu@us.ibm.com
On 8/13/24 14:40, Haren Myneni wrote:
> drmgr updates the device tree by writing to /proc/ppc64/ofdt. Also
> invokes configure_connector RTAS call to retrieve new device nodes
> for IO ADD. But this functionality need /dev/mem access which is
> restricted under system lockdown.
>
> The kernel updates provided a sysfs file (/sys/kernel/dlpar) that
> will allow drmgr command invoke the following interfaces to update
> the device tree.
>
> dt add index <DRC index> ---> To add new device nodes to the device
> tree which is used for IO ADD.
>
> dt remove index <DRC index> ---> To remove device nodes for IO
> REMOVE
>
> This patch checks the kernel interface for the availability of
> device tree update feature and adds do_dt_kernel_dlpar() to invoke
> the above kernel interfaces.
>
> Signed-off-by: Haren Myneni <ha...@linux.ibm.com>
> ---

Series applied to powerpc-utils/next branc.

[1/4]
https://github.com/ibm-power-utilities/powerpc-utils/commit/9ea191d15f4b279923a4c83a94b83436c79e3482

[2/4]
https://github.com/ibm-power-utilities/powerpc-utils/commit/9aaa1a625da9de1ca758c4eb8442589b46927acb

[3/4]
https://github.com/ibm-power-utilities/powerpc-utils/commit/a2d1b70cbc90ba41f16281c48e973309469f5d02

[4/4]
https://github.com/ibm-power-utilities/powerpc-utils/commit/bb766caa49f4aef036208023290f16ce7b1cf05d

Thanks,
-Tyrel

Reply all
Reply to author
Forward
0 new messages