|
Michal Suchanek |
b25333 |
From 319fa1a52e438a6e028329187783a25ad498c4e6 Mon Sep 17 00:00:00 2001
|
|
Michal Suchanek |
b25333 |
From: Nathan Lynch <nathanl@linux.ibm.com>
|
|
Michal Suchanek |
b25333 |
Date: Wed, 20 Oct 2021 14:47:03 -0500
|
|
Michal Suchanek |
b25333 |
Subject: [PATCH] powerpc/pseries/mobility: ignore ibm, platform-facilities
|
|
Michal Suchanek |
b25333 |
updates
|
|
Michal Suchanek |
b25333 |
MIME-Version: 1.0
|
|
Michal Suchanek |
b25333 |
Content-Type: text/plain; charset=UTF-8
|
|
Michal Suchanek |
b25333 |
Content-Transfer-Encoding: 8bit
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
References: bsc#1065729
|
|
Michal Suchanek |
b25333 |
Patch-mainline: v5.16-rc1
|
|
Michal Suchanek |
b25333 |
Git-commit: 319fa1a52e438a6e028329187783a25ad498c4e6
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
On VMs with NX encryption, compression, and/or RNG offload, these
|
|
Michal Suchanek |
b25333 |
capabilities are described by nodes in the ibm,platform-facilities device
|
|
Michal Suchanek |
b25333 |
tree hierarchy:
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
$ tree -d /sys/firmware/devicetree/base/ibm,platform-facilities/
|
|
Michal Suchanek |
b25333 |
/sys/firmware/devicetree/base/ibm,platform-facilities/
|
|
Michal Suchanek |
b25333 |
├── ibm,compression-v1
|
|
Michal Suchanek |
b25333 |
├── ibm,random-v1
|
|
Michal Suchanek |
b25333 |
└── ibm,sym-encryption-v1
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
3 directories
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
The acceleration functions that these nodes describe are not disrupted by
|
|
Michal Suchanek |
b25333 |
live migration, not even temporarily.
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
But the post-migration ibm,update-nodes sequence firmware always sends
|
|
Michal Suchanek |
b25333 |
"delete" messages for this hierarchy, followed by an "add" directive to
|
|
Michal Suchanek |
b25333 |
reconstruct it via ibm,configure-connector (log with debugging statements
|
|
Michal Suchanek |
b25333 |
enabled in mobility.c):
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
mobility: removing node /ibm,platform-facilities/ibm,random-v1:4294967285
|
|
Michal Suchanek |
b25333 |
mobility: removing node /ibm,platform-facilities/ibm,compression-v1:4294967284
|
|
Michal Suchanek |
b25333 |
mobility: removing node /ibm,platform-facilities/ibm,sym-encryption-v1:4294967283
|
|
Michal Suchanek |
b25333 |
mobility: removing node /ibm,platform-facilities:4294967286
|
|
Michal Suchanek |
b25333 |
...
|
|
Michal Suchanek |
b25333 |
mobility: added node /ibm,platform-facilities:4294967286
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
Note we receive a single "add" message for the entire hierarchy, and what
|
|
Michal Suchanek |
b25333 |
we receive from the ibm,configure-connector sequence is the top-level
|
|
Michal Suchanek |
b25333 |
platform-facilities node along with its three children. The debug message
|
|
Michal Suchanek |
b25333 |
simply reports the parent node and not the whole subtree.
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
Also, significantly, the nodes added are almost completely equivalent to
|
|
Michal Suchanek |
b25333 |
the ones removed; even phandles are unchanged. ibm,shared-interrupt-pool in
|
|
Michal Suchanek |
b25333 |
the leaf nodes is the only property I've observed to differ, and Linux does
|
|
Michal Suchanek |
b25333 |
not use that. So in practice, the sum of update messages Linux receives for
|
|
Michal Suchanek |
b25333 |
this hierarchy is equivalent to minor property updates.
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
We succeed in removing the original hierarchy from the device tree. But the
|
|
Michal Suchanek |
b25333 |
vio bus code is ignorant of this, and does not unbind or relinquish its
|
|
Michal Suchanek |
b25333 |
references. The leaf nodes, still reachable through sysfs, of course still
|
|
Michal Suchanek |
b25333 |
refer to the now-freed ibm,platform-facilities parent node, which makes
|
|
Michal Suchanek |
b25333 |
use-after-free possible:
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
refcount_t: addition on 0; use-after-free.
|
|
Michal Suchanek |
b25333 |
WARNING: CPU: 3 PID: 1706 at lib/refcount.c:25 refcount_warn_saturate+0x164/0x1f0
|
|
Michal Suchanek |
b25333 |
refcount_warn_saturate+0x160/0x1f0 (unreliable)
|
|
Michal Suchanek |
b25333 |
kobject_get+0xf0/0x100
|
|
Michal Suchanek |
b25333 |
of_node_get+0x30/0x50
|
|
Michal Suchanek |
b25333 |
of_get_parent+0x50/0xb0
|
|
Michal Suchanek |
b25333 |
of_fwnode_get_parent+0x54/0x90
|
|
Michal Suchanek |
b25333 |
fwnode_count_parents+0x50/0x150
|
|
Michal Suchanek |
b25333 |
fwnode_full_name_string+0x30/0x110
|
|
Michal Suchanek |
b25333 |
device_node_string+0x49c/0x790
|
|
Michal Suchanek |
b25333 |
vsnprintf+0x1c0/0x4c0
|
|
Michal Suchanek |
b25333 |
sprintf+0x44/0x60
|
|
Michal Suchanek |
b25333 |
devspec_show+0x34/0x50
|
|
Michal Suchanek |
b25333 |
dev_attr_show+0x40/0xa0
|
|
Michal Suchanek |
b25333 |
sysfs_kf_seq_show+0xbc/0x200
|
|
Michal Suchanek |
b25333 |
kernfs_seq_show+0x44/0x60
|
|
Michal Suchanek |
b25333 |
seq_read_iter+0x2a4/0x740
|
|
Michal Suchanek |
b25333 |
kernfs_fop_read_iter+0x254/0x2e0
|
|
Michal Suchanek |
b25333 |
new_sync_read+0x120/0x190
|
|
Michal Suchanek |
b25333 |
vfs_read+0x1d0/0x240
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
Moreover, the "new" replacement subtree is not correctly added to the
|
|
Michal Suchanek |
b25333 |
device tree, resulting in ibm,platform-facilities parent node without the
|
|
Michal Suchanek |
b25333 |
appropriate leaf nodes, and broken symlinks in the sysfs device hierarchy:
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
$ tree -d /sys/firmware/devicetree/base/ibm,platform-facilities/
|
|
Michal Suchanek |
b25333 |
/sys/firmware/devicetree/base/ibm,platform-facilities/
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
0 directories
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
$ cd /sys/devices/vio ; find . -xtype l -exec file {} +
|
|
Michal Suchanek |
b25333 |
./ibm,sym-encryption-v1/of_node: broken symbolic link to
|
|
Michal Suchanek |
b25333 |
../../../firmware/devicetree/base/ibm,platform-facilities/ibm,sym-encryption-v1
|
|
Michal Suchanek |
b25333 |
./ibm,random-v1/of_node: broken symbolic link to
|
|
Michal Suchanek |
b25333 |
../../../firmware/devicetree/base/ibm,platform-facilities/ibm,random-v1
|
|
Michal Suchanek |
b25333 |
./ibm,compression-v1/of_node: broken symbolic link to
|
|
Michal Suchanek |
b25333 |
../../../firmware/devicetree/base/ibm,platform-facilities/ibm,compression-v1
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
This is because add_dt_node() -> dlpar_attach_node() attaches only the
|
|
Michal Suchanek |
b25333 |
parent node returned from configure-connector, ignoring any children. This
|
|
Michal Suchanek |
b25333 |
should be corrected for the general case, but fixing that won't help with
|
|
Michal Suchanek |
b25333 |
the stale OF node references, which is the more urgent problem.
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
One way to address that would be to make the drivers respond to node
|
|
Michal Suchanek |
b25333 |
removal notifications, so that node references can be dropped
|
|
Michal Suchanek |
b25333 |
appropriately. But this would likely force the drivers to disrupt active
|
|
Michal Suchanek |
b25333 |
clients for no useful purpose: equivalent nodes are immediately re-added.
|
|
Michal Suchanek |
b25333 |
And recall that the acceleration capabilities described by the nodes remain
|
|
Michal Suchanek |
b25333 |
available throughout the whole process.
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
The solution I believe to be robust for this situation is to convert
|
|
Michal Suchanek |
b25333 |
remove+add of a node with an unchanged phandle to an update of the node's
|
|
Michal Suchanek |
b25333 |
properties in the Linux device tree structure. That would involve changing
|
|
Michal Suchanek |
b25333 |
and adding a fair amount of code, and may take several iterations to land.
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
Until that can be realized we have a confirmed use-after-free and the
|
|
Michal Suchanek |
b25333 |
possibility of memory corruption. So add a limited workaround that
|
|
Michal Suchanek |
b25333 |
discriminates on the node type, ignoring adds and removes. This should be
|
|
Michal Suchanek |
b25333 |
amenable to backporting in the meantime.
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel")
|
|
Michal Suchanek |
b25333 |
Cc: stable@vger.kernel.org
|
|
Michal Suchanek |
b25333 |
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
|
|
Michal Suchanek |
b25333 |
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
|
|
Michal Suchanek |
b25333 |
Link: https://lore.kernel.org/r/20211020194703.2613093-1-nathanl@linux.ibm.com
|
|
Michal Suchanek |
b25333 |
Acked-by: Michal Suchanek <msuchanek@suse.de>
|
|
Michal Suchanek |
b25333 |
---
|
|
Michal Suchanek |
b25333 |
arch/powerpc/platforms/pseries/mobility.c | 34 +++++++++++++++++++++++
|
|
Michal Suchanek |
b25333 |
1 file changed, 34 insertions(+)
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
|
|
Michal Suchanek |
b25333 |
index e83e0891272d..210a37a065fb 100644
|
|
Michal Suchanek |
b25333 |
--- a/arch/powerpc/platforms/pseries/mobility.c
|
|
Michal Suchanek |
b25333 |
+++ b/arch/powerpc/platforms/pseries/mobility.c
|
|
Michal Suchanek |
b25333 |
@@ -63,6 +63,27 @@ static int mobility_rtas_call(int token, char *buf, s32 scope)
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
static int delete_dt_node(struct device_node *dn)
|
|
Michal Suchanek |
b25333 |
{
|
|
Michal Suchanek |
b25333 |
+ struct device_node *pdn;
|
|
Michal Suchanek |
b25333 |
+ bool is_platfac;
|
|
Michal Suchanek |
b25333 |
+
|
|
Michal Suchanek |
b25333 |
+ pdn = of_get_parent(dn);
|
|
Michal Suchanek |
b25333 |
+ is_platfac = of_node_is_type(dn, "ibm,platform-facilities") ||
|
|
Michal Suchanek |
b25333 |
+ of_node_is_type(pdn, "ibm,platform-facilities");
|
|
Michal Suchanek |
b25333 |
+ of_node_put(pdn);
|
|
Michal Suchanek |
b25333 |
+
|
|
Michal Suchanek |
b25333 |
+ /*
|
|
Michal Suchanek |
b25333 |
+ * The drivers that bind to nodes in the platform-facilities
|
|
Michal Suchanek |
b25333 |
+ * hierarchy don't support node removal, and the removal directive
|
|
Michal Suchanek |
b25333 |
+ * from firmware is always followed by an add of an equivalent
|
|
Michal Suchanek |
b25333 |
+ * node. The capability (e.g. RNG, encryption, compression)
|
|
Michal Suchanek |
b25333 |
+ * represented by the node is never interrupted by the migration.
|
|
Michal Suchanek |
b25333 |
+ * So ignore changes to this part of the tree.
|
|
Michal Suchanek |
b25333 |
+ */
|
|
Michal Suchanek |
b25333 |
+ if (is_platfac) {
|
|
Michal Suchanek |
b25333 |
+ pr_notice("ignoring remove operation for %pOFfp\n", dn);
|
|
Michal Suchanek |
b25333 |
+ return 0;
|
|
Michal Suchanek |
b25333 |
+ }
|
|
Michal Suchanek |
b25333 |
+
|
|
Michal Suchanek |
b25333 |
pr_debug("removing node %pOFfp\n", dn);
|
|
Michal Suchanek |
b25333 |
dlpar_detach_node(dn);
|
|
Michal Suchanek |
b25333 |
return 0;
|
|
Michal Suchanek |
b25333 |
@@ -222,6 +243,19 @@ static int add_dt_node(struct device_node *parent_dn, __be32 drc_index)
|
|
Michal Suchanek |
b25333 |
if (!dn)
|
|
Michal Suchanek |
b25333 |
return -ENOENT;
|
|
Michal Suchanek |
b25333 |
|
|
Michal Suchanek |
b25333 |
+ /*
|
|
Michal Suchanek |
b25333 |
+ * Since delete_dt_node() ignores this node type, this is the
|
|
Michal Suchanek |
b25333 |
+ * necessary counterpart. We also know that a platform-facilities
|
|
Michal Suchanek |
b25333 |
+ * node returned from dlpar_configure_connector() has children
|
|
Michal Suchanek |
b25333 |
+ * attached, and dlpar_attach_node() only adds the parent, leaking
|
|
Michal Suchanek |
b25333 |
+ * the children. So ignore these on the add side for now.
|
|
Michal Suchanek |
b25333 |
+ */
|
|
Michal Suchanek |
b25333 |
+ if (of_node_is_type(dn, "ibm,platform-facilities")) {
|
|
Michal Suchanek |
b25333 |
+ pr_notice("ignoring add operation for %pOF\n", dn);
|
|
Michal Suchanek |
b25333 |
+ dlpar_free_cc_nodes(dn);
|
|
Michal Suchanek |
b25333 |
+ return 0;
|
|
Michal Suchanek |
b25333 |
+ }
|
|
Michal Suchanek |
b25333 |
+
|
|
Michal Suchanek |
b25333 |
rc = dlpar_attach_node(dn, parent_dn);
|
|
Michal Suchanek |
b25333 |
if (rc)
|
|
Michal Suchanek |
b25333 |
dlpar_free_cc_nodes(dn);
|
|
Michal Suchanek |
b25333 |
--
|
|
Michal Suchanek |
b25333 |
2.31.1
|
|
Michal Suchanek |
b25333 |
|