1 // SPDX-License-Identifier: GPL-2.0-only
3 * Support for Partition Mobility/Migration
5 * Copyright (C) 2010 Nathan Fontenot
6 * Copyright (C) 2010 IBM Corporation
10 #define pr_fmt(fmt) "mobility: " fmt
12 #include <linux/cpu.h>
13 #include <linux/kernel.h>
14 #include <linux/kobject.h>
15 #include <linux/sched.h>
16 #include <linux/smp.h>
17 #include <linux/stat.h>
18 #include <linux/completion.h>
19 #include <linux/device.h>
20 #include <linux/delay.h>
21 #include <linux/slab.h>
22 #include <linux/stringify.h>
24 #include <asm/machdep.h>
27 #include "../../kernel/cacheinfo.h"
29 static struct kobject *mobility_kobj;
31 struct update_props_workarea {
38 #define NODE_ACTION_MASK 0xff000000
39 #define NODE_COUNT_MASK 0x00ffffff
41 #define DELETE_DT_NODE 0x01000000
42 #define UPDATE_DT_NODE 0x02000000
43 #define ADD_DT_NODE 0x03000000
45 #define MIGRATION_SCOPE (1)
48 static int mobility_rtas_call(int token, char *buf, s32 scope)
52 spin_lock(&rtas_data_buf_lock);
54 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE);
55 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope);
56 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE);
58 spin_unlock(&rtas_data_buf_lock);
62 static int delete_dt_node(struct device_node *dn)
64 struct device_node *pdn;
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");
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.
81 pr_notice("ignoring remove operation for %pOFfp\n", dn);
85 pr_debug("removing node %pOFfp\n", dn);
86 dlpar_detach_node(dn);
90 static int update_dt_property(struct device_node *dn, struct property **prop,
91 const char *name, u32 vd, char *value)
93 struct property *new_prop = *prop;
96 /* A negative 'vd' value indicates that only part of the new property
97 * value is contained in the buffer and we need to call
98 * ibm,update-properties again to get the rest of the value.
100 * A negative value is also the two's compliment of the actual value.
102 if (vd & 0x80000000) {
108 /* partial property fixup */
109 char *new_data = kzalloc(new_prop->length + vd, GFP_KERNEL);
113 memcpy(new_data, new_prop->value, new_prop->length);
114 memcpy(new_data + new_prop->length, value, vd);
116 kfree(new_prop->value);
117 new_prop->value = new_data;
118 new_prop->length += vd;
120 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL);
124 new_prop->name = kstrdup(name, GFP_KERNEL);
125 if (!new_prop->name) {
130 new_prop->length = vd;
131 new_prop->value = kzalloc(new_prop->length, GFP_KERNEL);
132 if (!new_prop->value) {
133 kfree(new_prop->name);
138 memcpy(new_prop->value, value, vd);
143 pr_debug("updating node %pOF property %s\n", dn, name);
144 of_update_property(dn, new_prop);
151 static int update_dt_node(struct device_node *dn, s32 scope)
153 struct update_props_workarea *upwa;
154 struct property *prop = NULL;
158 int update_properties_token;
162 update_properties_token = rtas_token("ibm,update-properties");
163 if (update_properties_token == RTAS_UNKNOWN_SERVICE)
166 rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
170 upwa = (struct update_props_workarea *)&rtas_buf[0];
171 upwa->phandle = cpu_to_be32(dn->phandle);
174 rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf,
179 prop_data = rtas_buf + sizeof(*upwa);
180 nprops = be32_to_cpu(upwa->nprops);
182 /* On the first call to ibm,update-properties for a node the
183 * the first property value descriptor contains an empty
184 * property name, the property value length encoded as u32,
185 * and the property value is the node path being updated.
187 if (*prop_data == 0) {
189 vd = be32_to_cpu(*(__be32 *)prop_data);
190 prop_data += vd + sizeof(vd);
194 for (i = 0; i < nprops; i++) {
197 prop_name = prop_data;
198 prop_data += strlen(prop_name) + 1;
199 vd = be32_to_cpu(*(__be32 *)prop_data);
200 prop_data += sizeof(vd);
204 /* name only property, nothing to do */
208 of_remove_property(dn, of_find_property(dn,
214 rc = update_dt_property(dn, &prop, prop_name,
217 printk(KERN_ERR "Could not update %s"
218 " property\n", prop_name);
228 } while (rtas_rc == 1);
234 static int add_dt_node(struct device_node *parent_dn, __be32 drc_index)
236 struct device_node *dn;
239 dn = dlpar_configure_connector(drc_index, parent_dn);
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.
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);
256 rc = dlpar_attach_node(dn, parent_dn);
258 dlpar_free_cc_nodes(dn);
260 pr_debug("added node %pOFfp\n", dn);
265 int pseries_devicetree_update(s32 scope)
269 int update_nodes_token;
272 update_nodes_token = rtas_token("ibm,update-nodes");
273 if (update_nodes_token == RTAS_UNKNOWN_SERVICE)
276 rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL);
281 rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope);
285 data = (__be32 *)rtas_buf + 4;
286 while (be32_to_cpu(*data) & NODE_ACTION_MASK) {
288 u32 action = be32_to_cpu(*data) & NODE_ACTION_MASK;
289 u32 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK;
293 for (i = 0; i < node_count; i++) {
294 struct device_node *np;
295 __be32 phandle = *data++;
298 np = of_find_node_by_phandle(be32_to_cpu(phandle));
300 pr_warn("Failed lookup: phandle 0x%x for action 0x%x\n",
301 be32_to_cpu(phandle), action);
310 update_dt_node(np, scope);
314 add_dt_node(np, drc_index);
330 void post_mobility_fixup(void)
333 int activate_fw_token;
335 activate_fw_token = rtas_token("ibm,activate-firmware");
336 if (activate_fw_token == RTAS_UNKNOWN_SERVICE) {
337 printk(KERN_ERR "Could not make post-mobility "
338 "activate-fw call.\n");
343 rc = rtas_call(activate_fw_token, 0, 1, NULL);
344 } while (rtas_busy_delay(rc));
347 printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc);
350 * We don't want CPUs to go online/offline while the device
351 * tree is being updated.
356 * It's common for the destination firmware to replace cache
357 * nodes. Release all of the cacheinfo hierarchy's references
358 * before updating the device tree.
360 cacheinfo_teardown();
362 rc = pseries_devicetree_update(MIGRATION_SCOPE);
364 printk(KERN_ERR "Post-mobility device tree update "
371 /* Possibly switch to a new L1 flush type */
372 pseries_setup_security_mitigations();
374 /* Reinitialise system information for hv-24x7 */
375 read_24x7_sys_info();
380 static ssize_t migration_store(struct class *class,
381 struct class_attribute *attr, const char *buf,
387 rc = kstrtou64(buf, 0, &streamid);
392 rc = rtas_ibm_suspend_me(streamid);
395 } while (rc == -EAGAIN);
400 post_mobility_fixup();
406 * Used by drmgr to determine the kernel behavior of the migration interface.
408 * Version 1: Performs all PAPR requirements for migration including
409 * firmware activation and device tree update.
411 #define MIGRATION_API_VERSION 1
413 static CLASS_ATTR_WO(migration);
414 static CLASS_ATTR_STRING(api_version, 0444, __stringify(MIGRATION_API_VERSION));
416 static int __init mobility_sysfs_init(void)
420 mobility_kobj = kobject_create_and_add("mobility", kernel_kobj);
424 rc = sysfs_create_file(mobility_kobj, &class_attr_migration.attr);
426 pr_err("unable to create migration sysfs file (%d)\n", rc);
428 rc = sysfs_create_file(mobility_kobj, &class_attr_api_version.attr.attr);
430 pr_err("unable to create api_version sysfs file (%d)\n", rc);
434 machine_device_initcall(pseries, mobility_sysfs_init);