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 #include <linux/kernel.h> 10 #include <linux/kobject.h> 11 #include <linux/smp.h> 12 #include <linux/stat.h> 13 #include <linux/completion.h> 14 #include <linux/device.h> 15 #include <linux/delay.h> 16 #include <linux/slab.h> 17 #include <linux/stringify.h> 18 19 #include <asm/machdep.h> 20 #include <asm/rtas.h> 21 #include "pseries.h" 22 23 static struct kobject *mobility_kobj; 24 25 struct update_props_workarea { 26 __be32 phandle; 27 __be32 state; 28 __be64 reserved; 29 __be32 nprops; 30 } __packed; 31 32 #define NODE_ACTION_MASK 0xff000000 33 #define NODE_COUNT_MASK 0x00ffffff 34 35 #define DELETE_DT_NODE 0x01000000 36 #define UPDATE_DT_NODE 0x02000000 37 #define ADD_DT_NODE 0x03000000 38 39 #define MIGRATION_SCOPE (1) 40 #define PRRN_SCOPE -2 41 42 static int mobility_rtas_call(int token, char *buf, s32 scope) 43 { 44 int rc; 45 46 spin_lock(&rtas_data_buf_lock); 47 48 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); 49 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope); 50 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); 51 52 spin_unlock(&rtas_data_buf_lock); 53 return rc; 54 } 55 56 static int delete_dt_node(__be32 phandle) 57 { 58 struct device_node *dn; 59 60 dn = of_find_node_by_phandle(be32_to_cpu(phandle)); 61 if (!dn) 62 return -ENOENT; 63 64 dlpar_detach_node(dn); 65 of_node_put(dn); 66 return 0; 67 } 68 69 static int update_dt_property(struct device_node *dn, struct property **prop, 70 const char *name, u32 vd, char *value) 71 { 72 struct property *new_prop = *prop; 73 int more = 0; 74 75 /* A negative 'vd' value indicates that only part of the new property 76 * value is contained in the buffer and we need to call 77 * ibm,update-properties again to get the rest of the value. 78 * 79 * A negative value is also the two's compliment of the actual value. 80 */ 81 if (vd & 0x80000000) { 82 vd = ~vd + 1; 83 more = 1; 84 } 85 86 if (new_prop) { 87 /* partial property fixup */ 88 char *new_data = kzalloc(new_prop->length + vd, GFP_KERNEL); 89 if (!new_data) 90 return -ENOMEM; 91 92 memcpy(new_data, new_prop->value, new_prop->length); 93 memcpy(new_data + new_prop->length, value, vd); 94 95 kfree(new_prop->value); 96 new_prop->value = new_data; 97 new_prop->length += vd; 98 } else { 99 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); 100 if (!new_prop) 101 return -ENOMEM; 102 103 new_prop->name = kstrdup(name, GFP_KERNEL); 104 if (!new_prop->name) { 105 kfree(new_prop); 106 return -ENOMEM; 107 } 108 109 new_prop->length = vd; 110 new_prop->value = kzalloc(new_prop->length, GFP_KERNEL); 111 if (!new_prop->value) { 112 kfree(new_prop->name); 113 kfree(new_prop); 114 return -ENOMEM; 115 } 116 117 memcpy(new_prop->value, value, vd); 118 *prop = new_prop; 119 } 120 121 if (!more) { 122 of_update_property(dn, new_prop); 123 *prop = NULL; 124 } 125 126 return 0; 127 } 128 129 static int update_dt_node(__be32 phandle, s32 scope) 130 { 131 struct update_props_workarea *upwa; 132 struct device_node *dn; 133 struct property *prop = NULL; 134 int i, rc, rtas_rc; 135 char *prop_data; 136 char *rtas_buf; 137 int update_properties_token; 138 u32 nprops; 139 u32 vd; 140 141 update_properties_token = rtas_token("ibm,update-properties"); 142 if (update_properties_token == RTAS_UNKNOWN_SERVICE) 143 return -EINVAL; 144 145 rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 146 if (!rtas_buf) 147 return -ENOMEM; 148 149 dn = of_find_node_by_phandle(be32_to_cpu(phandle)); 150 if (!dn) { 151 kfree(rtas_buf); 152 return -ENOENT; 153 } 154 155 upwa = (struct update_props_workarea *)&rtas_buf[0]; 156 upwa->phandle = phandle; 157 158 do { 159 rtas_rc = mobility_rtas_call(update_properties_token, rtas_buf, 160 scope); 161 if (rtas_rc < 0) 162 break; 163 164 prop_data = rtas_buf + sizeof(*upwa); 165 nprops = be32_to_cpu(upwa->nprops); 166 167 /* On the first call to ibm,update-properties for a node the 168 * the first property value descriptor contains an empty 169 * property name, the property value length encoded as u32, 170 * and the property value is the node path being updated. 171 */ 172 if (*prop_data == 0) { 173 prop_data++; 174 vd = be32_to_cpu(*(__be32 *)prop_data); 175 prop_data += vd + sizeof(vd); 176 nprops--; 177 } 178 179 for (i = 0; i < nprops; i++) { 180 char *prop_name; 181 182 prop_name = prop_data; 183 prop_data += strlen(prop_name) + 1; 184 vd = be32_to_cpu(*(__be32 *)prop_data); 185 prop_data += sizeof(vd); 186 187 switch (vd) { 188 case 0x00000000: 189 /* name only property, nothing to do */ 190 break; 191 192 case 0x80000000: 193 of_remove_property(dn, of_find_property(dn, 194 prop_name, NULL)); 195 prop = NULL; 196 break; 197 198 default: 199 rc = update_dt_property(dn, &prop, prop_name, 200 vd, prop_data); 201 if (rc) { 202 printk(KERN_ERR "Could not update %s" 203 " property\n", prop_name); 204 } 205 206 prop_data += vd; 207 } 208 } 209 } while (rtas_rc == 1); 210 211 of_node_put(dn); 212 kfree(rtas_buf); 213 return 0; 214 } 215 216 static int add_dt_node(__be32 parent_phandle, __be32 drc_index) 217 { 218 struct device_node *dn; 219 struct device_node *parent_dn; 220 int rc; 221 222 parent_dn = of_find_node_by_phandle(be32_to_cpu(parent_phandle)); 223 if (!parent_dn) 224 return -ENOENT; 225 226 dn = dlpar_configure_connector(drc_index, parent_dn); 227 if (!dn) { 228 of_node_put(parent_dn); 229 return -ENOENT; 230 } 231 232 rc = dlpar_attach_node(dn, parent_dn); 233 if (rc) 234 dlpar_free_cc_nodes(dn); 235 236 of_node_put(parent_dn); 237 return rc; 238 } 239 240 static void prrn_update_node(__be32 phandle) 241 { 242 struct pseries_hp_errorlog hp_elog; 243 struct device_node *dn; 244 245 /* 246 * If a node is found from a the given phandle, the phandle does not 247 * represent the drc index of an LMB and we can ignore. 248 */ 249 dn = of_find_node_by_phandle(be32_to_cpu(phandle)); 250 if (dn) { 251 of_node_put(dn); 252 return; 253 } 254 255 hp_elog.resource = PSERIES_HP_ELOG_RESOURCE_MEM; 256 hp_elog.action = PSERIES_HP_ELOG_ACTION_READD; 257 hp_elog.id_type = PSERIES_HP_ELOG_ID_DRC_INDEX; 258 hp_elog._drc_u.drc_index = phandle; 259 260 handle_dlpar_errorlog(&hp_elog); 261 } 262 263 int pseries_devicetree_update(s32 scope) 264 { 265 char *rtas_buf; 266 __be32 *data; 267 int update_nodes_token; 268 int rc; 269 270 update_nodes_token = rtas_token("ibm,update-nodes"); 271 if (update_nodes_token == RTAS_UNKNOWN_SERVICE) 272 return -EINVAL; 273 274 rtas_buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 275 if (!rtas_buf) 276 return -ENOMEM; 277 278 do { 279 rc = mobility_rtas_call(update_nodes_token, rtas_buf, scope); 280 if (rc && rc != 1) 281 break; 282 283 data = (__be32 *)rtas_buf + 4; 284 while (be32_to_cpu(*data) & NODE_ACTION_MASK) { 285 int i; 286 u32 action = be32_to_cpu(*data) & NODE_ACTION_MASK; 287 u32 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK; 288 289 data++; 290 291 for (i = 0; i < node_count; i++) { 292 __be32 phandle = *data++; 293 __be32 drc_index; 294 295 switch (action) { 296 case DELETE_DT_NODE: 297 delete_dt_node(phandle); 298 break; 299 case UPDATE_DT_NODE: 300 update_dt_node(phandle, scope); 301 302 if (scope == PRRN_SCOPE) 303 prrn_update_node(phandle); 304 305 break; 306 case ADD_DT_NODE: 307 drc_index = *data++; 308 add_dt_node(phandle, drc_index); 309 break; 310 } 311 } 312 } 313 } while (rc == 1); 314 315 kfree(rtas_buf); 316 return rc; 317 } 318 319 void post_mobility_fixup(void) 320 { 321 int rc; 322 int activate_fw_token; 323 324 activate_fw_token = rtas_token("ibm,activate-firmware"); 325 if (activate_fw_token == RTAS_UNKNOWN_SERVICE) { 326 printk(KERN_ERR "Could not make post-mobility " 327 "activate-fw call.\n"); 328 return; 329 } 330 331 do { 332 rc = rtas_call(activate_fw_token, 0, 1, NULL); 333 } while (rtas_busy_delay(rc)); 334 335 if (rc) 336 printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc); 337 338 rc = pseries_devicetree_update(MIGRATION_SCOPE); 339 if (rc) 340 printk(KERN_ERR "Post-mobility device tree update " 341 "failed: %d\n", rc); 342 343 /* Possibly switch to a new RFI flush type */ 344 pseries_setup_rfi_flush(); 345 346 return; 347 } 348 349 static ssize_t migration_store(struct class *class, 350 struct class_attribute *attr, const char *buf, 351 size_t count) 352 { 353 u64 streamid; 354 int rc; 355 356 rc = kstrtou64(buf, 0, &streamid); 357 if (rc) 358 return rc; 359 360 stop_topology_update(); 361 362 do { 363 rc = rtas_ibm_suspend_me(streamid); 364 if (rc == -EAGAIN) 365 ssleep(1); 366 } while (rc == -EAGAIN); 367 368 if (rc) 369 return rc; 370 371 post_mobility_fixup(); 372 373 start_topology_update(); 374 375 return count; 376 } 377 378 /* 379 * Used by drmgr to determine the kernel behavior of the migration interface. 380 * 381 * Version 1: Performs all PAPR requirements for migration including 382 * firmware activation and device tree update. 383 */ 384 #define MIGRATION_API_VERSION 1 385 386 static CLASS_ATTR_WO(migration); 387 static CLASS_ATTR_STRING(api_version, 0444, __stringify(MIGRATION_API_VERSION)); 388 389 static int __init mobility_sysfs_init(void) 390 { 391 int rc; 392 393 mobility_kobj = kobject_create_and_add("mobility", kernel_kobj); 394 if (!mobility_kobj) 395 return -ENOMEM; 396 397 rc = sysfs_create_file(mobility_kobj, &class_attr_migration.attr); 398 if (rc) 399 pr_err("mobility: unable to create migration sysfs file (%d)\n", rc); 400 401 rc = sysfs_create_file(mobility_kobj, &class_attr_api_version.attr.attr); 402 if (rc) 403 pr_err("mobility: unable to create api_version sysfs file (%d)\n", rc); 404 405 return 0; 406 } 407 machine_device_initcall(pseries, mobility_sysfs_init); 408