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