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