1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Interface with platform TEE Security Manager (TSM) objects as defined by 4 * PCIe r7.0 section 11 TEE Device Interface Security Protocol (TDISP) 5 * 6 * Copyright(c) 2024-2025 Intel Corporation. All rights reserved. 7 */ 8 9 #define dev_fmt(fmt) "PCI/TSM: " fmt 10 11 #include <linux/bitfield.h> 12 #include <linux/pci.h> 13 #include <linux/pci-doe.h> 14 #include <linux/pci-tsm.h> 15 #include <linux/sysfs.h> 16 #include <linux/tsm.h> 17 #include <linux/xarray.h> 18 #include "pci.h" 19 20 /* 21 * Provide a read/write lock against the init / exit of pdev tsm 22 * capabilities and arrival/departure of a TSM instance 23 */ 24 static DECLARE_RWSEM(pci_tsm_rwsem); 25 26 /* 27 * Count of TSMs registered that support physical link operations vs device 28 * security state management. 29 */ 30 static int pci_tsm_link_count; 31 static int pci_tsm_devsec_count; 32 33 static const struct pci_tsm_ops *to_pci_tsm_ops(struct pci_tsm *tsm) 34 { 35 return tsm->tsm_dev->pci_ops; 36 } 37 38 static inline bool is_dsm(struct pci_dev *pdev) 39 { 40 return pdev->tsm && pdev->tsm->dsm_dev == pdev; 41 } 42 43 static inline bool has_tee(struct pci_dev *pdev) 44 { 45 return pdev->devcap & PCI_EXP_DEVCAP_TEE; 46 } 47 48 /* 'struct pci_tsm_pf0' wraps 'struct pci_tsm' when ->dsm_dev == ->pdev (self) */ 49 static struct pci_tsm_pf0 *to_pci_tsm_pf0(struct pci_tsm *tsm) 50 { 51 /* 52 * All "link" TSM contexts reference the device that hosts the DSM 53 * interface for a set of devices. Walk to the DSM device and cast its 54 * ->tsm context to a 'struct pci_tsm_pf0 *'. 55 */ 56 struct pci_dev *pf0 = tsm->dsm_dev; 57 58 if (!is_pci_tsm_pf0(pf0) || !is_dsm(pf0)) { 59 pci_WARN_ONCE(tsm->pdev, 1, "invalid context object\n"); 60 return NULL; 61 } 62 63 return container_of(pf0->tsm, struct pci_tsm_pf0, base_tsm); 64 } 65 66 static void tsm_remove(struct pci_tsm *tsm) 67 { 68 struct pci_dev *pdev; 69 70 if (!tsm) 71 return; 72 73 pdev = tsm->pdev; 74 to_pci_tsm_ops(tsm)->remove(tsm); 75 pdev->tsm = NULL; 76 } 77 DEFINE_FREE(tsm_remove, struct pci_tsm *, if (_T) tsm_remove(_T)) 78 79 static void pci_tsm_walk_fns(struct pci_dev *pdev, 80 int (*cb)(struct pci_dev *pdev, void *data), 81 void *data) 82 { 83 /* Walk subordinate physical functions */ 84 for (int i = 0; i < 8; i++) { 85 struct pci_dev *pf __free(pci_dev_put) = pci_get_slot( 86 pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), i)); 87 88 if (!pf) 89 continue; 90 91 /* on entry function 0 has already run @cb */ 92 if (i > 0) 93 cb(pf, data); 94 95 /* walk virtual functions of each pf */ 96 for (int j = 0; j < pci_num_vf(pf); j++) { 97 struct pci_dev *vf __free(pci_dev_put) = 98 pci_get_domain_bus_and_slot( 99 pci_domain_nr(pf->bus), 100 pci_iov_virtfn_bus(pf, j), 101 pci_iov_virtfn_devfn(pf, j)); 102 103 if (!vf) 104 continue; 105 106 cb(vf, data); 107 } 108 } 109 110 /* 111 * Walk downstream devices, assumes that an upstream DSM is 112 * limited to downstream physical functions 113 */ 114 if (pci_pcie_type(pdev) == PCI_EXP_TYPE_UPSTREAM && is_dsm(pdev)) 115 pci_walk_bus(pdev->subordinate, cb, data); 116 } 117 118 static void pci_tsm_walk_fns_reverse(struct pci_dev *pdev, 119 int (*cb)(struct pci_dev *pdev, 120 void *data), 121 void *data) 122 { 123 /* Reverse walk downstream devices */ 124 if (pci_pcie_type(pdev) == PCI_EXP_TYPE_UPSTREAM && is_dsm(pdev)) 125 pci_walk_bus_reverse(pdev->subordinate, cb, data); 126 127 /* Reverse walk subordinate physical functions */ 128 for (int i = 7; i >= 0; i--) { 129 struct pci_dev *pf __free(pci_dev_put) = pci_get_slot( 130 pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), i)); 131 132 if (!pf) 133 continue; 134 135 /* reverse walk virtual functions */ 136 for (int j = pci_num_vf(pf) - 1; j >= 0; j--) { 137 struct pci_dev *vf __free(pci_dev_put) = 138 pci_get_domain_bus_and_slot( 139 pci_domain_nr(pf->bus), 140 pci_iov_virtfn_bus(pf, j), 141 pci_iov_virtfn_devfn(pf, j)); 142 143 if (!vf) 144 continue; 145 cb(vf, data); 146 } 147 148 /* on exit, caller will run @cb on function 0 */ 149 if (i > 0) 150 cb(pf, data); 151 } 152 } 153 154 static void link_sysfs_disable(struct pci_dev *pdev) 155 { 156 sysfs_update_group(&pdev->dev.kobj, &pci_tsm_auth_attr_group); 157 sysfs_update_group(&pdev->dev.kobj, &pci_tsm_attr_group); 158 } 159 160 static void link_sysfs_enable(struct pci_dev *pdev) 161 { 162 bool tee = has_tee(pdev); 163 164 pci_dbg(pdev, "%s Security Manager detected (%s%s%s)\n", 165 pdev->tsm ? "Device" : "Platform TEE", 166 pdev->ide_cap ? "IDE" : "", pdev->ide_cap && tee ? " " : "", 167 tee ? "TEE" : ""); 168 169 sysfs_update_group(&pdev->dev.kobj, &pci_tsm_auth_attr_group); 170 sysfs_update_group(&pdev->dev.kobj, &pci_tsm_attr_group); 171 } 172 173 static int probe_fn(struct pci_dev *pdev, void *dsm) 174 { 175 struct pci_dev *dsm_dev = dsm; 176 const struct pci_tsm_ops *ops = to_pci_tsm_ops(dsm_dev->tsm); 177 178 pdev->tsm = ops->probe(dsm_dev->tsm->tsm_dev, pdev); 179 pci_dbg(pdev, "setup TSM context: DSM: %s status: %s\n", 180 pci_name(dsm_dev), pdev->tsm ? "success" : "failed"); 181 if (pdev->tsm) 182 link_sysfs_enable(pdev); 183 return 0; 184 } 185 186 static int pci_tsm_connect(struct pci_dev *pdev, struct tsm_dev *tsm_dev) 187 { 188 int rc; 189 struct pci_tsm_pf0 *tsm_pf0; 190 const struct pci_tsm_ops *ops = tsm_dev->pci_ops; 191 struct pci_tsm *pci_tsm __free(tsm_remove) = ops->probe(tsm_dev, pdev); 192 193 /* connect() mutually exclusive with subfunction pci_tsm_init() */ 194 lockdep_assert_held_write(&pci_tsm_rwsem); 195 196 if (!pci_tsm) 197 return -ENXIO; 198 199 pdev->tsm = pci_tsm; 200 tsm_pf0 = to_pci_tsm_pf0(pdev->tsm); 201 202 /* mutex_intr assumes connect() is always sysfs/user driven */ 203 ACQUIRE(mutex_intr, lock)(&tsm_pf0->lock); 204 if ((rc = ACQUIRE_ERR(mutex_intr, &lock))) 205 return rc; 206 207 rc = ops->connect(pdev); 208 if (rc) 209 return rc; 210 211 pdev->tsm = no_free_ptr(pci_tsm); 212 213 /* 214 * Now that the DSM is established, probe() all the potential 215 * dependent functions. Failure to probe a function is not fatal 216 * to connect(), it just disables subsequent security operations 217 * for that function. 218 * 219 * Note this is done unconditionally, without regard to finding 220 * PCI_EXP_DEVCAP_TEE on the dependent function, for robustness. The DSM 221 * is the ultimate arbiter of security state relative to a given 222 * interface id, and if it says it can manage TDISP state of a function, 223 * let it. 224 */ 225 if (has_tee(pdev)) 226 pci_tsm_walk_fns(pdev, probe_fn, pdev); 227 return 0; 228 } 229 230 static ssize_t connect_show(struct device *dev, struct device_attribute *attr, 231 char *buf) 232 { 233 struct pci_dev *pdev = to_pci_dev(dev); 234 struct tsm_dev *tsm_dev; 235 int rc; 236 237 ACQUIRE(rwsem_read_intr, lock)(&pci_tsm_rwsem); 238 if ((rc = ACQUIRE_ERR(rwsem_read_intr, &lock))) 239 return rc; 240 241 if (!pdev->tsm) 242 return sysfs_emit(buf, "\n"); 243 244 tsm_dev = pdev->tsm->tsm_dev; 245 return sysfs_emit(buf, "%s\n", dev_name(&tsm_dev->dev)); 246 } 247 248 /* Is @tsm_dev managing physical link / session properties... */ 249 static bool is_link_tsm(struct tsm_dev *tsm_dev) 250 { 251 return tsm_dev && tsm_dev->pci_ops && tsm_dev->pci_ops->link_ops.probe; 252 } 253 254 /* ...or is @tsm_dev managing device security state ? */ 255 static bool is_devsec_tsm(struct tsm_dev *tsm_dev) 256 { 257 return tsm_dev && tsm_dev->pci_ops && tsm_dev->pci_ops->devsec_ops.lock; 258 } 259 260 static ssize_t connect_store(struct device *dev, struct device_attribute *attr, 261 const char *buf, size_t len) 262 { 263 struct pci_dev *pdev = to_pci_dev(dev); 264 int rc, id; 265 266 rc = sscanf(buf, "tsm%d\n", &id); 267 if (rc != 1) 268 return -EINVAL; 269 270 ACQUIRE(rwsem_write_kill, lock)(&pci_tsm_rwsem); 271 if ((rc = ACQUIRE_ERR(rwsem_write_kill, &lock))) 272 return rc; 273 274 if (pdev->tsm) 275 return -EBUSY; 276 277 struct tsm_dev *tsm_dev __free(put_tsm_dev) = find_tsm_dev(id); 278 if (!is_link_tsm(tsm_dev)) 279 return -ENXIO; 280 281 rc = pci_tsm_connect(pdev, tsm_dev); 282 if (rc) 283 return rc; 284 return len; 285 } 286 static DEVICE_ATTR_RW(connect); 287 288 static int remove_fn(struct pci_dev *pdev, void *data) 289 { 290 tsm_remove(pdev->tsm); 291 link_sysfs_disable(pdev); 292 return 0; 293 } 294 295 /* 296 * Note, this helper only returns an error code and takes an argument for 297 * compatibility with the pci_walk_bus() callback prototype. pci_tsm_unbind() 298 * always succeeds. 299 */ 300 static int __pci_tsm_unbind(struct pci_dev *pdev, void *data) 301 { 302 struct pci_tdi *tdi; 303 struct pci_tsm_pf0 *tsm_pf0; 304 305 lockdep_assert_held(&pci_tsm_rwsem); 306 307 if (!pdev->tsm) 308 return 0; 309 310 tsm_pf0 = to_pci_tsm_pf0(pdev->tsm); 311 guard(mutex)(&tsm_pf0->lock); 312 313 tdi = pdev->tsm->tdi; 314 if (!tdi) 315 return 0; 316 317 to_pci_tsm_ops(pdev->tsm)->unbind(tdi); 318 pdev->tsm->tdi = NULL; 319 320 return 0; 321 } 322 323 void pci_tsm_unbind(struct pci_dev *pdev) 324 { 325 guard(rwsem_read)(&pci_tsm_rwsem); 326 __pci_tsm_unbind(pdev, NULL); 327 } 328 EXPORT_SYMBOL_GPL(pci_tsm_unbind); 329 330 /** 331 * pci_tsm_bind() - Bind @pdev as a TDI for @kvm 332 * @pdev: PCI device function to bind 333 * @kvm: Private memory attach context 334 * @tdi_id: Identifier (virtual BDF) for the TDI as referenced by the TSM and DSM 335 * 336 * Returns 0 on success, or a negative error code on failure. 337 * 338 * Context: Caller is responsible for constraining the bind lifetime to the 339 * registered state of the device. For example, pci_tsm_bind() / 340 * pci_tsm_unbind() limited to the VFIO driver bound state of the device. 341 */ 342 int pci_tsm_bind(struct pci_dev *pdev, struct kvm *kvm, u32 tdi_id) 343 { 344 struct pci_tsm_pf0 *tsm_pf0; 345 struct pci_tdi *tdi; 346 347 if (!kvm) 348 return -EINVAL; 349 350 guard(rwsem_read)(&pci_tsm_rwsem); 351 352 if (!pdev->tsm) 353 return -EINVAL; 354 355 if (!is_link_tsm(pdev->tsm->tsm_dev)) 356 return -ENXIO; 357 358 tsm_pf0 = to_pci_tsm_pf0(pdev->tsm); 359 guard(mutex)(&tsm_pf0->lock); 360 361 /* Resolve races to bind a TDI */ 362 if (pdev->tsm->tdi) { 363 if (pdev->tsm->tdi->kvm != kvm) 364 return -EBUSY; 365 return 0; 366 } 367 368 tdi = to_pci_tsm_ops(pdev->tsm)->bind(pdev, kvm, tdi_id); 369 if (IS_ERR(tdi)) 370 return PTR_ERR(tdi); 371 372 pdev->tsm->tdi = tdi; 373 374 return 0; 375 } 376 EXPORT_SYMBOL_GPL(pci_tsm_bind); 377 378 /** 379 * pci_tsm_guest_req() - helper to marshal guest requests to the TSM driver 380 * @pdev: @pdev representing a bound tdi 381 * @scope: caller asserts this passthrough request is limited to TDISP operations 382 * @req_in: Input payload forwarded from the guest 383 * @in_len: Length of @req_in 384 * @req_out: Output payload buffer response to the guest 385 * @out_len: Length of @req_out on input, bytes filled in @req_out on output 386 * @tsm_code: Optional TSM arch specific result code for the guest TSM 387 * 388 * This is a common entry point for requests triggered by userspace KVM-exit 389 * service handlers responding to TDI information or state change requests. The 390 * scope parameter limits requests to TDISP state management, or limited debug. 391 * This path is only suitable for commands and results that are the host kernel 392 * has no use, the host is only facilitating guest to TSM communication. 393 * 394 * Returns 0 on success and -error on failure and positive "residue" on success 395 * but @req_out is filled with less then @out_len, or @req_out is NULL and a 396 * residue number of bytes were not consumed from @req_in. On success or 397 * failure @tsm_code may be populated with a TSM implementation specific result 398 * code for the guest to consume. 399 * 400 * Context: Caller is responsible for calling this within the pci_tsm_bind() 401 * state of the TDI. 402 */ 403 ssize_t pci_tsm_guest_req(struct pci_dev *pdev, enum pci_tsm_req_scope scope, 404 sockptr_t req_in, size_t in_len, sockptr_t req_out, 405 size_t out_len, u64 *tsm_code) 406 { 407 struct pci_tsm_pf0 *tsm_pf0; 408 struct pci_tdi *tdi; 409 int rc; 410 411 /* Forbid requests that are not directly related to TDISP operations */ 412 if (scope > PCI_TSM_REQ_STATE_CHANGE) 413 return -EINVAL; 414 415 ACQUIRE(rwsem_read_intr, lock)(&pci_tsm_rwsem); 416 if ((rc = ACQUIRE_ERR(rwsem_read_intr, &lock))) 417 return rc; 418 419 if (!pdev->tsm) 420 return -ENXIO; 421 422 if (!is_link_tsm(pdev->tsm->tsm_dev)) 423 return -ENXIO; 424 425 tsm_pf0 = to_pci_tsm_pf0(pdev->tsm); 426 ACQUIRE(mutex_intr, ops_lock)(&tsm_pf0->lock); 427 if ((rc = ACQUIRE_ERR(mutex_intr, &ops_lock))) 428 return rc; 429 430 tdi = pdev->tsm->tdi; 431 if (!tdi) 432 return -ENXIO; 433 return to_pci_tsm_ops(pdev->tsm)->guest_req(tdi, scope, req_in, in_len, 434 req_out, out_len, tsm_code); 435 } 436 EXPORT_SYMBOL_GPL(pci_tsm_guest_req); 437 438 static void pci_tsm_unbind_all(struct pci_dev *pdev) 439 { 440 pci_tsm_walk_fns_reverse(pdev, __pci_tsm_unbind, NULL); 441 __pci_tsm_unbind(pdev, NULL); 442 } 443 444 static void __pci_tsm_disconnect(struct pci_dev *pdev) 445 { 446 struct pci_tsm_pf0 *tsm_pf0 = to_pci_tsm_pf0(pdev->tsm); 447 const struct pci_tsm_ops *ops = to_pci_tsm_ops(pdev->tsm); 448 449 /* disconnect() mutually exclusive with subfunction pci_tsm_init() */ 450 lockdep_assert_held_write(&pci_tsm_rwsem); 451 452 pci_tsm_unbind_all(pdev); 453 454 /* 455 * disconnect() is uninterruptible as it may be called for device 456 * teardown 457 */ 458 guard(mutex)(&tsm_pf0->lock); 459 pci_tsm_walk_fns_reverse(pdev, remove_fn, NULL); 460 ops->disconnect(pdev); 461 } 462 463 static void pci_tsm_disconnect(struct pci_dev *pdev) 464 { 465 __pci_tsm_disconnect(pdev); 466 tsm_remove(pdev->tsm); 467 } 468 469 static ssize_t disconnect_store(struct device *dev, 470 struct device_attribute *attr, const char *buf, 471 size_t len) 472 { 473 struct pci_dev *pdev = to_pci_dev(dev); 474 struct tsm_dev *tsm_dev; 475 int rc; 476 477 ACQUIRE(rwsem_write_kill, lock)(&pci_tsm_rwsem); 478 if ((rc = ACQUIRE_ERR(rwsem_write_kill, &lock))) 479 return rc; 480 481 if (!pdev->tsm) 482 return -ENXIO; 483 484 tsm_dev = pdev->tsm->tsm_dev; 485 if (!sysfs_streq(buf, dev_name(&tsm_dev->dev))) 486 return -EINVAL; 487 488 pci_tsm_disconnect(pdev); 489 return len; 490 } 491 static DEVICE_ATTR_WO(disconnect); 492 493 static ssize_t bound_show(struct device *dev, 494 struct device_attribute *attr, char *buf) 495 { 496 struct pci_dev *pdev = to_pci_dev(dev); 497 struct pci_tsm_pf0 *tsm_pf0; 498 struct pci_tsm *tsm; 499 int rc; 500 501 ACQUIRE(rwsem_read_intr, lock)(&pci_tsm_rwsem); 502 if ((rc = ACQUIRE_ERR(rwsem_read_intr, &lock))) 503 return rc; 504 505 tsm = pdev->tsm; 506 if (!tsm) 507 return sysfs_emit(buf, "\n"); 508 tsm_pf0 = to_pci_tsm_pf0(tsm); 509 510 ACQUIRE(mutex_intr, ops_lock)(&tsm_pf0->lock); 511 if ((rc = ACQUIRE_ERR(mutex_intr, &ops_lock))) 512 return rc; 513 514 if (!tsm->tdi) 515 return sysfs_emit(buf, "\n"); 516 return sysfs_emit(buf, "%s\n", dev_name(&tsm->tsm_dev->dev)); 517 } 518 static DEVICE_ATTR_RO(bound); 519 520 static ssize_t dsm_show(struct device *dev, struct device_attribute *attr, 521 char *buf) 522 { 523 struct pci_dev *pdev = to_pci_dev(dev); 524 struct pci_tsm *tsm; 525 int rc; 526 527 ACQUIRE(rwsem_read_intr, lock)(&pci_tsm_rwsem); 528 if ((rc = ACQUIRE_ERR(rwsem_read_intr, &lock))) 529 return rc; 530 531 tsm = pdev->tsm; 532 if (!tsm) 533 return sysfs_emit(buf, "\n"); 534 535 return sysfs_emit(buf, "%s\n", pci_name(tsm->dsm_dev)); 536 } 537 static DEVICE_ATTR_RO(dsm); 538 539 /* The 'authenticated' attribute is exclusive to the presence of a 'link' TSM */ 540 static bool pci_tsm_link_group_visible(struct kobject *kobj) 541 { 542 struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); 543 544 if (!pci_tsm_link_count) 545 return false; 546 547 if (!pci_is_pcie(pdev)) 548 return false; 549 550 if (is_pci_tsm_pf0(pdev)) 551 return true; 552 553 /* 554 * Show 'authenticated' and other attributes for the managed 555 * sub-functions of a DSM. 556 */ 557 if (pdev->tsm) 558 return true; 559 560 return false; 561 } 562 DEFINE_SIMPLE_SYSFS_GROUP_VISIBLE(pci_tsm_link); 563 564 /* 565 * 'link' and 'devsec' TSMs share the same 'tsm/' sysfs group, so the TSM type 566 * specific attributes need individual visibility checks. 567 */ 568 static umode_t pci_tsm_attr_visible(struct kobject *kobj, 569 struct attribute *attr, int n) 570 { 571 if (pci_tsm_link_group_visible(kobj)) { 572 struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj)); 573 574 if (attr == &dev_attr_bound.attr) { 575 if (is_pci_tsm_pf0(pdev) && has_tee(pdev)) 576 return attr->mode; 577 if (pdev->tsm && has_tee(pdev->tsm->dsm_dev)) 578 return attr->mode; 579 } 580 581 if (attr == &dev_attr_dsm.attr) { 582 if (is_pci_tsm_pf0(pdev)) 583 return attr->mode; 584 if (pdev->tsm && has_tee(pdev->tsm->dsm_dev)) 585 return attr->mode; 586 } 587 588 if (attr == &dev_attr_connect.attr || 589 attr == &dev_attr_disconnect.attr) { 590 if (is_pci_tsm_pf0(pdev)) 591 return attr->mode; 592 } 593 } 594 595 return 0; 596 } 597 598 static bool pci_tsm_group_visible(struct kobject *kobj) 599 { 600 return pci_tsm_link_group_visible(kobj); 601 } 602 DEFINE_SYSFS_GROUP_VISIBLE(pci_tsm); 603 604 static struct attribute *pci_tsm_attrs[] = { 605 &dev_attr_connect.attr, 606 &dev_attr_disconnect.attr, 607 &dev_attr_bound.attr, 608 &dev_attr_dsm.attr, 609 NULL 610 }; 611 612 const struct attribute_group pci_tsm_attr_group = { 613 .name = "tsm", 614 .attrs = pci_tsm_attrs, 615 .is_visible = SYSFS_GROUP_VISIBLE(pci_tsm), 616 }; 617 618 static ssize_t authenticated_show(struct device *dev, 619 struct device_attribute *attr, char *buf) 620 { 621 /* 622 * When the SPDM session established via TSM the 'authenticated' state 623 * of the device is identical to the connect state. 624 */ 625 return connect_show(dev, attr, buf); 626 } 627 static DEVICE_ATTR_RO(authenticated); 628 629 static struct attribute *pci_tsm_auth_attrs[] = { 630 &dev_attr_authenticated.attr, 631 NULL 632 }; 633 634 const struct attribute_group pci_tsm_auth_attr_group = { 635 .attrs = pci_tsm_auth_attrs, 636 .is_visible = SYSFS_GROUP_VISIBLE(pci_tsm_link), 637 }; 638 639 /* 640 * Retrieve physical function0 device whether it has TEE capability or not 641 */ 642 static struct pci_dev *pf0_dev_get(struct pci_dev *pdev) 643 { 644 struct pci_dev *pf_dev = pci_physfn(pdev); 645 646 if (PCI_FUNC(pf_dev->devfn) == 0) 647 return pci_dev_get(pf_dev); 648 649 return pci_get_slot(pf_dev->bus, 650 pf_dev->devfn - PCI_FUNC(pf_dev->devfn)); 651 } 652 653 /* 654 * Find the PCI Device instance that serves as the Device Security Manager (DSM) 655 * for @pdev. Note that no additional reference is held for the resulting device 656 * because that resulting object always has a registered lifetime 657 * greater-than-or-equal to that of the @pdev argument. This is by virtue of 658 * @pdev being a descendant of, or identical to, the returned DSM device. 659 */ 660 static struct pci_dev *find_dsm_dev(struct pci_dev *pdev) 661 { 662 struct device *grandparent; 663 struct pci_dev *uport; 664 665 if (is_pci_tsm_pf0(pdev)) 666 return pdev; 667 668 struct pci_dev *pf0 __free(pci_dev_put) = pf0_dev_get(pdev); 669 if (!pf0) 670 return NULL; 671 672 if (is_dsm(pf0)) 673 return pf0; 674 675 /* 676 * For cases where a switch may be hosting TDISP services on behalf of 677 * downstream devices, check the first upstream port relative to this 678 * endpoint. 679 */ 680 if (!pdev->dev.parent) 681 return NULL; 682 grandparent = pdev->dev.parent->parent; 683 if (!grandparent) 684 return NULL; 685 if (!dev_is_pci(grandparent)) 686 return NULL; 687 uport = to_pci_dev(grandparent); 688 if (!pci_is_pcie(uport) || 689 pci_pcie_type(uport) != PCI_EXP_TYPE_UPSTREAM) 690 return NULL; 691 692 if (is_dsm(uport)) 693 return uport; 694 return NULL; 695 } 696 697 /** 698 * pci_tsm_tdi_constructor() - base 'struct pci_tdi' initialization for link TSMs 699 * @pdev: PCI device function representing the TDI 700 * @tdi: context to initialize 701 * @kvm: Private memory attach context 702 * @tdi_id: Identifier (virtual BDF) for the TDI as referenced by the TSM and DSM 703 */ 704 void pci_tsm_tdi_constructor(struct pci_dev *pdev, struct pci_tdi *tdi, 705 struct kvm *kvm, u32 tdi_id) 706 { 707 tdi->pdev = pdev; 708 tdi->kvm = kvm; 709 tdi->tdi_id = tdi_id; 710 } 711 EXPORT_SYMBOL_GPL(pci_tsm_tdi_constructor); 712 713 /** 714 * pci_tsm_link_constructor() - base 'struct pci_tsm' initialization for link TSMs 715 * @pdev: The PCI device 716 * @tsm: context to initialize 717 * @tsm_dev: Platform TEE Security Manager, initiator of security operations 718 */ 719 int pci_tsm_link_constructor(struct pci_dev *pdev, struct pci_tsm *tsm, 720 struct tsm_dev *tsm_dev) 721 { 722 if (!is_link_tsm(tsm_dev)) 723 return -EINVAL; 724 725 tsm->dsm_dev = find_dsm_dev(pdev); 726 if (!tsm->dsm_dev) { 727 pci_warn(pdev, "failed to find Device Security Manager\n"); 728 return -ENXIO; 729 } 730 tsm->pdev = pdev; 731 tsm->tsm_dev = tsm_dev; 732 733 return 0; 734 } 735 EXPORT_SYMBOL_GPL(pci_tsm_link_constructor); 736 737 /** 738 * pci_tsm_pf0_constructor() - common 'struct pci_tsm_pf0' (DSM) initialization 739 * @pdev: Physical Function 0 PCI device (as indicated by is_pci_tsm_pf0()) 740 * @tsm: context to initialize 741 * @tsm_dev: Platform TEE Security Manager, initiator of security operations 742 */ 743 int pci_tsm_pf0_constructor(struct pci_dev *pdev, struct pci_tsm_pf0 *tsm, 744 struct tsm_dev *tsm_dev) 745 { 746 mutex_init(&tsm->lock); 747 tsm->doe_mb = pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG, 748 PCI_DOE_FEATURE_CMA); 749 if (!tsm->doe_mb) { 750 pci_warn(pdev, "TSM init failure, no CMA mailbox\n"); 751 return -ENODEV; 752 } 753 754 return pci_tsm_link_constructor(pdev, &tsm->base_tsm, tsm_dev); 755 } 756 EXPORT_SYMBOL_GPL(pci_tsm_pf0_constructor); 757 758 void pci_tsm_pf0_destructor(struct pci_tsm_pf0 *pf0_tsm) 759 { 760 mutex_destroy(&pf0_tsm->lock); 761 } 762 EXPORT_SYMBOL_GPL(pci_tsm_pf0_destructor); 763 764 int pci_tsm_register(struct tsm_dev *tsm_dev) 765 { 766 struct pci_dev *pdev = NULL; 767 768 if (!tsm_dev) 769 return -EINVAL; 770 771 /* The TSM device must only implement one of link_ops or devsec_ops */ 772 if (!is_link_tsm(tsm_dev) && !is_devsec_tsm(tsm_dev)) 773 return -EINVAL; 774 775 if (is_link_tsm(tsm_dev) && is_devsec_tsm(tsm_dev)) 776 return -EINVAL; 777 778 guard(rwsem_write)(&pci_tsm_rwsem); 779 780 /* On first enable, update sysfs groups */ 781 if (is_link_tsm(tsm_dev) && pci_tsm_link_count++ == 0) { 782 for_each_pci_dev(pdev) 783 if (is_pci_tsm_pf0(pdev)) 784 link_sysfs_enable(pdev); 785 } else if (is_devsec_tsm(tsm_dev)) { 786 pci_tsm_devsec_count++; 787 } 788 789 return 0; 790 } 791 792 static void pci_tsm_fn_exit(struct pci_dev *pdev) 793 { 794 __pci_tsm_unbind(pdev, NULL); 795 tsm_remove(pdev->tsm); 796 } 797 798 /** 799 * __pci_tsm_destroy() - destroy the TSM context for @pdev 800 * @pdev: device to cleanup 801 * @tsm_dev: the TSM device being removed, or NULL if @pdev is being removed. 802 * 803 * At device removal or TSM unregistration all established context 804 * with the TSM is torn down. Additionally, if there are no more TSMs 805 * registered, the PCI tsm/ sysfs attributes are hidden. 806 */ 807 static void __pci_tsm_destroy(struct pci_dev *pdev, struct tsm_dev *tsm_dev) 808 { 809 struct pci_tsm *tsm = pdev->tsm; 810 811 lockdep_assert_held_write(&pci_tsm_rwsem); 812 813 /* 814 * First, handle the TSM removal case to shutdown @pdev sysfs, this is 815 * skipped if the device itself is being removed since sysfs goes away 816 * naturally at that point 817 */ 818 if (is_link_tsm(tsm_dev) && is_pci_tsm_pf0(pdev) && !pci_tsm_link_count) 819 link_sysfs_disable(pdev); 820 821 /* Nothing else to do if this device never attached to the departing TSM */ 822 if (!tsm) 823 return; 824 825 /* Now lookup the tsm_dev to destroy TSM context */ 826 if (!tsm_dev) 827 tsm_dev = tsm->tsm_dev; 828 else if (tsm_dev != tsm->tsm_dev) 829 return; 830 831 if (is_link_tsm(tsm_dev) && is_pci_tsm_pf0(pdev)) 832 pci_tsm_disconnect(pdev); 833 else 834 pci_tsm_fn_exit(pdev); 835 } 836 837 void pci_tsm_destroy(struct pci_dev *pdev) 838 { 839 guard(rwsem_write)(&pci_tsm_rwsem); 840 __pci_tsm_destroy(pdev, NULL); 841 } 842 843 void pci_tsm_init(struct pci_dev *pdev) 844 { 845 guard(rwsem_read)(&pci_tsm_rwsem); 846 847 /* 848 * Subfunctions are either probed synchronous with connect() or later 849 * when either the SR-IOV configuration is changed, or, unlikely, 850 * connect() raced initial bus scanning. 851 */ 852 if (pdev->tsm) 853 return; 854 855 if (pci_tsm_link_count) { 856 struct pci_dev *dsm = find_dsm_dev(pdev); 857 858 if (!dsm) 859 return; 860 861 /* 862 * The only path to init a Device Security Manager capable 863 * device is via connect(). 864 */ 865 if (!dsm->tsm) 866 return; 867 868 probe_fn(pdev, dsm); 869 } 870 } 871 872 void pci_tsm_unregister(struct tsm_dev *tsm_dev) 873 { 874 struct pci_dev *pdev = NULL; 875 876 guard(rwsem_write)(&pci_tsm_rwsem); 877 if (is_link_tsm(tsm_dev)) 878 pci_tsm_link_count--; 879 if (is_devsec_tsm(tsm_dev)) 880 pci_tsm_devsec_count--; 881 for_each_pci_dev_reverse(pdev) 882 __pci_tsm_destroy(pdev, tsm_dev); 883 } 884 885 int pci_tsm_doe_transfer(struct pci_dev *pdev, u8 type, const void *req, 886 size_t req_sz, void *resp, size_t resp_sz) 887 { 888 struct pci_tsm_pf0 *tsm; 889 890 if (!pdev->tsm || !is_pci_tsm_pf0(pdev)) 891 return -ENXIO; 892 893 tsm = to_pci_tsm_pf0(pdev->tsm); 894 if (!tsm->doe_mb) 895 return -ENXIO; 896 897 return pci_doe(tsm->doe_mb, PCI_VENDOR_ID_PCI_SIG, type, req, req_sz, 898 resp, resp_sz); 899 } 900 EXPORT_SYMBOL_GPL(pci_tsm_doe_transfer); 901