1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/kernel.h> 3 #include <linux/fs.h> 4 #include <linux/semaphore.h> 5 #include <linux/slab.h> 6 #include <linux/uaccess.h> 7 #include <asm/rtas.h> 8 9 #include "cxl.h" 10 #include "hcalls.h" 11 12 #define DOWNLOAD_IMAGE 1 13 #define VALIDATE_IMAGE 2 14 15 struct ai_header { 16 u16 version; 17 u8 reserved0[6]; 18 u16 vendor; 19 u16 device; 20 u16 subsystem_vendor; 21 u16 subsystem; 22 u64 image_offset; 23 u64 image_length; 24 u8 reserved1[96]; 25 }; 26 27 static struct semaphore sem; 28 static unsigned long *buffer[CXL_AI_MAX_ENTRIES]; 29 static struct sg_list *le; 30 static u64 continue_token; 31 static unsigned int transfer; 32 33 struct update_props_workarea { 34 __be32 phandle; 35 __be32 state; 36 __be64 reserved; 37 __be32 nprops; 38 } __packed; 39 40 struct update_nodes_workarea { 41 __be32 state; 42 __be64 unit_address; 43 __be32 reserved; 44 } __packed; 45 46 #define DEVICE_SCOPE 3 47 #define NODE_ACTION_MASK 0xff000000 48 #define NODE_COUNT_MASK 0x00ffffff 49 #define OPCODE_DELETE 0x01000000 50 #define OPCODE_UPDATE 0x02000000 51 #define OPCODE_ADD 0x03000000 52 53 static int rcall(int token, char *buf, s32 scope) 54 { 55 int rc; 56 57 spin_lock(&rtas_data_buf_lock); 58 59 memcpy(rtas_data_buf, buf, RTAS_DATA_BUF_SIZE); 60 rc = rtas_call(token, 2, 1, NULL, rtas_data_buf, scope); 61 memcpy(buf, rtas_data_buf, RTAS_DATA_BUF_SIZE); 62 63 spin_unlock(&rtas_data_buf_lock); 64 return rc; 65 } 66 67 static int update_property(struct device_node *dn, const char *name, 68 u32 vd, char *value) 69 { 70 struct property *new_prop; 71 u32 *val; 72 int rc; 73 74 new_prop = kzalloc(sizeof(*new_prop), GFP_KERNEL); 75 if (!new_prop) 76 return -ENOMEM; 77 78 new_prop->name = kstrdup(name, GFP_KERNEL); 79 if (!new_prop->name) { 80 kfree(new_prop); 81 return -ENOMEM; 82 } 83 84 new_prop->length = vd; 85 new_prop->value = kzalloc(new_prop->length, GFP_KERNEL); 86 if (!new_prop->value) { 87 kfree(new_prop->name); 88 kfree(new_prop); 89 return -ENOMEM; 90 } 91 memcpy(new_prop->value, value, vd); 92 93 val = (u32 *)new_prop->value; 94 rc = cxl_update_properties(dn, new_prop); 95 pr_devel("%pOFn: update property (%s, length: %i, value: %#x)\n", 96 dn, name, vd, be32_to_cpu(*val)); 97 98 if (rc) { 99 kfree(new_prop->name); 100 kfree(new_prop->value); 101 kfree(new_prop); 102 } 103 return rc; 104 } 105 106 static int update_node(__be32 phandle, s32 scope) 107 { 108 struct update_props_workarea *upwa; 109 struct device_node *dn; 110 int i, rc, ret; 111 char *prop_data; 112 char *buf; 113 int token; 114 u32 nprops; 115 u32 vd; 116 117 token = rtas_token("ibm,update-properties"); 118 if (token == RTAS_UNKNOWN_SERVICE) 119 return -EINVAL; 120 121 buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 122 if (!buf) 123 return -ENOMEM; 124 125 dn = of_find_node_by_phandle(be32_to_cpu(phandle)); 126 if (!dn) { 127 kfree(buf); 128 return -ENOENT; 129 } 130 131 upwa = (struct update_props_workarea *)&buf[0]; 132 upwa->phandle = phandle; 133 do { 134 rc = rcall(token, buf, scope); 135 if (rc < 0) 136 break; 137 138 prop_data = buf + sizeof(*upwa); 139 nprops = be32_to_cpu(upwa->nprops); 140 141 if (*prop_data == 0) { 142 prop_data++; 143 vd = be32_to_cpu(*(__be32 *)prop_data); 144 prop_data += vd + sizeof(vd); 145 nprops--; 146 } 147 148 for (i = 0; i < nprops; i++) { 149 char *prop_name; 150 151 prop_name = prop_data; 152 prop_data += strlen(prop_name) + 1; 153 vd = be32_to_cpu(*(__be32 *)prop_data); 154 prop_data += sizeof(vd); 155 156 if ((vd != 0x00000000) && (vd != 0x80000000)) { 157 ret = update_property(dn, prop_name, vd, 158 prop_data); 159 if (ret) 160 pr_err("cxl: Could not update property %s - %i\n", 161 prop_name, ret); 162 163 prop_data += vd; 164 } 165 } 166 } while (rc == 1); 167 168 of_node_put(dn); 169 kfree(buf); 170 return rc; 171 } 172 173 static int update_devicetree(struct cxl *adapter, s32 scope) 174 { 175 struct update_nodes_workarea *unwa; 176 u32 action, node_count; 177 int token, rc, i; 178 __be32 *data, phandle; 179 char *buf; 180 181 token = rtas_token("ibm,update-nodes"); 182 if (token == RTAS_UNKNOWN_SERVICE) 183 return -EINVAL; 184 185 buf = kzalloc(RTAS_DATA_BUF_SIZE, GFP_KERNEL); 186 if (!buf) 187 return -ENOMEM; 188 189 unwa = (struct update_nodes_workarea *)&buf[0]; 190 unwa->unit_address = cpu_to_be64(adapter->guest->handle); 191 do { 192 rc = rcall(token, buf, scope); 193 if (rc && rc != 1) 194 break; 195 196 data = (__be32 *)buf + 4; 197 while (be32_to_cpu(*data) & NODE_ACTION_MASK) { 198 action = be32_to_cpu(*data) & NODE_ACTION_MASK; 199 node_count = be32_to_cpu(*data) & NODE_COUNT_MASK; 200 pr_devel("device reconfiguration - action: %#x, nodes: %#x\n", 201 action, node_count); 202 data++; 203 204 for (i = 0; i < node_count; i++) { 205 phandle = *data++; 206 207 switch (action) { 208 case OPCODE_DELETE: 209 /* nothing to do */ 210 break; 211 case OPCODE_UPDATE: 212 update_node(phandle, scope); 213 break; 214 case OPCODE_ADD: 215 /* nothing to do, just move pointer */ 216 data++; 217 break; 218 } 219 } 220 } 221 } while (rc == 1); 222 223 kfree(buf); 224 return 0; 225 } 226 227 static int handle_image(struct cxl *adapter, int operation, 228 long (*fct)(u64, u64, u64, u64 *), 229 struct cxl_adapter_image *ai) 230 { 231 size_t mod, s_copy, len_chunk = 0; 232 struct ai_header *header = NULL; 233 unsigned int entries = 0, i; 234 void *dest, *from; 235 int rc = 0, need_header; 236 237 /* base adapter image header */ 238 need_header = (ai->flags & CXL_AI_NEED_HEADER); 239 if (need_header) { 240 header = kzalloc(sizeof(struct ai_header), GFP_KERNEL); 241 if (!header) 242 return -ENOMEM; 243 header->version = cpu_to_be16(1); 244 header->vendor = cpu_to_be16(adapter->guest->vendor); 245 header->device = cpu_to_be16(adapter->guest->device); 246 header->subsystem_vendor = cpu_to_be16(adapter->guest->subsystem_vendor); 247 header->subsystem = cpu_to_be16(adapter->guest->subsystem); 248 header->image_offset = cpu_to_be64(CXL_AI_HEADER_SIZE); 249 header->image_length = cpu_to_be64(ai->len_image); 250 } 251 252 /* number of entries in the list */ 253 len_chunk = ai->len_data; 254 if (need_header) 255 len_chunk += CXL_AI_HEADER_SIZE; 256 257 entries = len_chunk / CXL_AI_BUFFER_SIZE; 258 mod = len_chunk % CXL_AI_BUFFER_SIZE; 259 if (mod) 260 entries++; 261 262 if (entries > CXL_AI_MAX_ENTRIES) { 263 rc = -EINVAL; 264 goto err; 265 } 266 267 /* < -- MAX_CHUNK_SIZE = 4096 * 256 = 1048576 bytes --> 268 * chunk 0 ---------------------------------------------------- 269 * | header | data | 270 * ---------------------------------------------------- 271 * chunk 1 ---------------------------------------------------- 272 * | data | 273 * ---------------------------------------------------- 274 * .... 275 * chunk n ---------------------------------------------------- 276 * | data | 277 * ---------------------------------------------------- 278 */ 279 from = (void *) ai->data; 280 for (i = 0; i < entries; i++) { 281 dest = buffer[i]; 282 s_copy = CXL_AI_BUFFER_SIZE; 283 284 if ((need_header) && (i == 0)) { 285 /* add adapter image header */ 286 memcpy(buffer[i], header, sizeof(struct ai_header)); 287 s_copy = CXL_AI_BUFFER_SIZE - CXL_AI_HEADER_SIZE; 288 dest += CXL_AI_HEADER_SIZE; /* image offset */ 289 } 290 if ((i == (entries - 1)) && mod) 291 s_copy = mod; 292 293 /* copy data */ 294 if (copy_from_user(dest, from, s_copy)) 295 goto err; 296 297 /* fill in the list */ 298 le[i].phys_addr = cpu_to_be64(virt_to_phys(buffer[i])); 299 le[i].len = cpu_to_be64(CXL_AI_BUFFER_SIZE); 300 if ((i == (entries - 1)) && mod) 301 le[i].len = cpu_to_be64(mod); 302 from += s_copy; 303 } 304 pr_devel("%s (op: %i, need header: %i, entries: %i, token: %#llx)\n", 305 __func__, operation, need_header, entries, continue_token); 306 307 /* 308 * download/validate the adapter image to the coherent 309 * platform facility 310 */ 311 rc = fct(adapter->guest->handle, virt_to_phys(le), entries, 312 &continue_token); 313 if (rc == 0) /* success of download/validation operation */ 314 continue_token = 0; 315 316 err: 317 kfree(header); 318 319 return rc; 320 } 321 322 static int transfer_image(struct cxl *adapter, int operation, 323 struct cxl_adapter_image *ai) 324 { 325 int rc = 0; 326 int afu; 327 328 switch (operation) { 329 case DOWNLOAD_IMAGE: 330 rc = handle_image(adapter, operation, 331 &cxl_h_download_adapter_image, ai); 332 if (rc < 0) { 333 pr_devel("resetting adapter\n"); 334 cxl_h_reset_adapter(adapter->guest->handle); 335 } 336 return rc; 337 338 case VALIDATE_IMAGE: 339 rc = handle_image(adapter, operation, 340 &cxl_h_validate_adapter_image, ai); 341 if (rc < 0) { 342 pr_devel("resetting adapter\n"); 343 cxl_h_reset_adapter(adapter->guest->handle); 344 return rc; 345 } 346 if (rc == 0) { 347 pr_devel("remove current afu\n"); 348 for (afu = 0; afu < adapter->slices; afu++) 349 cxl_guest_remove_afu(adapter->afu[afu]); 350 351 pr_devel("resetting adapter\n"); 352 cxl_h_reset_adapter(adapter->guest->handle); 353 354 /* The entire image has now been 355 * downloaded and the validation has 356 * been successfully performed. 357 * After that, the partition should call 358 * ibm,update-nodes and 359 * ibm,update-properties to receive the 360 * current configuration 361 */ 362 rc = update_devicetree(adapter, DEVICE_SCOPE); 363 transfer = 1; 364 } 365 return rc; 366 } 367 368 return -EINVAL; 369 } 370 371 static long ioctl_transfer_image(struct cxl *adapter, int operation, 372 struct cxl_adapter_image __user *uai) 373 { 374 struct cxl_adapter_image ai; 375 376 pr_devel("%s\n", __func__); 377 378 if (copy_from_user(&ai, uai, sizeof(struct cxl_adapter_image))) 379 return -EFAULT; 380 381 /* 382 * Make sure reserved fields and bits are set to 0 383 */ 384 if (ai.reserved1 || ai.reserved2 || ai.reserved3 || ai.reserved4 || 385 (ai.flags & ~CXL_AI_ALL)) 386 return -EINVAL; 387 388 return transfer_image(adapter, operation, &ai); 389 } 390 391 static int device_open(struct inode *inode, struct file *file) 392 { 393 int adapter_num = CXL_DEVT_ADAPTER(inode->i_rdev); 394 struct cxl *adapter; 395 int rc = 0, i; 396 397 pr_devel("in %s\n", __func__); 398 399 BUG_ON(sizeof(struct ai_header) != CXL_AI_HEADER_SIZE); 400 401 /* Allows one process to open the device by using a semaphore */ 402 if (down_interruptible(&sem) != 0) 403 return -EPERM; 404 405 if (!(adapter = get_cxl_adapter(adapter_num))) { 406 rc = -ENODEV; 407 goto err_unlock; 408 } 409 410 file->private_data = adapter; 411 continue_token = 0; 412 transfer = 0; 413 414 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) 415 buffer[i] = NULL; 416 417 /* aligned buffer containing list entries which describes up to 418 * 1 megabyte of data (256 entries of 4096 bytes each) 419 * Logical real address of buffer 0 - Buffer 0 length in bytes 420 * Logical real address of buffer 1 - Buffer 1 length in bytes 421 * Logical real address of buffer 2 - Buffer 2 length in bytes 422 * .... 423 * .... 424 * Logical real address of buffer N - Buffer N length in bytes 425 */ 426 le = (struct sg_list *)get_zeroed_page(GFP_KERNEL); 427 if (!le) { 428 rc = -ENOMEM; 429 goto err; 430 } 431 432 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) { 433 buffer[i] = (unsigned long *)get_zeroed_page(GFP_KERNEL); 434 if (!buffer[i]) { 435 rc = -ENOMEM; 436 goto err1; 437 } 438 } 439 440 return 0; 441 442 err1: 443 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) { 444 if (buffer[i]) 445 free_page((unsigned long) buffer[i]); 446 } 447 448 if (le) 449 free_page((unsigned long) le); 450 err: 451 put_device(&adapter->dev); 452 err_unlock: 453 up(&sem); 454 455 return rc; 456 } 457 458 static long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 459 { 460 struct cxl *adapter = file->private_data; 461 462 pr_devel("in %s\n", __func__); 463 464 if (cmd == CXL_IOCTL_DOWNLOAD_IMAGE) 465 return ioctl_transfer_image(adapter, 466 DOWNLOAD_IMAGE, 467 (struct cxl_adapter_image __user *)arg); 468 else if (cmd == CXL_IOCTL_VALIDATE_IMAGE) 469 return ioctl_transfer_image(adapter, 470 VALIDATE_IMAGE, 471 (struct cxl_adapter_image __user *)arg); 472 else 473 return -EINVAL; 474 } 475 476 static int device_close(struct inode *inode, struct file *file) 477 { 478 struct cxl *adapter = file->private_data; 479 int i; 480 481 pr_devel("in %s\n", __func__); 482 483 for (i = 0; i < CXL_AI_MAX_ENTRIES; i++) { 484 if (buffer[i]) 485 free_page((unsigned long) buffer[i]); 486 } 487 488 if (le) 489 free_page((unsigned long) le); 490 491 up(&sem); 492 put_device(&adapter->dev); 493 continue_token = 0; 494 495 /* reload the module */ 496 if (transfer) 497 cxl_guest_reload_module(adapter); 498 else { 499 pr_devel("resetting adapter\n"); 500 cxl_h_reset_adapter(adapter->guest->handle); 501 } 502 503 transfer = 0; 504 return 0; 505 } 506 507 static const struct file_operations fops = { 508 .owner = THIS_MODULE, 509 .open = device_open, 510 .unlocked_ioctl = device_ioctl, 511 .compat_ioctl = compat_ptr_ioctl, 512 .release = device_close, 513 }; 514 515 void cxl_guest_remove_chardev(struct cxl *adapter) 516 { 517 cdev_del(&adapter->guest->cdev); 518 } 519 520 int cxl_guest_add_chardev(struct cxl *adapter) 521 { 522 dev_t devt; 523 int rc; 524 525 devt = MKDEV(MAJOR(cxl_get_dev()), CXL_CARD_MINOR(adapter)); 526 cdev_init(&adapter->guest->cdev, &fops); 527 if ((rc = cdev_add(&adapter->guest->cdev, devt, 1))) { 528 dev_err(&adapter->dev, 529 "Unable to add chardev on adapter (card%i): %i\n", 530 adapter->adapter_num, rc); 531 goto err; 532 } 533 adapter->dev.devt = devt; 534 sema_init(&sem, 1); 535 err: 536 return rc; 537 } 538