1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Support for Partition Mobility/Migration 4 * 5 * Copyright (C) 2010 Nathan Fontenot 6 * Copyright (C) 2010 IBM Corporation 7 */ 8 9 10#define pr_fmt(fmt) "mobility: " fmt 11 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> 23 24#include <asm/machdep.h> 25#include <asm/rtas.h> 26#include "pseries.h" 27#include "../../kernel/cacheinfo.h" 28 29static struct kobject *mobility_kobj; 30 31struct update_props_workarea { 32 __be32 phandle; 33 __be32 state; 34 __be64 reserved; 35 __be32 nprops; 36} __packed; 37 38#define NODE_ACTION_MASK 0xff000000 39#define NODE_COUNT_MASK 0x00ffffff 40 41#define DELETE_DT_NODE 0x01000000 42#define UPDATE_DT_NODE 0x02000000 43#define ADD_DT_NODE 0x03000000 44 45#define MIGRATION_SCOPE (1) 46#define PRRN_SCOPE -2 47 48static int mobility_rtas_call(int token, char *buf, s32 scope) 49{ 50 int rc; 51 52 spin_lock(&rtas_data_buf_lock); 53 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); 57 58 spin_unlock(&rtas_data_buf_lock); 59 return rc; 60} 61 62static int delete_dt_node(struct device_node *dn) 63{ 64 struct device_node *pdn; 65 bool is_platfac; 66 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); 71 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); 86 dlpar_detach_node(dn); 87 return 0; 88} 89 90static int update_dt_property(struct device_node *dn, struct property **prop, 91 const char *name, u32 vd, char *value) 92{ 93 struct property *new_prop = *prop; 94 int more = 0; 95 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. 99 * 100 * A negative value is also the two's compliment of the actual value. 101 */ 102 if (vd & 0x80000000) { 103 vd = ~vd + 1; 104 more = 1; 105 } 106 107 if (new_prop) { 108 /* partial property fixup */ 109 char *new_data = kzalloc(new_prop->length + vd, GFP_KERNEL); 110 if (!new_data) 111 return -ENOMEM; 112 113 memcpy(new_data, new_prop->value, new_prop->length); 114 memcpy(new_data + new_prop->length, value, vd); 115 116 kfree(new_prop->value); 117 new_prop->value = new_data; 118 new_prop->length += vd; 119 } else { 120 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); 121 if (!new_prop) 122 return -ENOMEM; 123 124 new_prop->name = kstrdup(name, GFP_KERNEL); 125 if (!new_prop->name) { 126 kfree(new_prop); 127 return -ENOMEM; 128 } 129 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); 134 kfree(new_prop); 135 return -ENOMEM; 136 } 137 138 memcpy(new_prop->value, value, vd); 139 *prop = new_prop; 140 } 141 142 if (!more) { 143 pr_debug("updating node %pOF property %s\n", dn, name); 144 of_update_property(dn, new_prop); 145 *prop = NULL; 146 } 147 148 return 0; 149} 150 151static int update_dt_node(struct device_node *dn, s32 scope) 152{ 153 struct update_props_workarea *upwa; 154 struct property *prop = NULL; 155 int i, rc, rtas_rc; 156 char *prop_data; 157 char *rtas_buf; 158 int update_properties_token; 159 u32 nprops; 160 u32 vd; 161 162 update_properties_token = rtas_token("ibm,update-properties"); 163 if (update_properties_token == RTAS_UNKNOWN_SERVICE) 164 return -EINVAL; 165 166 rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 167 if (!rtas_buf) 168 return -ENOMEM; 169 170 upwa = (struct update_props_workarea *)&rtas_buf[0]; 171 upwa->phandle = cpu_to_be32(dn->phandle); 172 173 do { 174 rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf, 175 scope); 176 if (rtas_rc < 0) 177 break; 178 179 prop_data = rtas_buf + sizeof(*upwa); 180 nprops = be32_to_cpu(upwa->nprops); 181 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. 186 */ 187 if (*prop_data == 0) { 188 prop_data++; 189 vd = be32_to_cpu(*(__be32 *)prop_data); 190 prop_data += vd + sizeof(vd); 191 nprops--; 192 } 193 194 for (i = 0; i < nprops; i++) { 195 char *prop_name; 196 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); 201 202 switch (vd) { 203 case 0x00000000: 204 /* name only property, nothing to do */ 205 break; 206 207 case 0x80000000: 208 of_remove_property(dn, of_find_property(dn, 209 prop_name, NULL)); 210 prop = NULL; 211 break; 212 213 default: 214 rc = update_dt_property(dn, &prop, prop_name, 215 vd, prop_data); 216 if (rc) { 217 printk(KERN_ERR "Could not update %s" 218 " property\n", prop_name); 219 } 220 221 prop_data += vd; 222 } 223 224 cond_resched(); 225 } 226 227 cond_resched(); 228 } while (rtas_rc == 1); 229 230 kfree(rtas_buf); 231 return 0; 232} 233 234static int add_dt_node(struct device_node *parent_dn, __be32 drc_index) 235{ 236 struct device_node *dn; 237 int rc; 238 239 dn = dlpar_configure_connector(drc_index, parent_dn); 240 if (!dn) 241 return -ENOENT; 242 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; 254 } 255 256 rc = dlpar_attach_node(dn, parent_dn); 257 if (rc) 258 dlpar_free_cc_nodes(dn); 259 260 pr_debug("added node %pOFfp\n", dn); 261 262 return rc; 263} 264 265int pseries_devicetree_update(s32 scope) 266{ 267 char *rtas_buf; 268 __be32 *data; 269 int update_nodes_token; 270 int rc; 271 272 update_nodes_token = rtas_token("ibm,update-nodes"); 273 if (update_nodes_token == RTAS_UNKNOWN_SERVICE) 274 return -EINVAL; 275 276 rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 277 if (!rtas_buf) 278 return -ENOMEM; 279 280 do { 281 rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope); 282 if (rc && rc != 1) 283 break; 284 285 data = (__be32 *)rtas_buf + 4; 286 while (be32_to_cpu(*data) & NODE_ACTION_MASK) { 287 int i; 288 u32 action = be32_to_cpu(*data) & NODE_ACTION_MASK; 289 u32 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK; 290 291 data++; 292 293 for (i = 0; i < node_count; i++) { 294 struct device_node *np; 295 __be32 phandle = *data++; 296 __be32 drc_index; 297 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 305 switch (action) { 306 case DELETE_DT_NODE: 307 delete_dt_node(np); 308 break; 309 case UPDATE_DT_NODE: 310 update_dt_node(np, scope); 311 break; 312 case ADD_DT_NODE: 313 drc_index = *data++; 314 add_dt_node(np, drc_index); 315 break; 316 } 317 318 of_node_put(np); 319 cond_resched(); 320 } 321 } 322 323 cond_resched(); 324 } while (rc == 1); 325 326 kfree(rtas_buf); 327 return rc; 328} 329 330void post_mobility_fixup(void) 331{ 332 int rc; 333 int activate_fw_token; 334 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"); 339 return; 340 } 341 342 do { 343 rc = rtas_call(activate_fw_token, 0, 1, NULL); 344 } while (rtas_busy_delay(rc)); 345 346 if (rc) 347 printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc); 348 349 /* 350 * We don't want CPUs to go online/offline while the device 351 * tree is being updated. 352 */ 353 cpus_read_lock(); 354 355 /* 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. 359 */ 360 cacheinfo_teardown(); 361 362 rc = pseries_devicetree_update(MIGRATION_SCOPE); 363 if (rc) 364 printk(KERN_ERR "Post-mobility device tree update " 365 "failed: %d\n", rc); 366 367 cacheinfo_rebuild(); 368 369 cpus_read_unlock(); 370 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(); 376 377 return; 378} 379 380static ssize_t migration_store(struct class *class, 381 struct class_attribute *attr, const char *buf, 382 size_t count) 383{ 384 u64 streamid; 385 int rc; 386 387 rc = kstrtou64(buf, 0, &streamid); 388 if (rc) 389 return rc; 390 391 do { 392 rc = rtas_ibm_suspend_me(streamid); 393 if (rc == -EAGAIN) 394 ssleep(1); 395 } while (rc == -EAGAIN); 396 397 if (rc) 398 return rc; 399 400 post_mobility_fixup(); 401 402 return count; 403} 404 405/* 406 * Used by drmgr to determine the kernel behavior of the migration interface. 407 * 408 * Version 1: Performs all PAPR requirements for migration including 409 * firmware activation and device tree update. 410 */ 411#define MIGRATION_API_VERSION 1 412 413static CLASS_ATTR_WO(migration); 414static CLASS_ATTR_STRING(api_version, 0444, __stringify(MIGRATION_API_VERSION)); 415 416static int __init mobility_sysfs_init(void) 417{ 418 int rc; 419 420 mobility_kobj = kobject_create_and_add("mobility", kernel_kobj); 421 if (!mobility_kobj) 422 return -ENOMEM; 423 424 rc = sysfs_create_file(mobility_kobj, &class_attr_migration.attr); 425 if (rc) 426 pr_err("unable to create migration sysfs file (%d)\n", rc); 427 428 rc = sysfs_create_file(mobility_kobj, &class_attr_api_version.attr.attr); 429 if (rc) 430 pr_err("unable to create api_version sysfs file (%d)\n", rc); 431 432 return 0; 433} 434machine_device_initcall(pseries, mobility_sysfs_init); 435