File Index
Files and directories
Sign in
FILE

sp-pci.c

File preview with syntax highlighting.

linux-6.19.14/drivers/crypto/ccp/sp-pci.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * AMD Secure Processor device driver
  4 *
  5 * Copyright (C) 2013,2019 Advanced Micro Devices, Inc.
  6 *
  7 * Author: Tom Lendacky <thomas.lendacky@amd.com>
  8 * Author: Gary R Hook <gary.hook@amd.com>
  9 */
 10
 11#include <linux/bitfield.h>
 12#include <linux/module.h>
 13#include <linux/kernel.h>
 14#include <linux/device.h>
 15#include <linux/pci.h>
 16#include <linux/pci_ids.h>
 17#include <linux/dma-mapping.h>
 18#include <linux/kthread.h>
 19#include <linux/sched.h>
 20#include <linux/interrupt.h>
 21#include <linux/spinlock.h>
 22#include <linux/delay.h>
 23#include <linux/ccp.h>
 24
 25#include "ccp-dev.h"
 26#include "psp-dev.h"
 27#include "hsti.h"
 28
 29/* used for version string AA.BB.CC.DD */
 30#define AA				GENMASK(31, 24)
 31#define BB				GENMASK(23, 16)
 32#define CC				GENMASK(15, 8)
 33#define DD				GENMASK(7, 0)
 34
 35#define MSIX_VECTORS			2
 36
 37struct sp_pci {
 38	int msix_count;
 39	struct msix_entry msix_entry[MSIX_VECTORS];
 40};
 41static struct sp_device *sp_dev_master;
 42
 43#define version_attribute_show(name, _offset)					\
 44static ssize_t name##_show(struct device *d, struct device_attribute *attr,	\
 45			   char *buf)						\
 46{										\
 47	struct sp_device *sp = dev_get_drvdata(d);				\
 48	struct psp_device *psp = sp->psp_data;					\
 49	unsigned int val = ioread32(psp->io_regs + _offset);			\
 50	return sysfs_emit(buf, "%02lx.%02lx.%02lx.%02lx\n",			\
 51			  FIELD_GET(AA, val),			\
 52			  FIELD_GET(BB, val),			\
 53			  FIELD_GET(CC, val),			\
 54			  FIELD_GET(DD, val));			\
 55}
 56
 57version_attribute_show(bootloader_version, psp->vdata->bootloader_info_reg)
 58static DEVICE_ATTR_RO(bootloader_version);
 59version_attribute_show(tee_version, psp->vdata->tee->info_reg)
 60static DEVICE_ATTR_RO(tee_version);
 61
 62static struct attribute *psp_firmware_attrs[] = {
 63	&dev_attr_bootloader_version.attr,
 64	&dev_attr_tee_version.attr,
 65	NULL,
 66};
 67
 68static umode_t psp_firmware_is_visible(struct kobject *kobj, struct attribute *attr, int idx)
 69{
 70	struct device *dev = kobj_to_dev(kobj);
 71	struct sp_device *sp = dev_get_drvdata(dev);
 72	struct psp_device *psp = sp->psp_data;
 73	unsigned int val = 0xffffffff;
 74
 75	if (!psp)
 76		return 0;
 77
 78	if (attr == &dev_attr_bootloader_version.attr &&
 79	    psp->vdata->bootloader_info_reg)
 80		val = ioread32(psp->io_regs + psp->vdata->bootloader_info_reg);
 81
 82	if (attr == &dev_attr_tee_version.attr && psp->capability.tee &&
 83	    psp->vdata->tee->info_reg)
 84		val = ioread32(psp->io_regs + psp->vdata->tee->info_reg);
 85
 86	/* If platform disallows accessing this register it will be all f's */
 87	if (val != 0xffffffff)
 88		return 0444;
 89
 90	return 0;
 91}
 92
 93static struct attribute_group psp_firmware_attr_group = {
 94	.attrs = psp_firmware_attrs,
 95	.is_visible = psp_firmware_is_visible,
 96};
 97
 98static const struct attribute_group *psp_groups[] = {
 99#ifdef CONFIG_CRYPTO_DEV_SP_PSP
100	&psp_security_attr_group,
101#endif
102	&psp_firmware_attr_group,
103	NULL,
104};
105
106static int sp_get_msix_irqs(struct sp_device *sp)
107{
108	struct sp_pci *sp_pci = sp->dev_specific;
109	struct device *dev = sp->dev;
110	struct pci_dev *pdev = to_pci_dev(dev);
111	int v, ret;
112
113	for (v = 0; v < ARRAY_SIZE(sp_pci->msix_entry); v++)
114		sp_pci->msix_entry[v].entry = v;
115
116	ret = pci_enable_msix_range(pdev, sp_pci->msix_entry, 1, v);
117	if (ret < 0)
118		return ret;
119
120	sp_pci->msix_count = ret;
121	sp->use_tasklet = true;
122
123	sp->psp_irq = sp_pci->msix_entry[0].vector;
124	sp->ccp_irq = (sp_pci->msix_count > 1) ? sp_pci->msix_entry[1].vector
125					       : sp_pci->msix_entry[0].vector;
126	return 0;
127}
128
129static int sp_get_msi_irq(struct sp_device *sp)
130{
131	struct device *dev = sp->dev;
132	struct pci_dev *pdev = to_pci_dev(dev);
133	int ret;
134
135	ret = pci_enable_msi(pdev);
136	if (ret)
137		return ret;
138
139	sp->ccp_irq = pdev->irq;
140	sp->psp_irq = pdev->irq;
141
142	return 0;
143}
144
145static int sp_get_irqs(struct sp_device *sp)
146{
147	struct device *dev = sp->dev;
148	int ret;
149
150	ret = sp_get_msix_irqs(sp);
151	if (!ret)
152		return 0;
153
154	/* Couldn't get MSI-X vectors, try MSI */
155	dev_notice(dev, "could not enable MSI-X (%d), trying MSI\n", ret);
156	ret = sp_get_msi_irq(sp);
157	if (!ret)
158		return 0;
159
160	/* Couldn't get MSI interrupt */
161	dev_notice(dev, "could not enable MSI (%d)\n", ret);
162
163	return ret;
164}
165
166static void sp_free_irqs(struct sp_device *sp)
167{
168	struct sp_pci *sp_pci = sp->dev_specific;
169	struct device *dev = sp->dev;
170	struct pci_dev *pdev = to_pci_dev(dev);
171
172	if (sp_pci->msix_count)
173		pci_disable_msix(pdev);
174	else if (sp->psp_irq)
175		pci_disable_msi(pdev);
176
177	sp->ccp_irq = 0;
178	sp->psp_irq = 0;
179}
180
181static bool sp_pci_is_master(struct sp_device *sp)
182{
183	struct device *dev_cur, *dev_new;
184	struct pci_dev *pdev_cur, *pdev_new;
185
186	dev_new = sp->dev;
187	dev_cur = sp_dev_master->dev;
188
189	pdev_new = to_pci_dev(dev_new);
190	pdev_cur = to_pci_dev(dev_cur);
191
192	if (pci_domain_nr(pdev_new->bus) != pci_domain_nr(pdev_cur->bus))
193		return pci_domain_nr(pdev_new->bus) < pci_domain_nr(pdev_cur->bus);
194
195	if (pdev_new->bus->number != pdev_cur->bus->number)
196		return pdev_new->bus->number < pdev_cur->bus->number;
197
198	if (PCI_SLOT(pdev_new->devfn) != PCI_SLOT(pdev_cur->devfn))
199		return PCI_SLOT(pdev_new->devfn) < PCI_SLOT(pdev_cur->devfn);
200
201	if (PCI_FUNC(pdev_new->devfn) != PCI_FUNC(pdev_cur->devfn))
202		return PCI_FUNC(pdev_new->devfn) < PCI_FUNC(pdev_cur->devfn);
203
204	return false;
205}
206
207static void psp_set_master(struct sp_device *sp)
208{
209	if (!sp_dev_master) {
210		sp_dev_master = sp;
211		return;
212	}
213
214	if (sp_pci_is_master(sp))
215		sp_dev_master = sp;
216}
217
218static struct sp_device *psp_get_master(void)
219{
220	return sp_dev_master;
221}
222
223static void psp_clear_master(struct sp_device *sp)
224{
225	if (sp == sp_dev_master) {
226		sp_dev_master = NULL;
227		dev_dbg(sp->dev, "Cleared sp_dev_master\n");
228	}
229}
230
231static int sp_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
232{
233	struct sp_device *sp;
234	struct sp_pci *sp_pci;
235	struct device *dev = &pdev->dev;
236	void __iomem * const *iomap_table;
237	int bar_mask;
238	int ret;
239
240	ret = -ENOMEM;
241	sp = sp_alloc_struct(dev);
242	if (!sp)
243		goto e_err;
244
245	sp_pci = devm_kzalloc(dev, sizeof(*sp_pci), GFP_KERNEL);
246	if (!sp_pci)
247		goto e_err;
248
249	sp->dev_specific = sp_pci;
250	sp->dev_vdata = (struct sp_dev_vdata *)id->driver_data;
251	if (!sp->dev_vdata) {
252		ret = -ENODEV;
253		dev_err(dev, "missing driver data\n");
254		goto e_err;
255	}
256
257	ret = pcim_enable_device(pdev);
258	if (ret) {
259		dev_err(dev, "pcim_enable_device failed (%d)\n", ret);
260		goto e_err;
261	}
262
263	bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
264	ret = pcim_iomap_regions(pdev, bar_mask, "ccp");
265	if (ret) {
266		dev_err(dev, "pcim_iomap_regions failed (%d)\n", ret);
267		goto e_err;
268	}
269
270	iomap_table = pcim_iomap_table(pdev);
271	if (!iomap_table) {
272		dev_err(dev, "pcim_iomap_table failed\n");
273		ret = -ENOMEM;
274		goto e_err;
275	}
276
277	sp->io_map = iomap_table[sp->dev_vdata->bar];
278	if (!sp->io_map) {
279		dev_err(dev, "ioremap failed\n");
280		ret = -ENOMEM;
281		goto e_err;
282	}
283
284	ret = sp_get_irqs(sp);
285	if (ret)
286		goto e_err;
287
288	pci_set_master(pdev);
289	sp->set_psp_master_device = psp_set_master;
290	sp->get_psp_master_device = psp_get_master;
291	sp->clear_psp_master_device = psp_clear_master;
292
293	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(48));
294	if (ret) {
295		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
296		if (ret) {
297			dev_err(dev, "dma_set_mask_and_coherent failed (%d)\n",
298				ret);
299			goto free_irqs;
300		}
301	}
302
303	dev_set_drvdata(dev, sp);
304
305	ret = sp_init(sp);
306	if (ret)
307		goto free_irqs;
308
309	return 0;
310
311free_irqs:
312	sp_free_irqs(sp);
313e_err:
314	dev_notice(dev, "initialization failed\n");
315	return ret;
316}
317
318static void sp_pci_shutdown(struct pci_dev *pdev)
319{
320	struct device *dev = &pdev->dev;
321	struct sp_device *sp = dev_get_drvdata(dev);
322
323	if (!sp)
324		return;
325
326	sp_destroy(sp);
327}
328
329static void sp_pci_remove(struct pci_dev *pdev)
330{
331	struct device *dev = &pdev->dev;
332	struct sp_device *sp = dev_get_drvdata(dev);
333
334	if (!sp)
335		return;
336
337	sp_destroy(sp);
338
339	sp_free_irqs(sp);
340}
341
342static int __maybe_unused sp_pci_suspend(struct device *dev)
343{
344	struct sp_device *sp = dev_get_drvdata(dev);
345
346	return sp_suspend(sp);
347}
348
349static int __maybe_unused sp_pci_resume(struct device *dev)
350{
351	struct sp_device *sp = dev_get_drvdata(dev);
352
353	return sp_resume(sp);
354}
355
356static int __maybe_unused sp_pci_restore(struct device *dev)
357{
358	struct sp_device *sp = dev_get_drvdata(dev);
359
360	return sp_restore(sp);
361}
362
363#ifdef CONFIG_CRYPTO_DEV_SP_PSP
364static const struct sev_vdata sevv1 = {
365	.cmdresp_reg		= 0x10580,	/* C2PMSG_32 */
366	.cmdbuff_addr_lo_reg	= 0x105e0,	/* C2PMSG_56 */
367	.cmdbuff_addr_hi_reg	= 0x105e4,	/* C2PMSG_57 */
368};
369
370static const struct sev_vdata sevv2 = {
371	.cmdresp_reg		= 0x10980,	/* C2PMSG_32 */
372	.cmdbuff_addr_lo_reg	= 0x109e0,	/* C2PMSG_56 */
373	.cmdbuff_addr_hi_reg	= 0x109e4,	/* C2PMSG_57 */
374};
375
376static const struct tee_vdata teev1 = {
377	.ring_wptr_reg          = 0x10550,	/* C2PMSG_20 */
378	.ring_rptr_reg          = 0x10554,	/* C2PMSG_21 */
379	.info_reg		= 0x109e8,	/* C2PMSG_58 */
380};
381
382static const struct tee_vdata teev2 = {
383	.ring_wptr_reg		= 0x10950,	/* C2PMSG_20 */
384	.ring_rptr_reg		= 0x10954,	/* C2PMSG_21 */
385	.info_reg		= 0x109e8,	/* C2PMSG_58 */
386};
387
388static const struct platform_access_vdata pa_v1 = {
389	.cmdresp_reg		= 0x10570,	/* C2PMSG_28 */
390	.cmdbuff_addr_lo_reg	= 0x10574,	/* C2PMSG_29 */
391	.cmdbuff_addr_hi_reg	= 0x10578,	/* C2PMSG_30 */
392	.doorbell_button_reg	= 0x10a24,	/* C2PMSG_73 */
393	.doorbell_cmd_reg	= 0x10a40,	/* C2PMSG_80 */
394};
395
396static const struct platform_access_vdata pa_v2 = {
397	.doorbell_button_reg	= 0x10a24,	/* C2PMSG_73 */
398	.doorbell_cmd_reg	= 0x10a40,	/* C2PMSG_80 */
399};
400
401static const struct psp_vdata pspv1 = {
402	.sev			= &sevv1,
403	.bootloader_info_reg	= 0x105ec,	/* C2PMSG_59 */
404	.feature_reg		= 0x105fc,	/* C2PMSG_63 */
405	.inten_reg		= 0x10610,	/* P2CMSG_INTEN */
406	.intsts_reg		= 0x10614,	/* P2CMSG_INTSTS */
407};
408
409static const struct psp_vdata pspv2 = {
410	.sev			= &sevv2,
411	.platform_access	= &pa_v1,
412	.bootloader_info_reg	= 0x109ec,	/* C2PMSG_59 */
413	.feature_reg		= 0x109fc,	/* C2PMSG_63 */
414	.inten_reg		= 0x10690,	/* P2CMSG_INTEN */
415	.intsts_reg		= 0x10694,	/* P2CMSG_INTSTS */
416	.platform_features	= PLATFORM_FEATURE_HSTI,
417};
418
419static const struct psp_vdata pspv3 = {
420	.tee			= &teev1,
421	.platform_access	= &pa_v1,
422	.cmdresp_reg		= 0x10544,	/* C2PMSG_17 */
423	.cmdbuff_addr_lo_reg	= 0x10548,	/* C2PMSG_18 */
424	.cmdbuff_addr_hi_reg	= 0x1054c,	/* C2PMSG_19 */
425	.bootloader_info_reg	= 0x109ec,	/* C2PMSG_59 */
426	.feature_reg		= 0x109fc,	/* C2PMSG_63 */
427	.inten_reg		= 0x10690,	/* P2CMSG_INTEN */
428	.intsts_reg		= 0x10694,	/* P2CMSG_INTSTS */
429	.platform_features	= PLATFORM_FEATURE_DBC |
430				  PLATFORM_FEATURE_HSTI,
431};
432
433static const struct psp_vdata pspv4 = {
434	.sev			= &sevv2,
435	.tee			= &teev1,
436	.cmdresp_reg		= 0x10544,	/* C2PMSG_17 */
437	.cmdbuff_addr_lo_reg	= 0x10548,	/* C2PMSG_18 */
438	.cmdbuff_addr_hi_reg	= 0x1054c,	/* C2PMSG_19 */
439	.bootloader_info_reg	= 0x109ec,	/* C2PMSG_59 */
440	.feature_reg		= 0x109fc,	/* C2PMSG_63 */
441	.inten_reg		= 0x10690,	/* P2CMSG_INTEN */
442	.intsts_reg		= 0x10694,	/* P2CMSG_INTSTS */
443};
444
445static const struct psp_vdata pspv5 = {
446	.tee			= &teev2,
447	.platform_access	= &pa_v2,
448	.cmdresp_reg		= 0x10944,	/* C2PMSG_17 */
449	.cmdbuff_addr_lo_reg	= 0x10948,	/* C2PMSG_18 */
450	.cmdbuff_addr_hi_reg	= 0x1094c,	/* C2PMSG_19 */
451	.bootloader_info_reg	= 0x109ec,	/* C2PMSG_59 */
452	.feature_reg		= 0x109fc,	/* C2PMSG_63 */
453	.inten_reg		= 0x10510,	/* P2CMSG_INTEN */
454	.intsts_reg		= 0x10514,	/* P2CMSG_INTSTS */
455};
456
457static const struct psp_vdata pspv6 = {
458	.sev                    = &sevv2,
459	.tee                    = &teev2,
460	.cmdresp_reg		= 0x10944,	/* C2PMSG_17 */
461	.cmdbuff_addr_lo_reg	= 0x10948,	/* C2PMSG_18 */
462	.cmdbuff_addr_hi_reg	= 0x1094c,	/* C2PMSG_19 */
463	.bootloader_info_reg	= 0x109ec,	/* C2PMSG_59 */
464	.feature_reg            = 0x109fc,	/* C2PMSG_63 */
465	.inten_reg              = 0x10510,	/* P2CMSG_INTEN */
466	.intsts_reg             = 0x10514,	/* P2CMSG_INTSTS */
467};
468
469static const struct psp_vdata pspv7 = {
470	.tee			= &teev2,
471	.cmdresp_reg		= 0x10944,	/* C2PMSG_17 */
472	.cmdbuff_addr_lo_reg	= 0x10948,	/* C2PMSG_18 */
473	.cmdbuff_addr_hi_reg	= 0x1094c,	/* C2PMSG_19 */
474	.bootloader_info_reg	= 0x109ec,	/* C2PMSG_59 */
475	.feature_reg		= 0x109fc,	/* C2PMSG_63 */
476	.inten_reg		= 0x10510,	/* P2CMSG_INTEN */
477	.intsts_reg		= 0x10514,	/* P2CMSG_INTSTS */
478};
479
480#endif
481
482static const struct sp_dev_vdata dev_vdata[] = {
483	{	/* 0 */
484		.bar = 2,
485#ifdef CONFIG_CRYPTO_DEV_SP_CCP
486		.ccp_vdata = &ccpv3,
487#endif
488	},
489	{	/* 1 */
490		.bar = 2,
491#ifdef CONFIG_CRYPTO_DEV_SP_CCP
492		.ccp_vdata = &ccpv5a,
493#endif
494#ifdef CONFIG_CRYPTO_DEV_SP_PSP
495		.psp_vdata = &pspv1,
496#endif
497	},
498	{	/* 2 */
499		.bar = 2,
500#ifdef CONFIG_CRYPTO_DEV_SP_CCP
501		.ccp_vdata = &ccpv5b,
502#endif
503	},
504	{	/* 3 */
505		.bar = 2,
506#ifdef CONFIG_CRYPTO_DEV_SP_CCP
507		.ccp_vdata = &ccpv5a,
508#endif
509#ifdef CONFIG_CRYPTO_DEV_SP_PSP
510		.psp_vdata = &pspv2,
511#endif
512	},
513	{	/* 4 */
514		.bar = 2,
515#ifdef CONFIG_CRYPTO_DEV_SP_CCP
516		.ccp_vdata = &ccpv5a,
517#endif
518#ifdef CONFIG_CRYPTO_DEV_SP_PSP
519		.psp_vdata = &pspv3,
520#endif
521	},
522	{	/* 5 */
523		.bar = 2,
524#ifdef CONFIG_CRYPTO_DEV_SP_PSP
525		.psp_vdata = &pspv4,
526#endif
527	},
528	{	/* 6 */
529		.bar = 2,
530#ifdef CONFIG_CRYPTO_DEV_SP_PSP
531		.psp_vdata = &pspv3,
532#endif
533	},
534	{	/* 7 */
535		.bar = 2,
536#ifdef CONFIG_CRYPTO_DEV_SP_PSP
537		.psp_vdata = &pspv5,
538#endif
539	},
540	{	/* 8 */
541		.bar = 2,
542#ifdef CONFIG_CRYPTO_DEV_SP_PSP
543		.psp_vdata = &pspv6,
544#endif
545	},
546	{	/* 9 */
547		.bar = 2,
548#ifdef CONFIG_CRYPTO_DEV_SP_PSP
549		.psp_vdata = &pspv7,
550#endif
551	},
552
553};
554static const struct pci_device_id sp_pci_table[] = {
555	{ PCI_VDEVICE(AMD, 0x1537), (kernel_ulong_t)&dev_vdata[0] },
556	{ PCI_VDEVICE(AMD, 0x1456), (kernel_ulong_t)&dev_vdata[1] },
557	{ PCI_VDEVICE(AMD, 0x1468), (kernel_ulong_t)&dev_vdata[2] },
558	{ PCI_VDEVICE(AMD, 0x1486), (kernel_ulong_t)&dev_vdata[3] },
559	{ PCI_VDEVICE(AMD, 0x15DF), (kernel_ulong_t)&dev_vdata[4] },
560	{ PCI_VDEVICE(AMD, 0x14CA), (kernel_ulong_t)&dev_vdata[5] },
561	{ PCI_VDEVICE(AMD, 0x15C7), (kernel_ulong_t)&dev_vdata[6] },
562	{ PCI_VDEVICE(AMD, 0x1649), (kernel_ulong_t)&dev_vdata[6] },
563	{ PCI_VDEVICE(AMD, 0x1134), (kernel_ulong_t)&dev_vdata[7] },
564	{ PCI_VDEVICE(AMD, 0x17E0), (kernel_ulong_t)&dev_vdata[7] },
565	{ PCI_VDEVICE(AMD, 0x156E), (kernel_ulong_t)&dev_vdata[8] },
566	{ PCI_VDEVICE(AMD, 0x17D8), (kernel_ulong_t)&dev_vdata[8] },
567	{ PCI_VDEVICE(AMD, 0x115A), (kernel_ulong_t)&dev_vdata[9] },
568	/* Last entry must be zero */
569	{ 0, }
570};
571MODULE_DEVICE_TABLE(pci, sp_pci_table);
572
573static const struct dev_pm_ops sp_pci_pm_ops = {
574	.suspend = pm_sleep_ptr(sp_pci_suspend),
575	.resume = pm_sleep_ptr(sp_pci_resume),
576	.freeze = pm_sleep_ptr(sp_pci_suspend),
577	.thaw = pm_sleep_ptr(sp_pci_resume),
578	.poweroff = pm_sleep_ptr(sp_pci_suspend),
579	.restore_early = pm_sleep_ptr(sp_pci_restore),
580};
581
582static struct pci_driver sp_pci_driver = {
583	.name = "ccp",
584	.id_table = sp_pci_table,
585	.probe = sp_pci_probe,
586	.remove = sp_pci_remove,
587	.shutdown = sp_pci_shutdown,
588	.driver.pm = &sp_pci_pm_ops,
589	.dev_groups = psp_groups,
590};
591
592int sp_pci_init(void)
593{
594	return pci_register_driver(&sp_pci_driver);
595}
596
597void sp_pci_exit(void)
598{
599	pci_unregister_driver(&sp_pci_driver);
600}
~/ Read-only file preview.