powerpc/pseries/dlpar: Remove device tree node for DLPAR IO remove
PATCH v2 1/2 powerpc/pseries/dlpar: Remove device tree node for DLPAR IO remove
In the powerpc-pseries specific implementation, the IO hotplug event is handled in the user space (drmgr tool). But update the device tree and /dev/mem access to allocate buffers for some RTAS calls are restricted when the kernel lockdown feature is enabled. For the DLPAR IO REMOVE, the corresponding device tree nodes and properties have to be removed from the device tree after the device disable. The user space removes the device tree nodes by updating /proc/ppc64/ofdt which is not allowed under system lockdown is enabled. This restriction can be resolved by moving the complete IO hotplug handling in the kernel. But the pseries implementation need user interaction to power off and to remove device from the slot during hotplug event handling.
To overcome the /proc/ppc64/ofdt restriction, this patch extends the /sys/kernel/dlpar interface and provides
‘dt remove index <drc_index>’ to the user space so that drmgr tool can remove the corresponding device tree nodes based on DRC index from the device tree.
v2:
- Remove pr_info() and TODO comments
- Update more information in the commit logs
--- arch/powerpc/include/asm/rtas.h | 1 + arch/powerpc/platforms/pseries/dlpar.c | 85 +++++++++++++++++++++++++- 2 files changed, 85 insertions(+), 1 deletion(-)
arch/powerpc/include/asm/rtas.h +1 -0
@@ -397,6 +397,7 @@ inline uint16_t pseries_errorlog_length(struct pseries_errorlog *sect)#define PSERIES_HP_ELOG_RESOURCE_SLOT 3#define PSERIES_HP_ELOG_RESOURCE_PHB 4#define PSERIES_HP_ELOG_RESOURCE_PMEM 6 +#define PSERIES_HP_ELOG_RESOURCE_DT 7#define PSERIES_HP_ELOG_ACTION_ADD 1#define PSERIES_HP_ELOG_ACTION_REMOVE 2
arch/powerpc/platforms/pseries/dlpar.c +84 -1
109 lines not on this page · raw message
Signature · 1 line
2.43.5
PATCH v2 2/2 powerpc/pseries/dlpar: Add device tree nodes for DLPAR IO add
In the powerpc-pseries specific implementation, the IO hotplug event is handled in the user space (drmgr tool). For the DLPAR IO ADD, the corresponding device tree nodes and properties will be added to the device tree after the device enable. The user space (drmgr tool) uses configure_connector RTAS call with the DRC index to retrieve the device nodes and updates the device tree by writing to /proc/ppc64/ofdt. Under system lockdown, /dev/mem access to allocate buffers for configure_connector RTAS call is restricted which means the user space can not issue this RTAS call and also can not access to /proc/ppc64/ofdt. The pseries implementation need user interaction to power-on and add device to the slot during the ADD event handling. So adds complexity if the complete hotplug ADD event handling moved to the kernel.
To overcome /dev/mem access restriction, this patch extends the /sys/kernel/dlpar interface and provides ‘dt add index <drc_index>’ to the user space. The drmgr tool uses this interface to update the device tree whenever the device is added. This interface retrieves device tree nodes for the corresponding DRC index using the configure_connector RTAS call and adds new device nodes / properties to the device tree.
--- arch/powerpc/platforms/pseries/dlpar.c | 130 +++++++++++++++++++++++++ 1 file changed, 130 insertions(+)
arch/powerpc/platforms/pseries/dlpar.c +130 -0
@@ -23,6 +23,7 @@#include <linux/uaccess.h> #include <asm/rtas.h> #include <asm/rtas-work-area.h> +#include <asm/prom.h> static struct workqueue_struct *pseries_hp_wq;
@@ -264,6 +265,20 @@ int dlpar_detach_node(struct device_node *dn)return 0 ; } +static int dlpar_changeset_attach_cc_nodes (struct of_changeset *ocs, +struct device_node *dn) +{ +int rc; + + rc =of_changeset_attach_node (ocs, dn); + +if (!rc && dn->child) + rc =dlpar_changeset_attach_cc_nodes (ocs, dn->child); +if (!rc && dn->sibling) + rc =dlpar_changeset_attach_cc_nodes (ocs, dn->sibling); + +return rc; +}#define DR_ENTITY_SENSE 9003#define DR_ENTITY_PRESENT 1
@@ -330,6 +345,118 @@ int dlpar_unisolate_drc(u32 drc_index)return 0 ; } +static struct device_node * +get_device_node_with_drc_index (u32 index) +{ +struct device_node *np =NULL ; +u32 node_index; +int rc; + +for_each_node_with_property (np,"ibm,my-drc-index" ) { + rc =of_property_read_u32 (np,"ibm,my-drc-index" , + &node_index); +if (rc) { +pr_err ("%s: %pOF: of_property_read_u32 %s: %d\n" , + __func__, np,"ibm,my-drc-index" , rc); +of_node_put (np); +return NULL ; + } + +if (index == node_index) +break ; + } + +return np; +} + +static struct device_node * +get_device_node_with_drc_info (u32 index) +{ +struct device_node *np =NULL ; +struct of_drc_info drc; +struct property *info; +const __be32 *value; +u32 node_index; +int i, j, count; + +for_each_node_with_property (np,"ibm,drc-info" ) { + info =of_find_property (np,"ibm,drc-info" ,NULL ); +if (info ==NULL ) { +/* XXX can this happen? */ +of_node_put (np); +return NULL ; + } + value =of_prop_next_u32 (info,NULL , &count); +if (value ==NULL ) +continue ; + value++; +for (i =0 ; i < count; i++) { +if (of_read_drc_info_cell (&info, &value, &drc)) +break ; +if (index > drc.last_drc_index) +continue ; + node_index = drc.drc_index_start; +for (j =0 ; j < drc.num_sequential_elems; j++) { +if (index == node_index) +return np; + node_index += drc.sequential_inc; + } + } + } + +return NULL ; +} + +static int dlpar_hp_dt_add (u32 index) +{ +struct device_node *np, *nodes; +struct of_changeset ocs; +int rc; + +/* +* Do not add device node(s) if already exists in the +* device tree. +*/ + np =get_device_node_with_drc_index (index); +if (np) { +pr_err ("%s: Adding device node for index (%d), but " +"already exists in the device tree\n" , + __func__, index); + rc = -EINVAL ; + goto out; + } + + np =get_device_node_with_drc_info (index); + +if (!np) +return -EIO ; + +/* Next, configure the connector. */ + nodes =dlpar_configure_connector (cpu_to_be32 (index), np); +if (!nodes) { + rc = -EIO ; + goto out; + } + +/* +* Add the new nodes from dlpar_configure_connector() onto +* the device-tree. +*/ +of_changeset_init (&ocs); + rc =dlpar_changeset_attach_cc_nodes (&ocs, nodes); + +if (!rc) + rc =of_changeset_apply (&ocs); +else +dlpar_free_cc_nodes (nodes); + +of_changeset_destroy (&ocs); + +out: +of_node_put (np); +return rc; +} +static int changeset_detach_node_recursive (struct of_changeset *ocs,struct device_node *node) {
@@ -394,6 +521,9 @@ static int dlpar_hp_dt(struct pseries_hp_errorlog *phpe)lock_device_hotplug ();switch (phpe->action) { +case PSERIES_HP_ELOG_ACTION_ADD : + rc =dlpar_hp_dt_add (phpe->_drc_u.drc_index); +break ;case PSERIES_HP_ELOG_ACTION_REMOVE : rc =dlpar_hp_dt_remove (phpe->_drc_u.drc_index);break ;
Signature · 1 line
2.43.5
kernel test robot
build botRe: [PATCH v2 2/2] powerpc/pseries/dlpar: Add device tree nodes for DLPAR IO add
kernel test robot noticed the following build warnings:
Hi Haren,
kernel test robot noticed the following build warnings:
[auto build test WARNING on powerpc/next]
[also build test WARNING on powerpc/fixes linus/master v6.11-rc3 next-20240816] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Haren-Myneni/powerpc-pseries-dlpar-Add-device-tree-nodes-for-DLPAR-IO-add/20240817-115833 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next patch link: https://lore.kernel.org/r/20240817035401.125833-2-haren%40linux.ibm.com patch subject: [PATCH v2 2/2] powerpc/pseries/dlpar: Add device tree nodes for DLPAR IO add config: powerpc64-randconfig-r121-20240818 (https://download.01.org/0day-ci/archive/20240818/[email protected]/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 26670e7fa4f032a019d23d56c6a02926e854e8af) reproduce: (https://download.01.org/0day-ci/archive/20240818/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
sparse warnings: (new ones prefixed by >>)
>> arch/powerpc/platforms/pseries/dlpar.c:525:50: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int [usertype] index @@ got restricted __be32 [usertype] drc_index @@
arch/powerpc/platforms/pseries/dlpar.c:525:50: sparse: expected unsigned int [usertype] index
arch/powerpc/platforms/pseries/dlpar.c:525:50: sparse: got restricted __be32 [usertype] drc_index
arch/powerpc/platforms/pseries/dlpar.c:528:53: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int [usertype] drc_index @@ got restricted __be32 [usertype] drc_index @@
arch/powerpc/platforms/pseries/dlpar.c:528:53: sparse: expected unsigned int [usertype] drc_index
arch/powerpc/platforms/pseries/dlpar.c:528:53: sparse: got restricted __be32 [usertype] drc_index
arch/powerpc/platforms/pseries/dlpar.c:548:43: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] drc_count @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:548:43: sparse: expected restricted __be32 [usertype] drc_count
arch/powerpc/platforms/pseries/dlpar.c:548:43: sparse: got unsigned int [usertype]
arch/powerpc/platforms/pseries/dlpar.c:552:43: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] drc_index @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:552:43: sparse: expected restricted __be32 [usertype] drc_index
arch/powerpc/platforms/pseries/dlpar.c:552:43: sparse: got unsigned int [usertype]
arch/powerpc/platforms/pseries/dlpar.c:556:42: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] count @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:556:42: sparse: expected restricted __be32 [usertype] count
arch/powerpc/platforms/pseries/dlpar.c:556:42: sparse: got unsigned int [usertype]
arch/powerpc/platforms/pseries/dlpar.c:558:42: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] index @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:558:42: sparse: expected restricted __be32 [usertype] index
arch/powerpc/platforms/pseries/dlpar.c:558:42: sparse: got unsigned int [usertype]
vim +525 arch/powerpc/platforms/pseries/dlpar.c
513
514 static int dlpar_hp_dt(struct pseries_hp_errorlog *phpe)
515 {
516 int rc;
517
518 if (phpe->id_type != PSERIES_HP_ELOG_ID_DRC_INDEX)
519 return -EINVAL;
520
521 lock_device_hotplug();
522
523 switch (phpe->action) {
524 case PSERIES_HP_ELOG_ACTION_ADD:
> 525 rc = dlpar_hp_dt_add(phpe->_drc_u.drc_index);
526 break;
527 case PSERIES_HP_ELOG_ACTION_REMOVE:
528 rc = dlpar_hp_dt_remove(phpe->_drc_u.drc_index);
529 break;
530 default:
531 pr_err("Invalid action (%d) specified\n", phpe->action);
532 rc = -EINVAL;
533 break;
534 }
535
536 unlock_device_hotplug();
537
538 return rc;
539 }
540
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki
kernel test robot
build botkernel test robot noticed the following build warnings:
Hi Haren,
kernel test robot noticed the following build warnings:
[auto build test WARNING on powerpc/next]
[also build test WARNING on powerpc/fixes linus/master v6.11-rc3 next-20240816] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Haren-Myneni/powerpc-pseries-dlpar-Add-device-tree-nodes-for-DLPAR-IO-add/20240817-115833 base: https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next patch link: https://lore.kernel.org/r/20240817035401.125833-1-haren%40linux.ibm.com patch subject: [PATCH v2 1/2] powerpc/pseries/dlpar: Remove device tree node for DLPAR IO remove config: powerpc64-randconfig-r121-20240818 (https://download.01.org/0day-ci/archive/20240818/[email protected]/config) compiler: clang version 20.0.0git (https://github.com/llvm/llvm-project 26670e7fa4f032a019d23d56c6a02926e854e8af) reproduce: (https://download.01.org/0day-ci/archive/20240818/[email protected]/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/
sparse warnings: (new ones prefixed by >>)
>> arch/powerpc/platforms/pseries/dlpar.c:398:53: sparse: sparse: incorrect type in argument 1 (different base types) @@ expected unsigned int [usertype] drc_index @@ got restricted __be32 [usertype] drc_index @@
arch/powerpc/platforms/pseries/dlpar.c:398:53: sparse: expected unsigned int [usertype] drc_index
arch/powerpc/platforms/pseries/dlpar.c:398:53: sparse: got restricted __be32 [usertype] drc_index
arch/powerpc/platforms/pseries/dlpar.c:418:43: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] drc_count @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:418:43: sparse: expected restricted __be32 [usertype] drc_count
arch/powerpc/platforms/pseries/dlpar.c:418:43: sparse: got unsigned int [usertype]
arch/powerpc/platforms/pseries/dlpar.c:422:43: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] drc_index @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:422:43: sparse: expected restricted __be32 [usertype] drc_index
arch/powerpc/platforms/pseries/dlpar.c:422:43: sparse: got unsigned int [usertype]
arch/powerpc/platforms/pseries/dlpar.c:426:42: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] count @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:426:42: sparse: expected restricted __be32 [usertype] count
arch/powerpc/platforms/pseries/dlpar.c:426:42: sparse: got unsigned int [usertype]
arch/powerpc/platforms/pseries/dlpar.c:428:42: sparse: sparse: incorrect type in assignment (different base types) @@ expected restricted __be32 [usertype] index @@ got unsigned int [usertype] @@
arch/powerpc/platforms/pseries/dlpar.c:428:42: sparse: expected restricted __be32 [usertype] index
arch/powerpc/platforms/pseries/dlpar.c:428:42: sparse: got unsigned int [usertype]
vim +398 arch/powerpc/platforms/pseries/dlpar.c
386
387 static int dlpar_hp_dt(struct pseries_hp_errorlog *phpe)
388 {
389 int rc;
390
391 if (phpe->id_type != PSERIES_HP_ELOG_ID_DRC_INDEX)
392 return -EINVAL;
393
394 lock_device_hotplug();
395
396 switch (phpe->action) {
397 case PSERIES_HP_ELOG_ACTION_REMOVE:
> 398 rc = dlpar_hp_dt_remove(phpe->_drc_u.drc_index);
399 break;
400 default:
401 pr_err("Invalid action (%d) specified\n", phpe->action);
402 rc = -EINVAL;
403 break;
404 }
405
406 unlock_device_hotplug();
407
408 return rc;
409 }
410
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki