xref: /openbmc/linux/drivers/crypto/ccp/psp-dev.c (revision c6fddb28)
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 #include "tee-dev.h"
17 
18 struct psp_device *psp_master;
19 
20 static struct psp_device *psp_alloc_struct(struct sp_device *sp)
21 {
22 	struct device *dev = sp->dev;
23 	struct psp_device *psp;
24 
25 	psp = devm_kzalloc(dev, sizeof(*psp), GFP_KERNEL);
26 	if (!psp)
27 		return NULL;
28 
29 	psp->dev = dev;
30 	psp->sp = sp;
31 
32 	snprintf(psp->name, sizeof(psp->name), "psp-%u", sp->ord);
33 
34 	return psp;
35 }
36 
37 static irqreturn_t psp_irq_handler(int irq, void *data)
38 {
39 	struct psp_device *psp = data;
40 	unsigned int status;
41 
42 	/* Read the interrupt status: */
43 	status = ioread32(psp->io_regs + psp->vdata->intsts_reg);
44 
45 	/* invoke subdevice interrupt handlers */
46 	if (status) {
47 		if (psp->sev_irq_handler)
48 			psp->sev_irq_handler(irq, psp->sev_irq_data, status);
49 
50 		if (psp->tee_irq_handler)
51 			psp->tee_irq_handler(irq, psp->tee_irq_data, status);
52 	}
53 
54 	/* Clear the interrupt status by writing the same value we read. */
55 	iowrite32(status, psp->io_regs + psp->vdata->intsts_reg);
56 
57 	return IRQ_HANDLED;
58 }
59 
60 static unsigned int psp_get_capability(struct psp_device *psp)
61 {
62 	unsigned int val = ioread32(psp->io_regs + psp->vdata->feature_reg);
63 
64 	/*
65 	 * Check for a access to the registers.  If this read returns
66 	 * 0xffffffff, it's likely that the system is running a broken
67 	 * BIOS which disallows access to the device. Stop here and
68 	 * fail the PSP initialization (but not the load, as the CCP
69 	 * could get properly initialized).
70 	 */
71 	if (val == 0xffffffff) {
72 		dev_notice(psp->dev, "psp: unable to access the device: you might be running a broken BIOS.\n");
73 		return 0;
74 	}
75 
76 	return val;
77 }
78 
79 static int psp_check_sev_support(struct psp_device *psp,
80 				 unsigned int capability)
81 {
82 	/* Check if device supports SEV feature */
83 	if (!(capability & 1)) {
84 		dev_dbg(psp->dev, "psp does not support SEV\n");
85 		return -ENODEV;
86 	}
87 
88 	return 0;
89 }
90 
91 static int psp_check_tee_support(struct psp_device *psp,
92 				 unsigned int capability)
93 {
94 	/* Check if device supports TEE feature */
95 	if (!(capability & 2)) {
96 		dev_dbg(psp->dev, "psp does not support TEE\n");
97 		return -ENODEV;
98 	}
99 
100 	return 0;
101 }
102 
103 static int psp_check_support(struct psp_device *psp,
104 			     unsigned int capability)
105 {
106 	int sev_support = psp_check_sev_support(psp, capability);
107 	int tee_support = psp_check_tee_support(psp, capability);
108 
109 	/* Return error if device neither supports SEV nor TEE */
110 	if (sev_support && tee_support)
111 		return -ENODEV;
112 
113 	return 0;
114 }
115 
116 static int psp_init(struct psp_device *psp, unsigned int capability)
117 {
118 	int ret;
119 
120 	if (!psp_check_sev_support(psp, capability)) {
121 		ret = sev_dev_init(psp);
122 		if (ret)
123 			return ret;
124 	}
125 
126 	if (!psp_check_tee_support(psp, capability)) {
127 		ret = tee_dev_init(psp);
128 		if (ret)
129 			return ret;
130 	}
131 
132 	return 0;
133 }
134 
135 int psp_dev_init(struct sp_device *sp)
136 {
137 	struct device *dev = sp->dev;
138 	struct psp_device *psp;
139 	unsigned int capability;
140 	int ret;
141 
142 	ret = -ENOMEM;
143 	psp = psp_alloc_struct(sp);
144 	if (!psp)
145 		goto e_err;
146 
147 	sp->psp_data = psp;
148 
149 	psp->vdata = (struct psp_vdata *)sp->dev_vdata->psp_vdata;
150 	if (!psp->vdata) {
151 		ret = -ENODEV;
152 		dev_err(dev, "missing driver data\n");
153 		goto e_err;
154 	}
155 
156 	psp->io_regs = sp->io_map;
157 
158 	capability = psp_get_capability(psp);
159 	if (!capability)
160 		goto e_disable;
161 
162 	ret = psp_check_support(psp, capability);
163 	if (ret)
164 		goto e_disable;
165 
166 	/* Disable and clear interrupts until ready */
167 	iowrite32(0, psp->io_regs + psp->vdata->inten_reg);
168 	iowrite32(-1, psp->io_regs + psp->vdata->intsts_reg);
169 
170 	/* Request an irq */
171 	ret = sp_request_psp_irq(psp->sp, psp_irq_handler, psp->name, psp);
172 	if (ret) {
173 		dev_err(dev, "psp: unable to allocate an IRQ\n");
174 		goto e_err;
175 	}
176 
177 	ret = psp_init(psp, capability);
178 	if (ret)
179 		goto e_irq;
180 
181 	if (sp->set_psp_master_device)
182 		sp->set_psp_master_device(sp);
183 
184 	/* Enable interrupt */
185 	iowrite32(-1, psp->io_regs + psp->vdata->inten_reg);
186 
187 	dev_notice(dev, "psp enabled\n");
188 
189 	return 0;
190 
191 e_irq:
192 	sp_free_psp_irq(psp->sp, psp);
193 e_err:
194 	sp->psp_data = NULL;
195 
196 	dev_notice(dev, "psp initialization failed\n");
197 
198 	return ret;
199 
200 e_disable:
201 	sp->psp_data = NULL;
202 
203 	return ret;
204 }
205 
206 void psp_dev_destroy(struct sp_device *sp)
207 {
208 	struct psp_device *psp = sp->psp_data;
209 
210 	if (!psp)
211 		return;
212 
213 	sev_dev_destroy(psp);
214 
215 	tee_dev_destroy(psp);
216 
217 	sp_free_psp_irq(sp, psp);
218 
219 	if (sp->clear_psp_master_device)
220 		sp->clear_psp_master_device(sp);
221 }
222 
223 void psp_set_sev_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
224 			     void *data)
225 {
226 	psp->sev_irq_data = data;
227 	psp->sev_irq_handler = handler;
228 }
229 
230 void psp_clear_sev_irq_handler(struct psp_device *psp)
231 {
232 	psp_set_sev_irq_handler(psp, NULL, NULL);
233 }
234 
235 void psp_set_tee_irq_handler(struct psp_device *psp, psp_irq_handler_t handler,
236 			     void *data)
237 {
238 	psp->tee_irq_data = data;
239 	psp->tee_irq_handler = handler;
240 }
241 
242 void psp_clear_tee_irq_handler(struct psp_device *psp)
243 {
244 	psp_set_tee_irq_handler(psp, NULL, NULL);
245 }
246 
247 struct psp_device *psp_get_master_device(void)
248 {
249 	struct sp_device *sp = sp_get_psp_master_device();
250 
251 	return sp ? sp->psp_data : NULL;
252 }
253 
254 void psp_pci_init(void)
255 {
256 	psp_master = psp_get_master_device();
257 
258 	if (!psp_master)
259 		return;
260 
261 	sev_pci_init();
262 }
263 
264 void psp_pci_exit(void)
265 {
266 	if (!psp_master)
267 		return;
268 
269 	sev_pci_exit();
270 }
271