forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/arch/powerpc/platforms/pseries/mobility.c
....@@ -1,13 +1,13 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Support for Partition Mobility/Migration
34 *
45 * Copyright (C) 2010 Nathan Fontenot
56 * Copyright (C) 2010 IBM Corporation
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License version
9
- * 2 as published by the Free Software Foundation.
107 */
8
+
9
+
10
+#define pr_fmt(fmt) "mobility: " fmt
1111
1212 #include <linux/cpu.h>
1313 #include <linux/kernel.h>
....@@ -59,16 +59,31 @@
5959 return rc;
6060 }
6161
62
-static int delete_dt_node(__be32 phandle)
62
+static int delete_dt_node(struct device_node *dn)
6363 {
64
- struct device_node *dn;
64
+ struct device_node *pdn;
65
+ bool is_platfac;
6566
66
- dn = of_find_node_by_phandle(be32_to_cpu(phandle));
67
- if (!dn)
68
- return -ENOENT;
67
+ pdn = of_get_parent(dn);
68
+ is_platfac = of_node_is_type(dn, "ibm,platform-facilities") ||
69
+ of_node_is_type(pdn, "ibm,platform-facilities");
70
+ of_node_put(pdn);
6971
72
+ /*
73
+ * The drivers that bind to nodes in the platform-facilities
74
+ * hierarchy don't support node removal, and the removal directive
75
+ * from firmware is always followed by an add of an equivalent
76
+ * node. The capability (e.g. RNG, encryption, compression)
77
+ * represented by the node is never interrupted by the migration.
78
+ * So ignore changes to this part of the tree.
79
+ */
80
+ if (is_platfac) {
81
+ pr_notice("ignoring remove operation for %pOFfp\n", dn);
82
+ return 0;
83
+ }
84
+
85
+ pr_debug("removing node %pOFfp\n", dn);
7086 dlpar_detach_node(dn);
71
- of_node_put(dn);
7287 return 0;
7388 }
7489
....@@ -125,6 +140,7 @@
125140 }
126141
127142 if (!more) {
143
+ pr_debug("updating node %pOF property %s\n", dn, name);
128144 of_update_property(dn, new_prop);
129145 *prop = NULL;
130146 }
....@@ -132,10 +148,9 @@
132148 return 0;
133149 }
134150
135
-static int update_dt_node(__be32 phandle, s32 scope)
151
+static int update_dt_node(struct device_node *dn, s32 scope)
136152 {
137153 struct update_props_workarea *upwa;
138
- struct device_node *dn;
139154 struct property *prop = NULL;
140155 int i, rc, rtas_rc;
141156 char *prop_data;
....@@ -152,14 +167,8 @@
152167 if (!rtas_buf)
153168 return -ENOMEM;
154169
155
- dn = of_find_node_by_phandle(be32_to_cpu(phandle));
156
- if (!dn) {
157
- kfree(rtas_buf);
158
- return -ENOENT;
159
- }
160
-
161170 upwa = (struct update_props_workarea *)&rtas_buf[0];
162
- upwa->phandle = phandle;
171
+ upwa->phandle = cpu_to_be32(dn->phandle);
163172
164173 do {
165174 rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf,
....@@ -218,62 +227,39 @@
218227 cond_resched();
219228 } while (rtas_rc == 1);
220229
221
- of_node_put(dn);
222230 kfree(rtas_buf);
223231 return 0;
224232 }
225233
226
-static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
234
+static int add_dt_node(struct device_node *parent_dn, __be32 drc_index)
227235 {
228236 struct device_node *dn;
229
- struct device_node *parent_dn;
230237 int rc;
231238
232
- parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle));
233
- if (!parent_dn)
239
+ dn = dlpar_configure_connector(drc_index, parent_dn);
240
+ if (!dn)
234241 return -ENOENT;
235242
236
- dn = dlpar_configure_connector(drc_index, parent_dn);
237
- if (!dn) {
238
- of_node_put(parent_dn);
239
- return -ENOENT;
243
+ /*
244
+ * Since delete_dt_node() ignores this node type, this is the
245
+ * necessary counterpart. We also know that a platform-facilities
246
+ * node returned from dlpar_configure_connector() has children
247
+ * attached, and dlpar_attach_node() only adds the parent, leaking
248
+ * the children. So ignore these on the add side for now.
249
+ */
250
+ if (of_node_is_type(dn, "ibm,platform-facilities")) {
251
+ pr_notice("ignoring add operation for %pOF\n", dn);
252
+ dlpar_free_cc_nodes(dn);
253
+ return 0;
240254 }
241255
242256 rc = dlpar_attach_node(dn, parent_dn);
243257 if (rc)
244258 dlpar_free_cc_nodes(dn);
245259
246
- of_node_put(parent_dn);
260
+ pr_debug("added node %pOFfp\n", dn);
261
+
247262 return rc;
248
-}
249
-
250
-static void prrn_update_node(__be32 phandle)
251
-{
252
- struct pseries_hp_errorlog *hp_elog;
253
- struct device_node *dn;
254
-
255
- /*
256
- * If a node is found from a the given phandle, the phandle does not
257
- * represent the drc index of an LMB and we can ignore.
258
- */
259
- dn = of_find_node_by_phandle(be32_to_cpu(phandle));
260
- if (dn) {
261
- of_node_put(dn);
262
- return;
263
- }
264
-
265
- hp_elog = kzalloc(sizeof(*hp_elog), GFP_KERNEL);
266
- if(!hp_elog)
267
- return;
268
-
269
- hp_elog->resource = PSERIES_HP_ELOG_RESOURCE_MEM;
270
- hp_elog->action = PSERIES_HP_ELOG_ACTION_READD;
271
- hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
272
- hp_elog->_drc_u.drc_index = phandle;
273
-
274
- queue_hotplug_event(hp_elog, NULL, NULL);
275
-
276
- kfree(hp_elog);
277263 }
278264
279265 int pseries_devicetree_update(s32 scope)
....@@ -305,26 +291,31 @@
305291 data++;
306292
307293 for (i = 0; i < node_count; i++) {
294
+ struct device_node *np;
308295 __be32 phandle = *data++;
309296 __be32 drc_index;
310297
298
+ np = of_find_node_by_phandle(be32_to_cpu(phandle));
299
+ if (!np) {
300
+ pr_warn("Failed lookup: phandle 0x%x for action 0x%x\n",
301
+ be32_to_cpu(phandle), action);
302
+ continue;
303
+ }
304
+
311305 switch (action) {
312306 case DELETE_DT_NODE:
313
- delete_dt_node(phandle);
307
+ delete_dt_node(np);
314308 break;
315309 case UPDATE_DT_NODE:
316
- update_dt_node(phandle, scope);
317
-
318
- if (scope == PRRN_SCOPE)
319
- prrn_update_node(phandle);
320
-
310
+ update_dt_node(np, scope);
321311 break;
322312 case ADD_DT_NODE:
323313 drc_index = *data++;
324
- add_dt_node(phandle, drc_index);
314
+ add_dt_node(np, drc_index);
325315 break;
326316 }
327317
318
+ of_node_put(np);
328319 cond_resched();
329320 }
330321 }
....@@ -377,8 +368,11 @@
377368
378369 cpus_read_unlock();
379370
380
- /* Possibly switch to a new RFI flush type */
381
- pseries_setup_rfi_flush();
371
+ /* Possibly switch to a new L1 flush type */
372
+ pseries_setup_security_mitigations();
373
+
374
+ /* Reinitialise system information for hv-24x7 */
375
+ read_24x7_sys_info();
382376
383377 return;
384378 }
....@@ -404,6 +398,7 @@
404398 return rc;
405399
406400 post_mobility_fixup();
401
+
407402 return count;
408403 }
409404
....@@ -428,11 +423,11 @@
428423
429424 rc = sysfs_create_file(mobility_kobj, &class_attr_migration.attr);
430425 if (rc)
431
- pr_err("mobility: unable to create migration sysfs file (%d)\n", rc);
426
+ pr_err("unable to create migration sysfs file (%d)\n", rc);
432427
433428 rc = sysfs_create_file(mobility_kobj, &class_attr_api_version.attr.attr);
434429 if (rc)
435
- pr_err("mobility: unable to create api_version sysfs file (%d)\n", rc);
430
+ pr_err("unable to create api_version sysfs file (%d)\n", rc);
436431
437432 return 0;
438433 }