xref: /linux/drivers/crypto/ccp/psp-dev.c (revision b93566f1bb54e02a1ff1e3b4782073be1886744e)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * AMD Platform Security Processor (PSP) interface
4  *
5  * Copyright (C) 2016,2019 Advanced Micro Devices, Inc.
6  *
7  * Author: Brijesh Singh <brijesh.singh@amd.com>
8  */
9 
10 #include <linux/kernel.h>
11 #include <linux/irqreturn.h>
12 
13 #include "sp-dev.h"
14 #include "psp-dev.h"
15 #include "sev-dev.h"
16 
17 struct psp_device *psp_master;
18 
19 static struct psp_device *psp_alloc_struct(struct sp_device *sp)
20 {
21 	struct device *dev = sp->dev;
22 	struct psp_device *psp;
23 
24 	psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
25 	if (!psp)
26 		return NULL;
27 
28 	psp->dev = dev;
29 	psp->sp = sp;
30 
31 	snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
32 
33 	return psp;
34 }
35 
36 static irqreturn_t psp_irq_handler(int irq, void *data)
37 {
38 	struct psp_device *psp = data;
39 	unsigned int status;
40 
41 	/* Read the interrupt status: */
42 	status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
43 
44 	/* invoke subdevice interrupt handlers */
45 	if (status) {
46 		if (psp->sev_irq_handler)
47 			psp->sev_irq_handler(irq, psp->sev_irq_data, status);
48 	}
49 
50 	/* Clear the interrupt status by writing the same value we read. */
51 	iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
52 
53 	return IRQ_HANDLED;
54 }
55 
56 static int psp_check_sev_support(struct psp_device *psp)
57 {
58 	unsigned int val = ioread32(psp->io_regs + psp->vdata->feature_reg);
59 
60 	/*
61 	 * Check for a access to the registers.  If this read returns
62 	 * 0xffffffff, it's likely that the system is running a broken
63 	 * BIOS which disallows access to the device. Stop here and
64 	 * fail the PSP initialization (but not the load, as the CCP
65 	 * could get properly initialized).
66 	 */
67 	if (val == 0xffffffff) {
68 		dev_notice(psp->dev, "psp: unable to access the device: you might be running a broken BIOS.\n");
69 		return -ENODEV;
70 	}
71 
72 	if (!(val & 1)) {
73 		/* Device does not support the SEV feature */
74 		dev_dbg(psp->dev, "psp does not support SEV\n");
75 		return -ENODEV;
76 	}
77 
78 	return 0;
79 }
80 
81 int psp_dev_init(struct sp_device *sp)
82 {
83 	struct device *dev = sp->dev;
84 	struct psp_device *psp;
85 	int ret;
86 
87 	ret = -ENOMEM;
88 	psp = psp_alloc_struct(sp);
89 	if (!psp)
90 		goto e_err;
91 
92 	sp->psp_data = psp;
93 
94 	psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
95 	if (!psp->vdata) {
96 		ret = -ENODEV;
97 		dev_err(dev, "missing driver data\n");
98 		goto e_err;
99 	}
100 
101 	psp->io_regs = sp->io_map;
102 
103 	ret = psp_check_sev_support(psp);
104 	if (ret)
105 		goto e_disable;
106 
107 	/* Disable and clear interrupts until ready */
108 	iowrite32(0, psp->io_regs + psp->vdata->inten_reg);
109 	iowrite32(-1, psp->io_regs + psp->vdata->intsts_reg);
110 
111 	/* Request an irq */
112 	ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
113 	if (ret) {
114 		dev_err(dev, "psp: unable to allocate an IRQ\n");
115 		goto e_err;
116 	}
117 
118 	ret = sev_dev_init(psp);
119 	if (ret)
120 		goto e_irq;
121 
122 	if (sp->set_psp_master_device)
123 		sp->set_psp_master_device(sp);
124 
125 	/* Enable interrupt */
126 	iowrite32(-1, psp->io_regs + psp->vdata->inten_reg);
127 
128 	dev_notice(dev, "psp enabled\n");
129 
130 	return 0;
131 
132 e_irq:
133 	sp_free_psp_irq(psp->sp, psp);
134 e_err:
135 	sp->psp_data = NULL;
136 
137 	dev_notice(dev, "psp initialization failed\n");
138 
139 	return ret;
140 
141 e_disable:
142 	sp->psp_data = NULL;
143 
144 	return ret;
145 }
146 
147 void psp_dev_destroy(struct sp_device *sp)
148 {
149 	struct psp_device *psp = sp->psp_data;
150 
151 	if (!psp)
152 		return;
153 
154 	sev_dev_destroy(psp);
155 
156 	sp_free_psp_irq(sp, psp);
157 }
158 
159 void psp_set_sev_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
160 			     void *data)
161 {
162 	psp->sev_irq_data = data;
163 	psp->sev_irq_handler = handler;
164 }
165 
166 void psp_clear_sev_irq_handler(struct psp_device *psp)
167 {
168 	psp_set_sev_irq_handler(psp, NULL, NULL);
169 }
170 
171 struct psp_device *psp_get_master_device(void)
172 {
173 	struct sp_device *sp = sp_get_psp_master_device();
174 
175 	return sp ? sp->psp_data : NULL;
176 }
177 
178 void psp_pci_init(void)
179 {
180 	psp_master = psp_get_master_device();
181 
182 	if (!psp_master)
183 		return;
184 
185 	sev_pci_init();
186 }
187 
188 void psp_pci_exit(void)
189 {
190 	if (!psp_master)
191 		return;
192 
193 	sev_pci_exit();
194 }
195