tsm.c 23 KB

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