1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2025 Intel Corporation 4 */ 5 6 #include <linux/bitops.h> 7 #include <linux/ctype.h> 8 #include <linux/configfs.h> 9 #include <linux/cleanup.h> 10 #include <linux/find.h> 11 #include <linux/init.h> 12 #include <linux/module.h> 13 #include <linux/pci.h> 14 #include <linux/string.h> 15 16 #include "instructions/xe_mi_commands.h" 17 #include "xe_configfs.h" 18 #include "xe_defaults.h" 19 #include "xe_gt_types.h" 20 #include "xe_hw_engine_types.h" 21 #include "xe_module.h" 22 #include "xe_pci_types.h" 23 #include "xe_sriov_types.h" 24 25 /** 26 * DOC: Xe Configfs 27 * 28 * Overview 29 * ======== 30 * 31 * Configfs is a filesystem-based manager of kernel objects. Xe KMD registers a 32 * configfs subsystem called ``xe`` that creates a directory in the mounted 33 * configfs directory. The user can create devices under this directory and 34 * configure them as necessary. See Documentation/filesystems/configfs.rst for 35 * more information about how configfs works. 36 * 37 * Create devices 38 * ============== 39 * 40 * To create a device, the ``xe`` module should already be loaded, but some 41 * attributes can only be set before binding the device. It can be accomplished 42 * by blocking the driver autoprobe:: 43 * 44 * # echo 0 > /sys/bus/pci/drivers_autoprobe 45 * # modprobe xe 46 * 47 * In order to create a device, the user has to create a directory inside ``xe``:: 48 * 49 * # mkdir /sys/kernel/config/xe/0000:03:00.0/ 50 * 51 * Every device created is populated by the driver with entries that can be 52 * used to configure it:: 53 * 54 * /sys/kernel/config/xe/ 55 * ├── 0000:00:02.0 56 * │ └── ... 57 * ├── 0000:00:02.1 58 * │ └── ... 59 * : 60 * └── 0000:03:00.0 61 * ├── survivability_mode 62 * ├── gt_types_allowed 63 * ├── engines_allowed 64 * └── enable_psmi 65 * 66 * After configuring the attributes as per next section, the device can be 67 * probed with:: 68 * 69 * # echo 0000:03:00.0 > /sys/bus/pci/drivers/xe/bind 70 * # # or 71 * # echo 0000:03:00.0 > /sys/bus/pci/drivers_probe 72 * 73 * Configure Attributes 74 * ==================== 75 * 76 * Survivability mode: 77 * ------------------- 78 * 79 * Enable survivability mode on supported cards. This setting only takes 80 * effect when probing the device. Example to enable it:: 81 * 82 * # echo 1 > /sys/kernel/config/xe/0000:03:00.0/survivability_mode 83 * 84 * This attribute can only be set before binding to the device. 85 * 86 * Allowed GT types: 87 * ----------------- 88 * 89 * Allow only specific types of GTs to be detected and initialized by the 90 * driver. Any combination of GT types can be enabled/disabled, although 91 * some settings will cause the device to fail to probe. 92 * 93 * Writes support both comma- and newline-separated input format. Reads 94 * will always return one GT type per line. "primary" and "media" are the 95 * GT type names supported by this interface. 96 * 97 * This attribute can only be set before binding to the device. 98 * 99 * Examples: 100 * 101 * Allow both primary and media GTs to be initialized and used. This matches 102 * the driver's default behavior:: 103 * 104 * # echo 'primary,media' > /sys/kernel/config/xe/0000:03:00.0/gt_types_allowed 105 * 106 * Allow only the primary GT of each tile to be initialized and used, 107 * effectively disabling the media GT if it exists on the platform:: 108 * 109 * # echo 'primary' > /sys/kernel/config/xe/0000:03:00.0/gt_types_allowed 110 * 111 * Allow only the media GT of each tile to be initialized and used, 112 * effectively disabling the primary GT. **This configuration will cause 113 * device probe failure on all current platforms, but may be allowed on 114 * igpu platforms in the future**:: 115 * 116 * # echo 'media' > /sys/kernel/config/xe/0000:03:00.0/gt_types_allowed 117 * 118 * Disable all GTs. Only other GPU IP (such as display) is potentially usable. 119 * **This configuration will cause device probe failure on all current 120 * platforms, but may be allowed on igpu platforms in the future**:: 121 * 122 * # echo '' > /sys/kernel/config/xe/0000:03:00.0/gt_types_allowed 123 * 124 * Allowed engines: 125 * ---------------- 126 * 127 * Allow only a set of engine(s) to be available, disabling the other engines 128 * even if they are available in hardware. This is applied after HW fuses are 129 * considered on each tile. Examples: 130 * 131 * Allow only one render and one copy engines, nothing else:: 132 * 133 * # echo 'rcs0,bcs0' > /sys/kernel/config/xe/0000:03:00.0/engines_allowed 134 * 135 * Allow only compute engines and first copy engine:: 136 * 137 * # echo 'ccs*,bcs0' > /sys/kernel/config/xe/0000:03:00.0/engines_allowed 138 * 139 * Note that the engine names are the per-GT hardware names. On multi-tile 140 * platforms, writing ``rcs0,bcs0`` to this file would allow the first render 141 * and copy engines on each tile. 142 * 143 * The requested configuration may not be supported by the platform and driver 144 * may fail to probe. For example: if at least one copy engine is expected to be 145 * available for migrations, but it's disabled. This is intended for debugging 146 * purposes only. 147 * 148 * This attribute can only be set before binding to the device. 149 * 150 * PSMI 151 * ---- 152 * 153 * Enable extra debugging capabilities to trace engine execution. Only useful 154 * during early platform enabling and requires additional hardware connected. 155 * Once it's enabled, additionals WAs are added and runtime configuration is 156 * done via debugfs. Example to enable it:: 157 * 158 * # echo 1 > /sys/kernel/config/xe/0000:03:00.0/enable_psmi 159 * 160 * This attribute can only be set before binding to the device. 161 * 162 * Context restore BB 163 * ------------------ 164 * 165 * Allow to execute a batch buffer during any context switches. When the 166 * GPU is restoring the context, it executes additional commands. It's useful 167 * for testing additional workarounds and validating certain HW behaviors: it's 168 * not intended for normal execution and will taint the kernel with TAINT_TEST 169 * when used. 170 * 171 * The syntax allows to pass straight instructions to be executed by the engine 172 * in a batch buffer or set specific registers. 173 * 174 * #. Generic instruction:: 175 * 176 * <engine-class> cmd <instr> [[dword0] [dword1] [...]] 177 * 178 * #. Simple register setting:: 179 * 180 * <engine-class> reg <address> <value> 181 * 182 * Commands are saved per engine class: all instances of that class will execute 183 * those commands during context switch. The instruction, dword arguments, 184 * addresses and values are in hex format like in the examples below. 185 * 186 * #. Execute a LRI command to write 0xDEADBEEF to register 0x4f10 after the 187 * normal context restore:: 188 * 189 * # echo 'rcs cmd 11000001 4F100 DEADBEEF' \ 190 * > /sys/kernel/config/xe/0000:03:00.0/ctx_restore_post_bb 191 * 192 * #. Execute a LRI command to write 0xDEADBEEF to register 0x4f10 at the 193 * beginning of the context restore:: 194 * 195 * # echo 'rcs cmd 11000001 4F100 DEADBEEF' \ 196 * > /sys/kernel/config/xe/0000:03:00.0/ctx_restore_mid_bb 197 198 * #. Load certain values in a couple of registers (it can be used as a simpler 199 * alternative to the `cmd`) action:: 200 * 201 * # cat > /sys/kernel/config/xe/0000:03:00.0/ctx_restore_post_bb <<EOF 202 * rcs reg 4F100 DEADBEEF 203 * rcs reg 4F104 FFFFFFFF 204 * EOF 205 * 206 * .. note:: 207 * 208 * When using multiple lines, make sure to use a command that is 209 * implemented with a single write syscall, like HEREDOC. 210 * 211 * Currently this is implemented only for post and mid context restore and 212 * these attributes can only be set before binding to the device. 213 * 214 * Max SR-IOV Virtual Functions 215 * ---------------------------- 216 * 217 * This config allows to limit number of the Virtual Functions (VFs) that can 218 * be managed by the Physical Function (PF) driver, where value 0 disables the 219 * PF mode (no VFs). 220 * 221 * The default max_vfs config value is taken from the max_vfs modparam. 222 * 223 * How to enable PF with support with unlimited (up to HW limit) number of VFs:: 224 * 225 * # echo unlimited > /sys/kernel/config/xe/0000:00:02.0/sriov/max_vfs 226 * # echo 0000:00:02.0 > /sys/bus/pci/drivers/xe/bind 227 * 228 * How to enable PF with support up to 3 VFs:: 229 * 230 * # echo 3 > /sys/kernel/config/xe/0000:00:02.0/sriov/max_vfs 231 * # echo 0000:00:02.0 > /sys/bus/pci/drivers/xe/bind 232 * 233 * How to disable PF mode and always run as native:: 234 * 235 * # echo 0 > /sys/kernel/config/xe/0000:00:02.0/sriov/max_vfs 236 * # echo 0000:00:02.0 > /sys/bus/pci/drivers/xe/bind 237 * 238 * This setting only takes effect when probing the device. 239 * 240 * Enable multi-queue 241 * ------------------ 242 * 243 * Multi-queue support on the device is enabled by default where the 244 * hardware supports it. Writing 0 force-disables multi-queue support: 245 * multi-queue exec-queue group creation via ioctl is refused, and the 246 * GuC feature is disabled:: 247 * 248 * # echo 0 > /sys/kernel/config/xe/0000:03:00.0/enable_multi_queue 249 * 250 * This attribute can only be set before binding to the device. 251 * 252 * Remove devices 253 * ============== 254 * 255 * The created device directories can be removed using ``rmdir``:: 256 * 257 * # rmdir /sys/kernel/config/xe/0000:03:00.0/ 258 */ 259 260 /* Similar to struct xe_bb, but not tied to HW (yet) */ 261 struct wa_bb { 262 u32 *cs; 263 u32 len; /* in dwords */ 264 }; 265 266 struct xe_config_group_device { 267 struct config_group group; 268 struct config_group sriov; 269 270 struct xe_config_device { 271 u64 gt_types_allowed; 272 u64 engines_allowed; 273 struct wa_bb ctx_restore_post_bb[XE_ENGINE_CLASS_MAX]; 274 struct wa_bb ctx_restore_mid_bb[XE_ENGINE_CLASS_MAX]; 275 bool survivability_mode; 276 bool enable_psmi; 277 bool enable_multi_queue; 278 struct { 279 unsigned int max_vfs; 280 bool admin_only_pf; 281 } sriov; 282 } config; 283 284 /* protects attributes */ 285 struct mutex lock; 286 /* matching descriptor */ 287 const struct xe_device_desc *desc; 288 /* tentative SR-IOV mode */ 289 enum xe_sriov_mode mode; 290 }; 291 292 static const struct xe_config_device device_defaults = { 293 .gt_types_allowed = U64_MAX, 294 .engines_allowed = U64_MAX, 295 .survivability_mode = false, 296 .enable_psmi = false, 297 .enable_multi_queue = true, 298 .sriov = { 299 .max_vfs = XE_DEFAULT_MAX_VFS, 300 .admin_only_pf = XE_DEFAULT_ADMIN_ONLY_PF, 301 }, 302 }; 303 304 static void set_device_defaults(struct xe_config_device *config) 305 { 306 *config = device_defaults; 307 #ifdef CONFIG_PCI_IOV 308 config->sriov.max_vfs = xe_modparam.max_vfs; 309 #endif 310 } 311 312 struct engine_info { 313 const char *cls; 314 u64 mask; 315 enum xe_engine_class engine_class; 316 }; 317 318 /* Some helpful macros to aid on the sizing of buffer allocation when parsing */ 319 #define MAX_ENGINE_CLASS_CHARS 5 320 #define MAX_ENGINE_INSTANCE_CHARS 2 321 322 static const struct engine_info engine_info[] = { 323 { .cls = "rcs", .mask = XE_HW_ENGINE_RCS_MASK, .engine_class = XE_ENGINE_CLASS_RENDER }, 324 { .cls = "bcs", .mask = XE_HW_ENGINE_BCS_MASK, .engine_class = XE_ENGINE_CLASS_COPY }, 325 { .cls = "vcs", .mask = XE_HW_ENGINE_VCS_MASK, .engine_class = XE_ENGINE_CLASS_VIDEO_DECODE }, 326 { .cls = "vecs", .mask = XE_HW_ENGINE_VECS_MASK, .engine_class = XE_ENGINE_CLASS_VIDEO_ENHANCE }, 327 { .cls = "ccs", .mask = XE_HW_ENGINE_CCS_MASK, .engine_class = XE_ENGINE_CLASS_COMPUTE }, 328 { .cls = "gsccs", .mask = XE_HW_ENGINE_GSCCS_MASK, .engine_class = XE_ENGINE_CLASS_OTHER }, 329 }; 330 331 static const struct { 332 const char *name; 333 enum xe_gt_type type; 334 } gt_types[] = { 335 { .name = "primary", .type = XE_GT_TYPE_MAIN }, 336 { .name = "media", .type = XE_GT_TYPE_MEDIA }, 337 }; 338 339 static struct xe_config_group_device *to_xe_config_group_device(struct config_item *item) 340 { 341 return container_of(to_config_group(item), struct xe_config_group_device, group); 342 } 343 344 static struct xe_config_device *to_xe_config_device(struct config_item *item) 345 { 346 return &to_xe_config_group_device(item)->config; 347 } 348 349 static bool is_bound(struct xe_config_group_device *dev) 350 { 351 unsigned int domain, bus, slot, function; 352 struct pci_dev *pdev; 353 const char *name; 354 bool ret; 355 356 lockdep_assert_held(&dev->lock); 357 358 name = dev->group.cg_item.ci_name; 359 if (sscanf(name, "%x:%x:%x.%x", &domain, &bus, &slot, &function) != 4) 360 return false; 361 362 pdev = pci_get_domain_bus_and_slot(domain, bus, PCI_DEVFN(slot, function)); 363 if (!pdev) 364 return false; 365 366 ret = pci_get_drvdata(pdev); 367 if (ret) 368 pci_dbg(pdev, "Already bound to driver\n"); 369 370 pci_dev_put(pdev); 371 return ret; 372 } 373 374 static ssize_t survivability_mode_show(struct config_item *item, char *page) 375 { 376 struct xe_config_device *dev = to_xe_config_device(item); 377 378 return sprintf(page, "%d\n", dev->survivability_mode); 379 } 380 381 static ssize_t survivability_mode_store(struct config_item *item, const char *page, size_t len) 382 { 383 struct xe_config_group_device *dev = to_xe_config_group_device(item); 384 bool survivability_mode; 385 int ret; 386 387 ret = kstrtobool(page, &survivability_mode); 388 if (ret) 389 return ret; 390 391 guard(mutex)(&dev->lock); 392 if (is_bound(dev)) 393 return -EBUSY; 394 395 dev->config.survivability_mode = survivability_mode; 396 397 return len; 398 } 399 400 static ssize_t gt_types_allowed_show(struct config_item *item, char *page) 401 { 402 struct xe_config_device *dev = to_xe_config_device(item); 403 char *p = page; 404 405 for (size_t i = 0; i < ARRAY_SIZE(gt_types); i++) 406 if (dev->gt_types_allowed & BIT_ULL(gt_types[i].type)) 407 p += sprintf(p, "%s\n", gt_types[i].name); 408 409 return p - page; 410 } 411 412 static ssize_t gt_types_allowed_store(struct config_item *item, const char *page, 413 size_t len) 414 { 415 struct xe_config_group_device *dev = to_xe_config_group_device(item); 416 char *buf __free(kfree) = kstrdup(page, GFP_KERNEL); 417 char *p = buf; 418 u64 typemask = 0; 419 420 if (!buf) 421 return -ENOMEM; 422 423 while (p) { 424 char *typename = strsep(&p, ",\n"); 425 bool matched = false; 426 427 if (typename[0] == '\0') 428 continue; 429 430 for (size_t i = 0; i < ARRAY_SIZE(gt_types); i++) { 431 if (strcmp(typename, gt_types[i].name) == 0) { 432 typemask |= BIT(gt_types[i].type); 433 matched = true; 434 break; 435 } 436 } 437 438 if (!matched) 439 return -EINVAL; 440 } 441 442 guard(mutex)(&dev->lock); 443 if (is_bound(dev)) 444 return -EBUSY; 445 446 dev->config.gt_types_allowed = typemask; 447 448 return len; 449 } 450 451 static ssize_t engines_allowed_show(struct config_item *item, char *page) 452 { 453 struct xe_config_device *dev = to_xe_config_device(item); 454 char *p = page; 455 456 for (size_t i = 0; i < ARRAY_SIZE(engine_info); i++) { 457 u64 mask = engine_info[i].mask; 458 459 if ((dev->engines_allowed & mask) == mask) { 460 p += sprintf(p, "%s*\n", engine_info[i].cls); 461 } else if (mask & dev->engines_allowed) { 462 u16 bit0 = __ffs64(mask), bit; 463 464 mask &= dev->engines_allowed; 465 466 for_each_set_bit(bit, (const unsigned long *)&mask, 64) 467 p += sprintf(p, "%s%u\n", engine_info[i].cls, 468 bit - bit0); 469 } 470 } 471 472 return p - page; 473 } 474 475 /* 476 * Lookup engine_info. If @mask is not NULL, reduce the mask according to the 477 * instance in @pattern. 478 * 479 * Examples of inputs: 480 * - lookup_engine_info("rcs0", &mask): return "rcs" entry from @engine_info and 481 * mask == BIT_ULL(XE_HW_ENGINE_RCS0) 482 * - lookup_engine_info("rcs*", &mask): return "rcs" entry from @engine_info and 483 * mask == XE_HW_ENGINE_RCS_MASK 484 * - lookup_engine_info("rcs", NULL): return "rcs" entry from @engine_info 485 */ 486 static const struct engine_info *lookup_engine_info(const char *pattern, u64 *mask) 487 { 488 for (size_t i = 0; i < ARRAY_SIZE(engine_info); i++) { 489 u8 instance; 490 u16 bit; 491 492 if (!str_has_prefix(pattern, engine_info[i].cls)) 493 continue; 494 495 pattern += strlen(engine_info[i].cls); 496 if (!mask) 497 return *pattern ? NULL : &engine_info[i]; 498 499 if (!strcmp(pattern, "*")) { 500 *mask = engine_info[i].mask; 501 return &engine_info[i]; 502 } 503 504 if (kstrtou8(pattern, 10, &instance)) 505 return NULL; 506 507 bit = __ffs64(engine_info[i].mask) + instance; 508 if (bit >= fls64(engine_info[i].mask)) 509 return NULL; 510 511 *mask = BIT_ULL(bit); 512 return &engine_info[i]; 513 } 514 515 return NULL; 516 } 517 518 static int parse_engine(const char *s, const char *end_chars, u64 *mask, 519 const struct engine_info **pinfo) 520 { 521 char buf[MAX_ENGINE_CLASS_CHARS + MAX_ENGINE_INSTANCE_CHARS + 1]; 522 const struct engine_info *info; 523 size_t len; 524 525 len = strcspn(s, end_chars); 526 if (len >= sizeof(buf)) 527 return -EINVAL; 528 529 memcpy(buf, s, len); 530 buf[len] = '\0'; 531 532 info = lookup_engine_info(buf, mask); 533 if (!info) 534 return -ENOENT; 535 536 if (pinfo) 537 *pinfo = info; 538 539 return len; 540 } 541 542 static ssize_t engines_allowed_store(struct config_item *item, const char *page, 543 size_t len) 544 { 545 struct xe_config_group_device *dev = to_xe_config_group_device(item); 546 ssize_t patternlen, p; 547 u64 mask, val = 0; 548 549 for (p = 0; p < len; p += patternlen + 1) { 550 patternlen = parse_engine(page + p, ",\n", &mask, NULL); 551 if (patternlen < 0) 552 return -EINVAL; 553 554 val |= mask; 555 } 556 557 guard(mutex)(&dev->lock); 558 if (is_bound(dev)) 559 return -EBUSY; 560 561 dev->config.engines_allowed = val; 562 563 return len; 564 } 565 566 static ssize_t enable_psmi_show(struct config_item *item, char *page) 567 { 568 struct xe_config_device *dev = to_xe_config_device(item); 569 570 return sprintf(page, "%d\n", dev->enable_psmi); 571 } 572 573 static ssize_t enable_psmi_store(struct config_item *item, const char *page, size_t len) 574 { 575 struct xe_config_group_device *dev = to_xe_config_group_device(item); 576 bool val; 577 int ret; 578 579 ret = kstrtobool(page, &val); 580 if (ret) 581 return ret; 582 583 guard(mutex)(&dev->lock); 584 if (is_bound(dev)) 585 return -EBUSY; 586 587 dev->config.enable_psmi = val; 588 589 return len; 590 } 591 592 static ssize_t enable_multi_queue_show(struct config_item *item, char *page) 593 { 594 struct xe_config_device *dev = to_xe_config_device(item); 595 596 return sprintf(page, "%d\n", dev->enable_multi_queue); 597 } 598 599 static ssize_t enable_multi_queue_store(struct config_item *item, const char *page, 600 size_t len) 601 { 602 struct xe_config_group_device *dev = to_xe_config_group_device(item); 603 bool val; 604 int ret; 605 606 ret = kstrtobool(page, &val); 607 if (ret) 608 return ret; 609 610 guard(mutex)(&dev->lock); 611 if (is_bound(dev)) 612 return -EBUSY; 613 614 dev->config.enable_multi_queue = val; 615 616 return len; 617 } 618 619 static bool wa_bb_read_advance(bool dereference, char **p, 620 const char *append, size_t len, 621 size_t *max_size) 622 { 623 if (dereference) { 624 if (len >= *max_size) 625 return false; 626 *max_size -= len; 627 if (append) 628 memcpy(*p, append, len); 629 } 630 631 *p += len; 632 633 return true; 634 } 635 636 static ssize_t wa_bb_show(struct xe_config_group_device *dev, 637 struct wa_bb wa_bb[static XE_ENGINE_CLASS_MAX], 638 char *data, size_t sz) 639 { 640 char *p = data; 641 642 guard(mutex)(&dev->lock); 643 644 for (size_t i = 0; i < ARRAY_SIZE(engine_info); i++) { 645 enum xe_engine_class ec = engine_info[i].engine_class; 646 size_t len; 647 648 if (!wa_bb[ec].len) 649 continue; 650 651 len = snprintf(p, sz, "%s:", engine_info[i].cls); 652 if (!wa_bb_read_advance(data, &p, NULL, len, &sz)) 653 return -ENOBUFS; 654 655 for (size_t j = 0; j < wa_bb[ec].len; j++) { 656 len = snprintf(p, sz, " %08x", wa_bb[ec].cs[j]); 657 if (!wa_bb_read_advance(data, &p, NULL, len, &sz)) 658 return -ENOBUFS; 659 } 660 661 if (!wa_bb_read_advance(data, &p, "\n", 1, &sz)) 662 return -ENOBUFS; 663 } 664 665 if (!wa_bb_read_advance(data, &p, "", 1, &sz)) 666 return -ENOBUFS; 667 668 /* Reserve one more to match check for '\0' */ 669 if (!data) 670 p++; 671 672 return p - data; 673 } 674 675 static ssize_t ctx_restore_mid_bb_show(struct config_item *item, char *page) 676 { 677 struct xe_config_group_device *dev = to_xe_config_group_device(item); 678 679 return wa_bb_show(dev, dev->config.ctx_restore_mid_bb, page, SZ_4K); 680 } 681 682 static ssize_t ctx_restore_post_bb_show(struct config_item *item, char *page) 683 { 684 struct xe_config_group_device *dev = to_xe_config_group_device(item); 685 686 return wa_bb_show(dev, dev->config.ctx_restore_post_bb, page, SZ_4K); 687 } 688 689 static void wa_bb_append(struct wa_bb *wa_bb, u32 val) 690 { 691 if (wa_bb->cs) 692 wa_bb->cs[wa_bb->len] = val; 693 694 wa_bb->len++; 695 } 696 697 static ssize_t parse_hex(const char *line, u32 *pval) 698 { 699 char numstr[12]; 700 const char *p; 701 ssize_t numlen; 702 703 p = line + strspn(line, " \t"); 704 if (!*p || *p == '\n') 705 return 0; 706 707 numlen = strcspn(p, " \t\n"); 708 if (!numlen || numlen >= sizeof(numstr) - 1) 709 return -EINVAL; 710 711 memcpy(numstr, p, numlen); 712 numstr[numlen] = '\0'; 713 p += numlen; 714 715 if (kstrtou32(numstr, 16, pval)) 716 return -EINVAL; 717 718 return p - line; 719 } 720 721 /* 722 * Parse lines with the format 723 * 724 * <engine-class> cmd <u32> <u32...> 725 * <engine-class> reg <u32_addr> <u32_val> 726 * 727 * and optionally save them in @wa_bb[i].cs is non-NULL. 728 * 729 * Return the number of dwords parsed. 730 */ 731 static ssize_t parse_wa_bb_lines(const char *lines, 732 struct wa_bb wa_bb[static XE_ENGINE_CLASS_MAX]) 733 { 734 ssize_t dwords = 0, ret; 735 const char *p; 736 737 for (p = lines; *p; p++) { 738 const struct engine_info *info = NULL; 739 u32 val, val2; 740 741 /* Also allow empty lines */ 742 p += strspn(p, " \t\n"); 743 if (!*p) 744 break; 745 746 ret = parse_engine(p, " \t\n", NULL, &info); 747 if (ret < 0) 748 return ret; 749 750 p += ret; 751 p += strspn(p, " \t"); 752 753 if (str_has_prefix(p, "cmd")) { 754 for (p += strlen("cmd"); *p;) { 755 ret = parse_hex(p, &val); 756 if (ret < 0) 757 return -EINVAL; 758 if (!ret) 759 break; 760 761 p += ret; 762 dwords++; 763 wa_bb_append(&wa_bb[info->engine_class], val); 764 } 765 } else if (str_has_prefix(p, "reg")) { 766 p += strlen("reg"); 767 ret = parse_hex(p, &val); 768 if (ret <= 0) 769 return -EINVAL; 770 771 p += ret; 772 ret = parse_hex(p, &val2); 773 if (ret <= 0) 774 return -EINVAL; 775 776 p += ret; 777 dwords += 3; 778 wa_bb_append(&wa_bb[info->engine_class], 779 MI_LOAD_REGISTER_IMM | MI_LRI_NUM_REGS(1)); 780 wa_bb_append(&wa_bb[info->engine_class], val); 781 wa_bb_append(&wa_bb[info->engine_class], val2); 782 } else { 783 return -EINVAL; 784 } 785 } 786 787 return dwords; 788 } 789 790 static ssize_t wa_bb_store(struct wa_bb wa_bb[static XE_ENGINE_CLASS_MAX], 791 struct xe_config_group_device *dev, 792 const char *page, size_t len) 793 { 794 /* tmp_wa_bb must match wa_bb's size */ 795 struct wa_bb tmp_wa_bb[XE_ENGINE_CLASS_MAX] = { }; 796 ssize_t count, class; 797 u32 *tmp; 798 799 /* 1. Count dwords - wa_bb[i].cs is NULL for all classes */ 800 count = parse_wa_bb_lines(page, tmp_wa_bb); 801 if (count < 0) 802 return count; 803 804 guard(mutex)(&dev->lock); 805 806 if (is_bound(dev)) 807 return -EBUSY; 808 809 /* 810 * 2. Allocate a u32 array and set the pointers to the right positions 811 * according to the length of each class' wa_bb 812 */ 813 tmp = krealloc(wa_bb[0].cs, count * sizeof(u32), GFP_KERNEL); 814 if (!tmp) 815 return -ENOMEM; 816 817 if (!count) { 818 memset(wa_bb, 0, sizeof(tmp_wa_bb)); 819 return len; 820 } 821 822 for (class = 0, count = 0; class < XE_ENGINE_CLASS_MAX; ++class) { 823 tmp_wa_bb[class].cs = tmp + count; 824 count += tmp_wa_bb[class].len; 825 tmp_wa_bb[class].len = 0; 826 } 827 828 /* 3. Parse wa_bb lines again, this time saving the values */ 829 count = parse_wa_bb_lines(page, tmp_wa_bb); 830 if (count < 0) 831 return count; 832 833 memcpy(wa_bb, tmp_wa_bb, sizeof(tmp_wa_bb)); 834 835 return len; 836 } 837 838 static ssize_t ctx_restore_mid_bb_store(struct config_item *item, 839 const char *data, size_t sz) 840 { 841 struct xe_config_group_device *dev = to_xe_config_group_device(item); 842 843 return wa_bb_store(dev->config.ctx_restore_mid_bb, dev, data, sz); 844 } 845 846 static ssize_t ctx_restore_post_bb_store(struct config_item *item, 847 const char *data, size_t sz) 848 { 849 struct xe_config_group_device *dev = to_xe_config_group_device(item); 850 851 return wa_bb_store(dev->config.ctx_restore_post_bb, dev, data, sz); 852 } 853 854 CONFIGFS_ATTR(, ctx_restore_mid_bb); 855 CONFIGFS_ATTR(, ctx_restore_post_bb); 856 CONFIGFS_ATTR(, enable_multi_queue); 857 CONFIGFS_ATTR(, enable_psmi); 858 CONFIGFS_ATTR(, engines_allowed); 859 CONFIGFS_ATTR(, gt_types_allowed); 860 CONFIGFS_ATTR(, survivability_mode); 861 862 static struct configfs_attribute *xe_config_device_attrs[] = { 863 &attr_ctx_restore_mid_bb, 864 &attr_ctx_restore_post_bb, 865 &attr_enable_multi_queue, 866 &attr_enable_psmi, 867 &attr_engines_allowed, 868 &attr_gt_types_allowed, 869 &attr_survivability_mode, 870 NULL, 871 }; 872 873 static void xe_config_device_release(struct config_item *item) 874 { 875 struct xe_config_group_device *dev = to_xe_config_group_device(item); 876 877 mutex_destroy(&dev->lock); 878 879 kfree(dev->config.ctx_restore_mid_bb[0].cs); 880 kfree(dev->config.ctx_restore_post_bb[0].cs); 881 kfree(dev); 882 } 883 884 static struct configfs_item_operations xe_config_device_ops = { 885 .release = xe_config_device_release, 886 }; 887 888 static bool xe_config_device_is_visible(struct config_item *item, 889 struct configfs_attribute *attr, int n) 890 { 891 struct xe_config_group_device *dev = to_xe_config_group_device(item); 892 893 if (attr == &attr_survivability_mode) { 894 if (!dev->desc->is_dgfx || dev->desc->platform < XE_BATTLEMAGE) 895 return false; 896 } 897 898 return true; 899 } 900 901 static struct configfs_group_operations xe_config_device_group_ops = { 902 .is_visible = xe_config_device_is_visible, 903 }; 904 905 static const struct config_item_type xe_config_device_type = { 906 .ct_item_ops = &xe_config_device_ops, 907 .ct_group_ops = &xe_config_device_group_ops, 908 .ct_attrs = xe_config_device_attrs, 909 .ct_owner = THIS_MODULE, 910 }; 911 912 static ssize_t sriov_max_vfs_show(struct config_item *item, char *page) 913 { 914 struct xe_config_group_device *dev = to_xe_config_group_device(item->ci_parent); 915 916 guard(mutex)(&dev->lock); 917 918 if (dev->config.sriov.max_vfs == UINT_MAX) 919 return sprintf(page, "%s\n", "unlimited"); 920 else 921 return sprintf(page, "%u\n", dev->config.sriov.max_vfs); 922 } 923 924 static ssize_t sriov_max_vfs_store(struct config_item *item, const char *page, size_t len) 925 { 926 struct xe_config_group_device *dev = to_xe_config_group_device(item->ci_parent); 927 unsigned int max_vfs; 928 int ret; 929 930 guard(mutex)(&dev->lock); 931 932 if (is_bound(dev)) 933 return -EBUSY; 934 935 ret = kstrtouint(page, 0, &max_vfs); 936 if (ret) { 937 if (!sysfs_streq(page, "unlimited")) 938 return ret; 939 max_vfs = UINT_MAX; 940 } 941 942 dev->config.sriov.max_vfs = max_vfs; 943 return len; 944 } 945 946 static ssize_t sriov_admin_only_pf_show(struct config_item *item, char *page) 947 { 948 struct xe_config_group_device *dev = to_xe_config_group_device(item->ci_parent); 949 950 guard(mutex)(&dev->lock); 951 952 return sprintf(page, "%s\n", str_yes_no(dev->config.sriov.admin_only_pf)); 953 } 954 955 static ssize_t sriov_admin_only_pf_store(struct config_item *item, const char *page, size_t len) 956 { 957 struct xe_config_group_device *dev = to_xe_config_group_device(item->ci_parent); 958 bool admin_only_pf; 959 int ret; 960 961 guard(mutex)(&dev->lock); 962 963 if (is_bound(dev)) 964 return -EBUSY; 965 966 ret = kstrtobool(page, &admin_only_pf); 967 if (ret) 968 return ret; 969 970 dev->config.sriov.admin_only_pf = admin_only_pf; 971 return len; 972 } 973 974 CONFIGFS_ATTR(sriov_, max_vfs); 975 CONFIGFS_ATTR(sriov_, admin_only_pf); 976 977 static struct configfs_attribute *xe_config_sriov_attrs[] = { 978 &sriov_attr_max_vfs, 979 &sriov_attr_admin_only_pf, 980 NULL, 981 }; 982 983 static bool xe_config_sriov_is_visible(struct config_item *item, 984 struct configfs_attribute *attr, int n) 985 { 986 struct xe_config_group_device *dev = to_xe_config_group_device(item->ci_parent); 987 988 if (attr == &sriov_attr_max_vfs && dev->mode != XE_SRIOV_MODE_PF) 989 return false; 990 if (attr == &sriov_attr_admin_only_pf && dev->mode != XE_SRIOV_MODE_PF) 991 return false; 992 993 return true; 994 } 995 996 static struct configfs_group_operations xe_config_sriov_group_ops = { 997 .is_visible = xe_config_sriov_is_visible, 998 }; 999 1000 static const struct config_item_type xe_config_sriov_type = { 1001 .ct_owner = THIS_MODULE, 1002 .ct_group_ops = &xe_config_sriov_group_ops, 1003 .ct_attrs = xe_config_sriov_attrs, 1004 }; 1005 1006 static const struct xe_device_desc *xe_match_desc(struct pci_dev *pdev) 1007 { 1008 struct device_driver *driver = driver_find("xe", &pci_bus_type); 1009 struct pci_driver *drv = to_pci_driver(driver); 1010 const struct pci_device_id *ids = drv ? drv->id_table : NULL; 1011 const struct pci_device_id *found = pci_match_id(ids, pdev); 1012 1013 return found ? (const void *)found->driver_data : NULL; 1014 } 1015 1016 static struct pci_dev *get_physfn_instead(struct pci_dev *virtfn) 1017 { 1018 struct pci_dev *physfn = pci_physfn(virtfn); 1019 1020 pci_dev_get(physfn); 1021 pci_dev_put(virtfn); 1022 return physfn; 1023 } 1024 1025 static struct config_group *xe_config_make_device_group(struct config_group *group, 1026 const char *name) 1027 { 1028 unsigned int domain, bus, slot, function; 1029 struct xe_config_group_device *dev; 1030 const struct xe_device_desc *match; 1031 enum xe_sriov_mode mode; 1032 struct pci_dev *pdev; 1033 char canonical[16]; 1034 int vfnumber = 0; 1035 int ret; 1036 1037 ret = sscanf(name, "%x:%x:%x.%x", &domain, &bus, &slot, &function); 1038 if (ret != 4) 1039 return ERR_PTR(-EINVAL); 1040 1041 ret = scnprintf(canonical, sizeof(canonical), "%04x:%02x:%02x.%d", domain, bus, 1042 PCI_SLOT(PCI_DEVFN(slot, function)), 1043 PCI_FUNC(PCI_DEVFN(slot, function))); 1044 if (ret != 12 || strcmp(name, canonical)) 1045 return ERR_PTR(-EINVAL); 1046 1047 pdev = pci_get_domain_bus_and_slot(domain, bus, PCI_DEVFN(slot, function)); 1048 mode = pdev ? dev_is_pf(&pdev->dev) ? 1049 XE_SRIOV_MODE_PF : XE_SRIOV_MODE_NONE : XE_SRIOV_MODE_VF; 1050 1051 if (!pdev && function) 1052 pdev = pci_get_domain_bus_and_slot(domain, bus, PCI_DEVFN(slot, 0)); 1053 if (!pdev && slot) 1054 pdev = pci_get_domain_bus_and_slot(domain, bus, PCI_DEVFN(0, 0)); 1055 if (!pdev) 1056 return ERR_PTR(-ENODEV); 1057 1058 if (PCI_DEVFN(slot, function) != pdev->devfn) { 1059 pdev = get_physfn_instead(pdev); 1060 vfnumber = PCI_DEVFN(slot, function) - pdev->devfn; 1061 if (!dev_is_pf(&pdev->dev) || vfnumber > pci_sriov_get_totalvfs(pdev)) { 1062 pci_dev_put(pdev); 1063 return ERR_PTR(-ENODEV); 1064 } 1065 } 1066 1067 match = xe_match_desc(pdev); 1068 if (match && vfnumber && !match->has_sriov) { 1069 pci_info(pdev, "xe driver does not support VFs on this device\n"); 1070 match = NULL; 1071 } else if (!match) { 1072 pci_info(pdev, "xe driver does not support configuration of this device\n"); 1073 } 1074 1075 pci_dev_put(pdev); 1076 1077 if (!match) 1078 return ERR_PTR(-ENOENT); 1079 1080 dev = kzalloc_obj(*dev); 1081 if (!dev) 1082 return ERR_PTR(-ENOMEM); 1083 1084 dev->desc = match; 1085 dev->mode = match->has_sriov ? mode : XE_SRIOV_MODE_NONE; 1086 1087 set_device_defaults(&dev->config); 1088 1089 config_group_init_type_name(&dev->group, name, &xe_config_device_type); 1090 if (dev->mode != XE_SRIOV_MODE_NONE) { 1091 config_group_init_type_name(&dev->sriov, "sriov", &xe_config_sriov_type); 1092 configfs_add_default_group(&dev->sriov, &dev->group); 1093 } 1094 1095 mutex_init(&dev->lock); 1096 1097 return &dev->group; 1098 } 1099 1100 static struct configfs_group_operations xe_config_group_ops = { 1101 .make_group = xe_config_make_device_group, 1102 }; 1103 1104 static const struct config_item_type xe_configfs_type = { 1105 .ct_group_ops = &xe_config_group_ops, 1106 .ct_owner = THIS_MODULE, 1107 }; 1108 1109 static struct configfs_subsystem xe_configfs = { 1110 .su_group = { 1111 .cg_item = { 1112 .ci_namebuf = "xe", 1113 .ci_type = &xe_configfs_type, 1114 }, 1115 }, 1116 }; 1117 1118 static struct xe_config_group_device *find_xe_config_group_device(struct pci_dev *pdev) 1119 { 1120 struct config_item *item; 1121 1122 mutex_lock(&xe_configfs.su_mutex); 1123 item = config_group_find_item(&xe_configfs.su_group, pci_name(pdev)); 1124 mutex_unlock(&xe_configfs.su_mutex); 1125 1126 if (!item) 1127 return NULL; 1128 1129 return to_xe_config_group_device(item); 1130 } 1131 1132 static void dump_custom_dev_config(struct pci_dev *pdev, 1133 struct xe_config_group_device *dev) 1134 { 1135 #define PRI_CUSTOM_ATTR(fmt_, attr_) do { \ 1136 if (dev->config.attr_ != device_defaults.attr_) \ 1137 pci_info(pdev, "configfs: " __stringify(attr_) " = " fmt_ "\n", \ 1138 dev->config.attr_); \ 1139 } while (0) 1140 1141 PRI_CUSTOM_ATTR("%llx", gt_types_allowed); 1142 PRI_CUSTOM_ATTR("%llx", engines_allowed); 1143 PRI_CUSTOM_ATTR("%d", enable_multi_queue); 1144 PRI_CUSTOM_ATTR("%d", enable_psmi); 1145 PRI_CUSTOM_ATTR("%d", survivability_mode); 1146 PRI_CUSTOM_ATTR("%u", sriov.admin_only_pf); 1147 1148 #undef PRI_CUSTOM_ATTR 1149 } 1150 1151 /** 1152 * xe_configfs_check_device() - Test if device was configured by configfs 1153 * @pdev: the &pci_dev device to test 1154 * 1155 * Try to find the configfs group that belongs to the specified pci device 1156 * and print a diagnostic message if different than the default value. 1157 */ 1158 void xe_configfs_check_device(struct pci_dev *pdev) 1159 { 1160 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1161 1162 if (!dev) 1163 return; 1164 1165 /* memcmp here is safe as both are zero-initialized */ 1166 if (memcmp(&dev->config, &device_defaults, sizeof(dev->config))) { 1167 pci_info(pdev, "Found custom settings in configfs\n"); 1168 dump_custom_dev_config(pdev, dev); 1169 } 1170 1171 config_group_put(&dev->group); 1172 } 1173 1174 /** 1175 * xe_configfs_get_survivability_mode - get configfs survivability mode attribute 1176 * @pdev: pci device 1177 * 1178 * Return: survivability_mode attribute in configfs 1179 */ 1180 bool xe_configfs_get_survivability_mode(struct pci_dev *pdev) 1181 { 1182 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1183 bool mode; 1184 1185 if (!dev) 1186 return device_defaults.survivability_mode; 1187 1188 mode = dev->config.survivability_mode; 1189 config_group_put(&dev->group); 1190 1191 return mode; 1192 } 1193 1194 static u64 get_gt_types_allowed(struct pci_dev *pdev) 1195 { 1196 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1197 u64 mask; 1198 1199 if (!dev) 1200 return device_defaults.gt_types_allowed; 1201 1202 mask = dev->config.gt_types_allowed; 1203 config_group_put(&dev->group); 1204 1205 return mask; 1206 } 1207 1208 /** 1209 * xe_configfs_primary_gt_allowed - determine whether primary GTs are supported 1210 * @pdev: pci device 1211 * 1212 * Return: True if primary GTs are enabled, false if they have been disabled via 1213 * configfs. 1214 */ 1215 bool xe_configfs_primary_gt_allowed(struct pci_dev *pdev) 1216 { 1217 return get_gt_types_allowed(pdev) & BIT_ULL(XE_GT_TYPE_MAIN); 1218 } 1219 1220 /** 1221 * xe_configfs_media_gt_allowed - determine whether media GTs are supported 1222 * @pdev: pci device 1223 * 1224 * Return: True if the media GTs are enabled, false if they have been disabled 1225 * via configfs. 1226 */ 1227 bool xe_configfs_media_gt_allowed(struct pci_dev *pdev) 1228 { 1229 return get_gt_types_allowed(pdev) & BIT_ULL(XE_GT_TYPE_MEDIA); 1230 } 1231 1232 /** 1233 * xe_configfs_get_engines_allowed - get engine allowed mask from configfs 1234 * @pdev: pci device 1235 * 1236 * Return: engine mask with allowed engines set in configfs 1237 */ 1238 u64 xe_configfs_get_engines_allowed(struct pci_dev *pdev) 1239 { 1240 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1241 u64 engines_allowed; 1242 1243 if (!dev) 1244 return device_defaults.engines_allowed; 1245 1246 engines_allowed = dev->config.engines_allowed; 1247 config_group_put(&dev->group); 1248 1249 return engines_allowed; 1250 } 1251 1252 /** 1253 * xe_configfs_get_psmi_enabled - get configfs enable_psmi setting 1254 * @pdev: pci device 1255 * 1256 * Return: enable_psmi setting in configfs 1257 */ 1258 bool xe_configfs_get_psmi_enabled(struct pci_dev *pdev) 1259 { 1260 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1261 bool ret; 1262 1263 if (!dev) 1264 return false; 1265 1266 ret = dev->config.enable_psmi; 1267 config_group_put(&dev->group); 1268 1269 return ret; 1270 } 1271 1272 /** 1273 * xe_configfs_get_enable_multi_queue - get configfs enable_multi_queue setting 1274 * @pdev: pci device 1275 * 1276 * Return: true if multi-queue is enabled for this device (the default), 1277 * false if it has been force-disabled via configfs. 1278 */ 1279 bool xe_configfs_get_enable_multi_queue(struct pci_dev *pdev) 1280 { 1281 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1282 bool ret; 1283 1284 if (!dev) 1285 return true; 1286 1287 ret = dev->config.enable_multi_queue; 1288 config_group_put(&dev->group); 1289 1290 return ret; 1291 } 1292 1293 /** 1294 * xe_configfs_get_ctx_restore_mid_bb - get configfs ctx_restore_mid_bb setting 1295 * @pdev: pci device 1296 * @class: hw engine class 1297 * @cs: pointer to the bb to use - only valid during probe 1298 * 1299 * Return: Number of dwords used in the mid_ctx_restore setting in configfs 1300 */ 1301 u32 xe_configfs_get_ctx_restore_mid_bb(struct pci_dev *pdev, 1302 enum xe_engine_class class, 1303 const u32 **cs) 1304 { 1305 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1306 u32 len; 1307 1308 if (!dev) 1309 return 0; 1310 1311 if (cs) 1312 *cs = dev->config.ctx_restore_mid_bb[class].cs; 1313 1314 len = dev->config.ctx_restore_mid_bb[class].len; 1315 config_group_put(&dev->group); 1316 1317 return len; 1318 } 1319 1320 /** 1321 * xe_configfs_get_ctx_restore_post_bb - get configfs ctx_restore_post_bb setting 1322 * @pdev: pci device 1323 * @class: hw engine class 1324 * @cs: pointer to the bb to use - only valid during probe 1325 * 1326 * Return: Number of dwords used in the post_ctx_restore setting in configfs 1327 */ 1328 u32 xe_configfs_get_ctx_restore_post_bb(struct pci_dev *pdev, 1329 enum xe_engine_class class, 1330 const u32 **cs) 1331 { 1332 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1333 u32 len; 1334 1335 if (!dev) 1336 return 0; 1337 1338 *cs = dev->config.ctx_restore_post_bb[class].cs; 1339 len = dev->config.ctx_restore_post_bb[class].len; 1340 config_group_put(&dev->group); 1341 1342 return len; 1343 } 1344 1345 #ifdef CONFIG_PCI_IOV 1346 /** 1347 * xe_configfs_admin_only_pf() - Get PF's operational mode. 1348 * @pdev: the &pci_dev device 1349 * 1350 * Find the configfs group that belongs to the PCI device and return a flag 1351 * whether the PF driver should be dedicated for VFs management only. 1352 * 1353 * If configfs group is not present, use driver's default value. 1354 * 1355 * Return: true if PF driver is dedicated for VFs administration only. 1356 */ 1357 bool xe_configfs_admin_only_pf(struct pci_dev *pdev) 1358 { 1359 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1360 bool admin_only_pf; 1361 1362 if (!dev) 1363 return XE_DEFAULT_ADMIN_ONLY_PF; 1364 1365 scoped_guard(mutex, &dev->lock) 1366 admin_only_pf = dev->config.sriov.admin_only_pf; 1367 1368 config_group_put(&dev->group); 1369 1370 return admin_only_pf; 1371 } 1372 /** 1373 * xe_configfs_get_max_vfs() - Get number of VFs that could be managed 1374 * @pdev: the &pci_dev device 1375 * 1376 * Find the configfs group that belongs to the PCI device and return maximum 1377 * number of Virtual Functions (VFs) that could be managed by this device. 1378 * If configfs group is not present, use value of max_vfs module parameter. 1379 * 1380 * Return: maximum number of VFs that could be managed. 1381 */ 1382 unsigned int xe_configfs_get_max_vfs(struct pci_dev *pdev) 1383 { 1384 struct xe_config_group_device *dev = find_xe_config_group_device(pdev); 1385 unsigned int max_vfs; 1386 1387 if (!dev) 1388 return xe_modparam.max_vfs; 1389 1390 scoped_guard(mutex, &dev->lock) 1391 max_vfs = dev->config.sriov.max_vfs; 1392 1393 config_group_put(&dev->group); 1394 1395 return max_vfs; 1396 } 1397 #endif 1398 1399 int __init xe_configfs_init(void) 1400 { 1401 int ret; 1402 1403 config_group_init(&xe_configfs.su_group); 1404 mutex_init(&xe_configfs.su_mutex); 1405 ret = configfs_register_subsystem(&xe_configfs); 1406 if (ret) { 1407 mutex_destroy(&xe_configfs.su_mutex); 1408 return ret; 1409 } 1410 1411 return 0; 1412 } 1413 1414 void xe_configfs_exit(void) 1415 { 1416 configfs_unregister_subsystem(&xe_configfs); 1417 mutex_destroy(&xe_configfs.su_mutex); 1418 } 1419