xref: /linux/drivers/pci/tsm.c (revision 249872f53d64441690927853e9d3af36394802d5)
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 
to_pci_tsm_ops(struct pci_tsm * tsm)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 
is_dsm(struct pci_dev * pdev)38 static inline bool is_dsm(struct pci_dev *pdev)
39 {
40 	return pdev->tsm && pdev->tsm->dsm_dev == pdev;
41 }
42 
has_tee(struct pci_dev * pdev)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) */
to_pci_tsm_pf0(struct pci_tsm * tsm)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 
tsm_remove(struct pci_tsm * tsm)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 }
DEFINE_FREE(tsm_remove,struct pci_tsm *,if (_T)tsm_remove (_T))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 
pci_tsm_walk_fns_reverse(struct pci_dev * pdev,int (* cb)(struct pci_dev * pdev,void * data),void * data)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 
link_sysfs_disable(struct pci_dev * pdev)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 
link_sysfs_enable(struct pci_dev * pdev)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 
probe_fn(struct pci_dev * pdev,void * dsm)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 
pci_tsm_connect(struct pci_dev * pdev,struct tsm_dev * tsm_dev)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 
connect_show(struct device * dev,struct device_attribute * attr,char * buf)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... */
is_link_tsm(struct tsm_dev * tsm_dev)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 ? */
is_devsec_tsm(struct tsm_dev * tsm_dev)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 
connect_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)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 
remove_fn(struct pci_dev * pdev,void * data)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  */
__pci_tsm_unbind(struct pci_dev * pdev,void * data)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 
pci_tsm_unbind(struct pci_dev * pdev)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  */
pci_tsm_bind(struct pci_dev * pdev,struct kvm * kvm,u32 tdi_id)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  */
pci_tsm_guest_req(struct pci_dev * pdev,enum pci_tsm_req_scope scope,sockptr_t req_in,size_t in_len,sockptr_t req_out,size_t out_len,u64 * tsm_code)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 
pci_tsm_unbind_all(struct pci_dev * pdev)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 
__pci_tsm_disconnect(struct pci_dev * pdev)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 
pci_tsm_disconnect(struct pci_dev * pdev)463 static void pci_tsm_disconnect(struct pci_dev *pdev)
464 {
465 	__pci_tsm_disconnect(pdev);
466 	tsm_remove(pdev->tsm);
467 }
468 
disconnect_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t len)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 
bound_show(struct device * dev,struct device_attribute * attr,char * buf)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 
dsm_show(struct device * dev,struct device_attribute * attr,char * buf)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 */
pci_tsm_link_group_visible(struct kobject * kobj)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  */
pci_tsm_attr_visible(struct kobject * kobj,struct attribute * attr,int n)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 
pci_tsm_group_visible(struct kobject * kobj)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 
authenticated_show(struct device * dev,struct device_attribute * attr,char * buf)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  */
pf0_dev_get(struct pci_dev * pdev)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  */
find_dsm_dev(struct pci_dev * pdev)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  */
pci_tsm_tdi_constructor(struct pci_dev * pdev,struct pci_tdi * tdi,struct kvm * kvm,u32 tdi_id)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  */
pci_tsm_link_constructor(struct pci_dev * pdev,struct pci_tsm * tsm,struct tsm_dev * tsm_dev)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  */
pci_tsm_pf0_constructor(struct pci_dev * pdev,struct pci_tsm_pf0 * tsm,struct tsm_dev * tsm_dev)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 
pci_tsm_pf0_destructor(struct pci_tsm_pf0 * pf0_tsm)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 
pci_tsm_register(struct tsm_dev * tsm_dev)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 
pci_tsm_fn_exit(struct pci_dev * pdev)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  */
__pci_tsm_destroy(struct pci_dev * pdev,struct tsm_dev * tsm_dev)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 
pci_tsm_destroy(struct pci_dev * pdev)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 
pci_tsm_init(struct pci_dev * pdev)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 
pci_tsm_unregister(struct tsm_dev * tsm_dev)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 
pci_tsm_doe_transfer(struct pci_dev * pdev,u8 type,const void * req,size_t req_sz,void * resp,size_t resp_sz)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