xref: /linux/drivers/crypto/ccp/sev-dev-tsm.c (revision 09e6b79b8ce388993aec9ac91b1cb2c181c27bd9)
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 // Interface to CCP/SEV-TIO for generic PCIe TDISP module
4 
5 #include <linux/pci.h>
6 #include <linux/device.h>
7 #include <linux/tsm.h>
8 #include <linux/iommu.h>
9 #include <linux/pci-doe.h>
10 #include <linux/bitfield.h>
11 #include <linux/module.h>
12 
13 #include <asm/sev-common.h>
14 #include <asm/sev.h>
15 
16 #include "psp-dev.h"
17 #include "sev-dev.h"
18 #include "sev-dev-tio.h"
19 
20 MODULE_IMPORT_NS("PCI_IDE");
21 
22 #define dev_to_sp(dev)		((struct sp_device *)dev_get_drvdata(dev))
23 #define dev_to_psp(dev)		((struct psp_device *)(dev_to_sp(dev)->psp_data))
24 #define dev_to_sev(dev)		((struct sev_device *)(dev_to_psp(dev)->sev_data))
25 #define tsm_dev_to_sev(tsmdev)	dev_to_sev((tsmdev)->dev.parent)
26 
27 #define pdev_to_tio_dsm(pdev)	(container_of((pdev)->tsm, struct tio_dsm, tsm.base_tsm))
28 
29 static int sev_tio_spdm_cmd(struct tio_dsm *dsm, int ret)
30 {
31 	struct tsm_dsm_tio *dev_data = &dsm->data;
32 	struct tsm_spdm *spdm = &dev_data->spdm;
33 
34 	/* Check the main command handler response before entering the loop */
35 	if (ret == 0 && dev_data->psp_ret != SEV_RET_SUCCESS)
36 		return -EINVAL;
37 
38 	if (ret <= 0)
39 		return ret;
40 
41 	/* ret > 0 means "SPDM requested" */
42 	while (ret == PCI_DOE_FEATURE_CMA || ret == PCI_DOE_FEATURE_SSESSION) {
43 		ret = pci_doe(dsm->tsm.doe_mb, PCI_VENDOR_ID_PCI_SIG, ret,
44 			      spdm->req, spdm->req_len, spdm->rsp, spdm->rsp_len);
45 		if (ret < 0)
46 			break;
47 
48 		WARN_ON_ONCE(ret == 0); /* The response should never be empty */
49 		spdm->rsp_len = ret;
50 		ret = sev_tio_continue(dev_data);
51 	}
52 
53 	return ret;
54 }
55 
56 static int stream_enable(struct pci_ide *ide)
57 {
58 	struct pci_dev *rp = pcie_find_root_port(ide->pdev);
59 	int ret;
60 
61 	ret = pci_ide_stream_enable(rp, ide);
62 	if (ret)
63 		return ret;
64 
65 	ret = pci_ide_stream_enable(ide->pdev, ide);
66 	if (ret)
67 		pci_ide_stream_disable(rp, ide);
68 
69 	return ret;
70 }
71 
72 static int streams_enable(struct pci_ide **ide)
73 {
74 	int ret = 0;
75 
76 	for (int i = 0; i < TIO_IDE_MAX_TC; ++i) {
77 		if (ide[i]) {
78 			ret = stream_enable(ide[i]);
79 			if (ret)
80 				break;
81 		}
82 	}
83 
84 	return ret;
85 }
86 
87 static void stream_disable(struct pci_ide *ide)
88 {
89 	pci_ide_stream_disable(ide->pdev, ide);
90 	pci_ide_stream_disable(pcie_find_root_port(ide->pdev), ide);
91 }
92 
93 static void streams_disable(struct pci_ide **ide)
94 {
95 	for (int i = 0; i < TIO_IDE_MAX_TC; ++i)
96 		if (ide[i])
97 			stream_disable(ide[i]);
98 }
99 
100 static void stream_setup(struct pci_ide *ide)
101 {
102 	struct pci_dev *rp = pcie_find_root_port(ide->pdev);
103 
104 	ide->partner[PCI_IDE_EP].rid_start = 0;
105 	ide->partner[PCI_IDE_EP].rid_end = 0xffff;
106 	ide->partner[PCI_IDE_RP].rid_start = 0;
107 	ide->partner[PCI_IDE_RP].rid_end = 0xffff;
108 
109 	ide->pdev->ide_cfg = 0;
110 	ide->pdev->ide_tee_limit = 1;
111 	rp->ide_cfg = 1;
112 	rp->ide_tee_limit = 0;
113 
114 	pci_warn(ide->pdev, "Forcing CFG/TEE for %s", pci_name(rp));
115 	pci_ide_stream_setup(ide->pdev, ide);
116 	pci_ide_stream_setup(rp, ide);
117 }
118 
119 static u8 streams_setup(struct pci_ide **ide, u8 *ids)
120 {
121 	bool def = false;
122 	u8 tc_mask = 0;
123 	int i;
124 
125 	for (i = 0; i < TIO_IDE_MAX_TC; ++i) {
126 		if (!ide[i]) {
127 			ids[i] = 0xFF;
128 			continue;
129 		}
130 
131 		tc_mask |= BIT(i);
132 		ids[i] = ide[i]->stream_id;
133 
134 		if (!def) {
135 			struct pci_ide_partner *settings;
136 
137 			settings = pci_ide_to_settings(ide[i]->pdev, ide[i]);
138 			settings->default_stream = 1;
139 			def = true;
140 		}
141 
142 		stream_setup(ide[i]);
143 	}
144 
145 	return tc_mask;
146 }
147 
148 static int streams_register(struct pci_ide **ide)
149 {
150 	int ret = 0, i;
151 
152 	for (i = 0; i < TIO_IDE_MAX_TC; ++i) {
153 		if (ide[i]) {
154 			ret = pci_ide_stream_register(ide[i]);
155 			if (ret)
156 				break;
157 		}
158 	}
159 
160 	return ret;
161 }
162 
163 static void streams_unregister(struct pci_ide **ide)
164 {
165 	for (int i = 0; i < TIO_IDE_MAX_TC; ++i)
166 		if (ide[i])
167 			pci_ide_stream_unregister(ide[i]);
168 }
169 
170 static void stream_teardown(struct pci_ide *ide)
171 {
172 	pci_ide_stream_teardown(ide->pdev, ide);
173 	pci_ide_stream_teardown(pcie_find_root_port(ide->pdev), ide);
174 }
175 
176 static void streams_teardown(struct pci_ide **ide)
177 {
178 	for (int i = 0; i < TIO_IDE_MAX_TC; ++i) {
179 		if (ide[i]) {
180 			stream_teardown(ide[i]);
181 			pci_ide_stream_free(ide[i]);
182 			ide[i] = NULL;
183 		}
184 	}
185 }
186 
187 static int stream_alloc(struct pci_dev *pdev, struct pci_ide **ide,
188 			unsigned int tc)
189 {
190 	struct pci_ide *ide1;
191 
192 	if (ide[tc]) {
193 		pci_err(pdev, "Stream for class=%d already registered", tc);
194 		return -EBUSY;
195 	}
196 
197 	ide1 = pci_ide_stream_alloc(pdev);
198 	if (!ide1)
199 		return -EFAULT;
200 
201 	ide1->stream_id = ide1->host_bridge_stream;
202 
203 	ide[tc] = ide1;
204 
205 	return 0;
206 }
207 
208 static struct pci_tsm *tio_pf0_probe(struct pci_dev *pdev, struct sev_device *sev)
209 {
210 	struct tio_dsm *dsm __free(kfree) = kzalloc_obj(*dsm);
211 	int rc;
212 
213 	if (!dsm)
214 		return NULL;
215 
216 	rc = pci_tsm_pf0_constructor(pdev, &dsm->tsm, sev->tsmdev);
217 	if (rc)
218 		return NULL;
219 
220 	pci_dbg(pdev, "TSM enabled\n");
221 	dsm->sev = sev;
222 	return &no_free_ptr(dsm)->tsm.base_tsm;
223 }
224 
225 static struct pci_tsm *dsm_probe(struct tsm_dev *tsmdev, struct pci_dev *pdev)
226 {
227 	struct sev_device *sev = tsm_dev_to_sev(tsmdev);
228 
229 	if (is_pci_tsm_pf0(pdev))
230 		return tio_pf0_probe(pdev, sev);
231 	return NULL;
232 }
233 
234 static void dsm_remove(struct pci_tsm *tsm)
235 {
236 	struct pci_dev *pdev = tsm->pdev;
237 
238 	pci_dbg(pdev, "TSM disabled\n");
239 
240 	if (is_pci_tsm_pf0(pdev)) {
241 		struct tio_dsm *dsm = container_of(tsm, struct tio_dsm, tsm.base_tsm);
242 
243 		pci_tsm_pf0_destructor(&dsm->tsm);
244 		kfree(dsm);
245 	}
246 }
247 
248 static int dsm_create(struct tio_dsm *dsm)
249 {
250 	struct pci_dev *pdev = dsm->tsm.base_tsm.pdev;
251 	struct pci_dev *rootport;
252 	u8 segment_id;
253 	u16 device_id;
254 	u16 root_port_id;
255 	u32 lnkcap = 0;
256 
257 	if (!pdev->bus)
258 		return -ENODEV;
259 
260 	segment_id = pci_domain_nr(pdev->bus);
261 	rootport = pcie_find_root_port(pdev);
262 	device_id = pci_dev_id(pdev);
263 
264 	if (pci_read_config_dword(rootport, pci_pcie_cap(rootport) + PCI_EXP_LNKCAP,
265 				  &lnkcap))
266 		return -ENODEV;
267 
268 	root_port_id = FIELD_GET(PCI_EXP_LNKCAP_PN, lnkcap);
269 
270 	return sev_tio_dev_create(&dsm->data, device_id, root_port_id, segment_id);
271 }
272 
273 static int dsm_connect(struct pci_dev *pdev)
274 {
275 	struct tio_dsm *dsm = pdev_to_tio_dsm(pdev);
276 	struct tsm_dsm_tio *dev_data = &dsm->data;
277 	u8 ids[TIO_IDE_MAX_TC];
278 	u8 tc_mask;
279 	int ret;
280 
281 	if (pci_find_doe_mailbox(pdev, PCI_VENDOR_ID_PCI_SIG,
282 				 PCI_DOE_FEATURE_SSESSION) != dsm->tsm.doe_mb) {
283 		pci_err(pdev, "CMA DOE MB must support SSESSION\n");
284 		return -EFAULT;
285 	}
286 
287 	ret = stream_alloc(pdev, dev_data->ide, 0);
288 	if (ret)
289 		return ret;
290 
291 	ret = dsm_create(dsm);
292 	if (ret)
293 		goto ide_free_exit;
294 
295 	tc_mask = streams_setup(dev_data->ide, ids);
296 
297 	ret = sev_tio_dev_connect(dev_data, tc_mask, ids, dev_data->cert_slot);
298 	ret = sev_tio_spdm_cmd(dsm, ret);
299 	if (ret)
300 		goto free_exit;
301 
302 	streams_enable(dev_data->ide);
303 
304 	ret = streams_register(dev_data->ide);
305 	if (ret)
306 		goto free_exit;
307 
308 	return 0;
309 
310 free_exit:
311 	sev_tio_dev_reclaim(dev_data);
312 
313 	streams_disable(dev_data->ide);
314 ide_free_exit:
315 
316 	streams_teardown(dev_data->ide);
317 
318 	return ret;
319 }
320 
321 static void dsm_disconnect(struct pci_dev *pdev)
322 {
323 	bool force = SYSTEM_HALT <= system_state && system_state <= SYSTEM_RESTART;
324 	struct tio_dsm *dsm = pdev_to_tio_dsm(pdev);
325 	struct tsm_dsm_tio *dev_data = &dsm->data;
326 	int ret;
327 
328 	ret = sev_tio_dev_disconnect(dev_data, force);
329 	ret = sev_tio_spdm_cmd(dsm, ret);
330 	if (ret && !force) {
331 		ret = sev_tio_dev_disconnect(dev_data, true);
332 		sev_tio_spdm_cmd(dsm, ret);
333 	}
334 
335 	sev_tio_dev_reclaim(dev_data);
336 
337 	streams_disable(dev_data->ide);
338 	streams_unregister(dev_data->ide);
339 	streams_teardown(dev_data->ide);
340 }
341 
342 static struct pci_tsm_ops sev_tsm_ops = {
343 	.probe = dsm_probe,
344 	.remove = dsm_remove,
345 	.connect = dsm_connect,
346 	.disconnect = dsm_disconnect,
347 };
348 
349 void sev_tsm_init_locked(struct sev_device *sev, void *tio_status_page)
350 {
351 	struct sev_tio_status *t = kzalloc_obj(*t);
352 	struct tsm_dev *tsmdev;
353 	int ret;
354 
355 	WARN_ON(sev->tio_status);
356 
357 	if (!t)
358 		return;
359 
360 	ret = sev_tio_init_locked(tio_status_page);
361 	if (ret) {
362 		pr_warn("SEV-TIO STATUS failed with %d\n", ret);
363 		goto error_exit;
364 	}
365 
366 	tsmdev = tsm_register(sev->dev, &sev_tsm_ops);
367 	if (IS_ERR(tsmdev))
368 		goto error_exit;
369 
370 	memcpy(t, tio_status_page, sizeof(*t));
371 
372 	pr_notice("SEV-TIO status: EN=%d INIT_DONE=%d rq=%d..%d rs=%d..%d "
373 		  "scr=%d..%d out=%d..%d dev=%d tdi=%d algos=%x\n",
374 		  t->tio_en, t->tio_init_done,
375 		  t->spdm_req_size_min, t->spdm_req_size_max,
376 		  t->spdm_rsp_size_min, t->spdm_rsp_size_max,
377 		  t->spdm_scratch_size_min, t->spdm_scratch_size_max,
378 		  t->spdm_out_size_min, t->spdm_out_size_max,
379 		  t->devctx_size, t->tdictx_size,
380 		  t->tio_crypto_alg);
381 
382 	sev->tsmdev = tsmdev;
383 	sev->tio_status = t;
384 
385 	return;
386 
387 error_exit:
388 	pr_err("Failed to enable SEV-TIO: ret=%d en=%d initdone=%d SEV=%d\n",
389 	       ret, t->tio_en, t->tio_init_done, boot_cpu_has(X86_FEATURE_SEV));
390 	kfree(t);
391 }
392 
393 void sev_tsm_uninit(struct sev_device *sev)
394 {
395 	if (sev->tsmdev)
396 		tsm_unregister(sev->tsmdev);
397 
398 	sev->tsmdev = NULL;
399 }
400