xref: /openbsd/sys/dev/ic/psp.c (revision 45c4fed2)
1 /*	$OpenBSD: psp.c,v 1.14 2024/11/10 06:51:59 jsg Exp $ */
2 
3 /*
4  * Copyright (c) 2023, 2024 Hans-Joerg Hoexer <hshoexer@genua.de>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/param.h>
20 #include <sys/systm.h>
21 #include <sys/device.h>
22 #include <sys/malloc.h>
23 #include <sys/mutex.h>
24 #include <sys/pledge.h>
25 #include <sys/proc.h>
26 #include <sys/rwlock.h>
27 
28 #include <machine/bus.h>
29 
30 #include <uvm/uvm_extern.h>
31 #include <crypto/xform.h>
32 
33 #include <dev/ic/ccpvar.h>
34 #include <dev/ic/pspvar.h>
35 
36 struct psp_softc {
37 	struct device		sc_dev;
38 	bus_space_tag_t		sc_iot;
39 	bus_space_handle_t	sc_ioh;
40 
41 	bus_dma_tag_t		sc_dmat;
42 
43 	bus_size_t		sc_reg_inten;
44 	bus_size_t		sc_reg_intsts;
45 	bus_size_t		sc_reg_cmdresp;
46 	bus_size_t		sc_reg_addrlo;
47 	bus_size_t		sc_reg_addrhi;
48 
49 	bus_dmamap_t		sc_cmd_map;
50 	bus_dma_segment_t	sc_cmd_seg;
51 	size_t			sc_cmd_size;
52 	caddr_t			sc_cmd_kva;
53 
54 	bus_dmamap_t		sc_tmr_map;
55 	bus_dma_segment_t	sc_tmr_seg;
56 	size_t			sc_tmr_size;
57 	caddr_t			sc_tmr_kva;
58 
59 	struct rwlock		sc_lock;
60 	struct mutex		psp_lock;
61 
62 	uint32_t		sc_flags;
63 #define PSPF_INITIALIZED	0x1
64 #define PSPF_UCODELOADED	0x2
65 #define PSPF_NOUCODE		0x4
66 
67 	u_char			*sc_ucodebuf;
68 	size_t			sc_ucodelen;
69 };
70 
71 int	psp_get_pstatus(struct psp_softc *, struct psp_platform_status *);
72 int	psp_init(struct psp_softc *, struct psp_init *);
73 int	psp_reinit(struct psp_softc *);
74 int	psp_match(struct device *, void *, void *);
75 void	psp_attach(struct device *, struct device *, void *);
76 void	psp_load_ucode(struct psp_softc *);
77 
78 struct cfdriver psp_cd = {
79 	NULL, "psp", DV_DULL
80 };
81 
82 const struct cfattach psp_ca = {
83 	sizeof(struct psp_softc),
84 	psp_match,
85 	psp_attach
86 };
87 
88 int
psp_sev_intr(void * arg)89 psp_sev_intr(void *arg)
90 {
91 	struct ccp_softc *csc = arg;
92 	struct psp_softc *sc = (struct psp_softc *)csc->sc_psp;
93 	uint32_t status;
94 
95 	mtx_enter(&sc->psp_lock);
96 	status = bus_space_read_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_intsts);
97 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_intsts, status);
98 	mtx_leave(&sc->psp_lock);
99 
100 	if (!(status & PSP_CMDRESP_COMPLETE))
101 		return (0);
102 
103 	wakeup(sc);
104 
105 	return (1);
106 }
107 
108 int
psp_match(struct device * parent,void * match,void * aux)109 psp_match(struct device *parent, void *match, void *aux)
110 {
111 	return (1);
112 }
113 
114 void
psp_attach(struct device * parent,struct device * self,void * aux)115 psp_attach(struct device *parent, struct device *self, void *aux)
116 {
117 	struct psp_softc		*sc = (struct psp_softc *)self;
118 	struct psp_attach_args		*arg = aux;
119 	struct psp_platform_status	pst;
120 	size_t				size;
121 	int				nsegs;
122 
123 	printf(":");
124 	sc->sc_iot = arg->iot;
125 	sc->sc_ioh = arg->ioh;
126 	sc->sc_dmat = arg->dmat;
127 	if (arg->version == 1) {
128 		sc->sc_reg_inten = PSPV1_REG_INTEN;
129 		sc->sc_reg_intsts = PSPV1_REG_INTSTS;
130 		sc->sc_reg_cmdresp = PSPV1_REG_CMDRESP;
131 		sc->sc_reg_addrlo = PSPV1_REG_ADDRLO;
132 		sc->sc_reg_addrhi = PSPV1_REG_ADDRHI;
133 	} else {
134 		sc->sc_reg_inten = PSP_REG_INTEN;
135 		sc->sc_reg_intsts = PSP_REG_INTSTS;
136 		sc->sc_reg_cmdresp = PSP_REG_CMDRESP;
137 		sc->sc_reg_addrlo = PSP_REG_ADDRLO;
138 		sc->sc_reg_addrhi = PSP_REG_ADDRHI;
139 	}
140 	if (arg->version)
141 		printf(" vers %d,", arg->version);
142 
143 	rw_init(&sc->sc_lock, "psp_lock");
144 	mtx_init(&sc->psp_lock, IPL_BIO);
145 
146 	/* create and map SEV command buffer */
147 	sc->sc_cmd_size = size = PAGE_SIZE;
148 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
149 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
150 	    &sc->sc_cmd_map) != 0)
151 		return;
152 
153 	if (bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_cmd_seg, 1,
154 	    &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0)
155 		goto fail_0;
156 
157 	if (bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_seg, nsegs, size,
158 	    &sc->sc_cmd_kva, BUS_DMA_WAITOK) != 0)
159 		goto fail_1;
160 
161 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_map, sc->sc_cmd_kva,
162 	    size, NULL, BUS_DMA_WAITOK) != 0)
163 		goto fail_2;
164 
165 	if (psp_get_pstatus(sc, &pst)) {
166 		printf(" platform status");
167 		goto fail_3;
168 	}
169 	if (pst.state != PSP_PSTATE_UNINIT) {
170 		printf(" uninitialized state");
171 		goto fail_3;
172 	}
173 	printf(" api %u.%u, build %u, SEV, SEV-ES",
174 	    pst.api_major, pst.api_minor, pst.cfges_build >> 24);
175 
176 	/* enable interrupts */
177 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_inten, -1);
178 
179 	printf("\n");
180 
181 	return;
182 
183 fail_3:
184 	bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_map);
185 fail_2:
186 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_cmd_kva, size);
187 fail_1:
188 	bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_seg, 1);
189 fail_0:
190 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmd_map);
191 
192 	printf(" failed\n");
193 
194 	return;
195 }
196 
197 static int
ccp_wait(struct psp_softc * sc,uint32_t * status,int poll)198 ccp_wait(struct psp_softc *sc, uint32_t *status, int poll)
199 {
200 	uint32_t	cmdword;
201 	int		count;
202 
203 	MUTEX_ASSERT_LOCKED(&sc->psp_lock);
204 
205 	if (poll) {
206 		count = 0;
207 		while (count++ < 400) {
208 			cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
209 			    sc->sc_reg_cmdresp);
210 			if (cmdword & PSP_CMDRESP_RESPONSE)
211 				goto done;
212 			delay(5000);
213 		}
214 
215 		/* timeout */
216 		return (1);
217 	}
218 
219 	if (msleep_nsec(sc, &sc->psp_lock, PWAIT, "psp", SEC_TO_NSEC(2))
220 	    == EWOULDBLOCK)
221 		return (1);
222 
223 	cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp);
224 done:
225 	if (status != NULL)
226 		*status = cmdword;
227 	return (0);
228 }
229 
230 static int
ccp_docmd(struct psp_softc * sc,int cmd,uint64_t paddr)231 ccp_docmd(struct psp_softc *sc, int cmd, uint64_t paddr)
232 {
233 	uint32_t	plo, phi, cmdword, status;
234 	int		ret;
235 
236 	plo = ((paddr >> 0) & 0xffffffff);
237 	phi = ((paddr >> 32) & 0xffffffff);
238 	cmdword = (cmd & 0x3ff) << 16;
239 	if (!cold)
240 		cmdword |= PSP_CMDRESP_IOC;
241 
242 	mtx_enter(&sc->psp_lock);
243 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_addrlo, plo);
244 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_addrhi, phi);
245 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp, cmdword);
246 
247 	ret = ccp_wait(sc, &status, cold);
248 	mtx_leave(&sc->psp_lock);
249 	if (ret)
250 		return (1);
251 
252 	/* Did PSP sent a response code? */
253 	if (status & PSP_CMDRESP_RESPONSE) {
254 		if ((status & PSP_STATUS_MASK) != PSP_STATUS_SUCCESS)
255 			return (1);
256 	}
257 
258 	return (0);
259 }
260 
261 int
psp_init(struct psp_softc * sc,struct psp_init * uinit)262 psp_init(struct psp_softc *sc, struct psp_init *uinit)
263 {
264 	struct psp_init		*init;
265 	int			 ret;
266 
267 	init = (struct psp_init *)sc->sc_cmd_kva;
268 	bzero(init, sizeof(*init));
269 
270 	init->enable_es = uinit->enable_es;
271 	init->tmr_paddr = uinit->tmr_paddr;
272 	init->tmr_length = uinit->tmr_length;
273 
274 	ret = ccp_docmd(sc, PSP_CMD_INIT, sc->sc_cmd_map->dm_segs[0].ds_addr);
275 	if (ret != 0)
276 		return (EIO);
277 
278 	wbinvd_on_all_cpus_acked();
279 
280 	sc->sc_flags |= PSPF_INITIALIZED;
281 
282 	return (0);
283 }
284 
285 int
psp_reinit(struct psp_softc * sc)286 psp_reinit(struct psp_softc *sc)
287 {
288 	struct psp_init	init;
289 	size_t		size;
290 	int		nsegs;
291 
292 	if (sc->sc_flags & PSPF_INITIALIZED) {
293 		printf("%s: invalid flags 0x%x\n", __func__, sc->sc_flags);
294 		return (EINVAL);
295 	}
296 
297 	if (sc->sc_tmr_map != NULL)
298 		return (EINVAL);
299 
300 	/*
301 	 * create and map Trusted Memory Region (TMR); size 1 Mbyte,
302 	 * needs to be aligend to 1 Mbyte.
303 	 */
304 	sc->sc_tmr_size = size = PSP_TMR_SIZE;
305 	if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
306 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT,
307 	    &sc->sc_tmr_map) != 0)
308 		return (ENOMEM);
309 
310 	if (bus_dmamem_alloc(sc->sc_dmat, size, size, 0, &sc->sc_tmr_seg, 1,
311 	    &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0)
312 		goto fail_0;
313 
314 	if (bus_dmamem_map(sc->sc_dmat, &sc->sc_tmr_seg, nsegs, size,
315 	    &sc->sc_tmr_kva, BUS_DMA_WAITOK) != 0)
316 		goto fail_1;
317 
318 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_tmr_map, sc->sc_tmr_kva,
319 	    size, NULL, BUS_DMA_WAITOK) != 0)
320 		goto fail_2;
321 
322 	memset(&init, 0, sizeof(init));
323 	init.enable_es = 1;
324 	init.tmr_length = PSP_TMR_SIZE;
325 	init.tmr_paddr = sc->sc_tmr_map->dm_segs[0].ds_addr;
326 	if (psp_init(sc, &init))
327 		goto fail_3;
328 
329 	return (0);
330 
331 fail_3:
332 	bus_dmamap_unload(sc->sc_dmat, sc->sc_tmr_map);
333 fail_2:
334 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_tmr_kva, size);
335 fail_1:
336 	bus_dmamem_free(sc->sc_dmat, &sc->sc_tmr_seg, 1);
337 fail_0:
338 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_tmr_map);
339 
340 	return (ENOMEM);
341 }
342 
343 int
psp_shutdown(struct psp_softc * sc)344 psp_shutdown(struct psp_softc *sc)
345 {
346 	int ret;
347 
348 	if (sc->sc_tmr_map == NULL)
349 		return (EINVAL);
350 
351 	ret = ccp_docmd(sc, PSP_CMD_SHUTDOWN, 0x0);
352 
353 	if (ret != 0)
354 		return (EIO);
355 
356 	/* wbinvd right after SHUTDOWN */
357 	wbinvd_on_all_cpus_acked();
358 
359 	/* release TMR */
360 	bus_dmamap_unload(sc->sc_dmat, sc->sc_tmr_map);
361 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_tmr_kva, sc->sc_tmr_size);
362 	bus_dmamem_free(sc->sc_dmat, &sc->sc_tmr_seg, 1);
363 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_tmr_map);
364 	sc->sc_tmr_map = NULL;
365 
366 	/* reset flags */
367 	sc->sc_flags = 0;
368 
369 	return (0);
370 }
371 
372 int
psp_get_pstatus(struct psp_softc * sc,struct psp_platform_status * ustatus)373 psp_get_pstatus(struct psp_softc *sc, struct psp_platform_status *ustatus)
374 {
375 	struct psp_platform_status *status;
376 	int			 ret;
377 
378 	status = (struct psp_platform_status *)sc->sc_cmd_kva;
379 	bzero(status, sizeof(*status));
380 
381 	ret = ccp_docmd(sc, PSP_CMD_PLATFORMSTATUS,
382 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
383 
384 	if (ret != 0)
385 		return (EIO);
386 
387 	bcopy(status, ustatus, sizeof(*ustatus));
388 
389 	return (0);
390 }
391 
392 int
psp_df_flush(struct psp_softc * sc)393 psp_df_flush(struct psp_softc *sc)
394 {
395 	int			 ret;
396 
397 	wbinvd_on_all_cpus_acked();
398 
399 	ret = ccp_docmd(sc, PSP_CMD_DF_FLUSH, 0x0);
400 
401 	if (ret != 0)
402 		return (EIO);
403 
404 	return (0);
405 }
406 
407 int
psp_decommission(struct psp_softc * sc,struct psp_decommission * udecom)408 psp_decommission(struct psp_softc *sc, struct psp_decommission *udecom)
409 {
410 	struct psp_decommission	*decom;
411 	int			 ret;
412 
413 	decom = (struct psp_decommission *)sc->sc_cmd_kva;
414 	bzero(decom, sizeof(*decom));
415 
416 	decom->handle = udecom->handle;
417 
418 	ret = ccp_docmd(sc, PSP_CMD_DECOMMISSION,
419 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
420 
421 	if (ret != 0)
422 		return (EIO);
423 
424 	return (0);
425 }
426 
427 int
psp_get_gstatus(struct psp_softc * sc,struct psp_guest_status * ustatus)428 psp_get_gstatus(struct psp_softc *sc, struct psp_guest_status *ustatus)
429 {
430 	struct psp_guest_status	*status;
431 	int			 ret;
432 
433 	status = (struct psp_guest_status *)sc->sc_cmd_kva;
434 	bzero(status, sizeof(*status));
435 
436 	status->handle = ustatus->handle;
437 
438 	ret = ccp_docmd(sc, PSP_CMD_GUESTSTATUS,
439 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
440 
441 	if (ret != 0)
442 		return (EIO);
443 
444 	ustatus->policy = status->policy;
445 	ustatus->asid = status->asid;
446 	ustatus->state = status->state;
447 
448 	return (0);
449 }
450 
451 int
psp_launch_start(struct psp_softc * sc,struct psp_launch_start * ustart)452 psp_launch_start(struct psp_softc *sc, struct psp_launch_start *ustart)
453 {
454 	struct psp_launch_start	*start;
455 	int			 ret;
456 
457 	start = (struct psp_launch_start *)sc->sc_cmd_kva;
458 	bzero(start, sizeof(*start));
459 
460 	start->handle = ustart->handle;
461 	start->policy = ustart->policy;
462 
463 	ret = ccp_docmd(sc, PSP_CMD_LAUNCH_START,
464 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
465 
466 	if (ret != 0)
467 		return (EIO);
468 
469 	/* If requested, return new handle. */
470 	if (ustart->handle == 0)
471 		ustart->handle = start->handle;
472 
473 	return (0);
474 }
475 
476 int
psp_launch_update_data(struct psp_softc * sc,struct psp_launch_update_data * ulud,struct proc * p)477 psp_launch_update_data(struct psp_softc *sc,
478     struct psp_launch_update_data *ulud, struct proc *p)
479 {
480 	struct psp_launch_update_data	*ludata;
481 	pmap_t				 pmap;
482 	vaddr_t				 v, next, start, end;
483 	size_t				 size, len, off;
484 	int				 ret;
485 
486 	/* Ensure AES_XTS_BLOCKSIZE alignment and multiplicity. */
487 	if ((ulud->paddr & (AES_XTS_BLOCKSIZE - 1)) != 0 ||
488 	    (ulud->length % AES_XTS_BLOCKSIZE) != 0)
489 		return (EINVAL);
490 
491 	ludata = (struct psp_launch_update_data *)sc->sc_cmd_kva;
492 	bzero(ludata, sizeof(*ludata));
493 
494 	ludata->handle = ulud->handle;
495 
496 	/* Drain caches before we encrypt memory. */
497 	wbinvd_on_all_cpus_acked();
498 
499 	/*
500 	 * Launch update one physical page at a time.  We could
501 	 * optimise this for contiguous pages of physical memory.
502 	 *
503 	 * vmd(8) provides the guest physical address, thus convert
504 	 * to system physical address.
505 	 */
506 	pmap = vm_map_pmap(&p->p_vmspace->vm_map);
507 	start = ulud->paddr;
508 	size = ulud->length;
509 	end = start + size;
510 
511 	ret = EINVAL;
512 
513 	/* Wire mapping. */
514 	if (uvm_map_pageable(&p->p_vmspace->vm_map, start, end, FALSE, 0))
515 		goto out;
516 
517 	for (v = ulud->paddr; v < end; v = next) {
518 		off = v & PAGE_MASK;
519 
520 		len = MIN(PAGE_SIZE - off, size);
521 
522 		if (!pmap_extract(pmap, v, (paddr_t *)&ludata->paddr))
523 			goto out;
524 		ludata->length = len;
525 
526 		ret = ccp_docmd(sc, PSP_CMD_LAUNCH_UPDATE_DATA,
527 		    sc->sc_cmd_map->dm_segs[0].ds_addr);
528 
529 		if (ret != 0) {
530 			ret = EIO;
531 			goto out;
532 		}
533 
534 		size -= len;
535 		next = v + len;
536 	}
537 
538 out:
539 	/* Unwire again. */
540 	if (uvm_map_pageable(&p->p_vmspace->vm_map, start, end, TRUE, 0))
541 		return (EINVAL);
542 
543 	return (ret);
544 }
545 
546 int
psp_launch_measure(struct psp_softc * sc,struct psp_launch_measure * ulm)547 psp_launch_measure(struct psp_softc *sc, struct psp_launch_measure *ulm)
548 {
549 	struct psp_launch_measure *lm;
550 	int			 ret;
551 	uint64_t		 paddr;
552 
553 	if (ulm->measure_len != sizeof(ulm->psp_measure))
554 		return (EINVAL);
555 
556 	lm = (struct psp_launch_measure *)sc->sc_cmd_kva;
557 	bzero(lm, sizeof(*lm));
558 
559 	lm->handle = ulm->handle;
560 	paddr = sc->sc_cmd_map->dm_segs[0].ds_addr;
561 	lm->measure_paddr =
562 	    paddr + offsetof(struct psp_launch_measure, psp_measure);
563 	lm->measure_len = sizeof(lm->psp_measure);
564 
565 	ret = ccp_docmd(sc, PSP_CMD_LAUNCH_MEASURE, paddr);
566 
567 	if (ret != 0 || lm->measure_len != ulm->measure_len)
568 		return (EIO);
569 
570 	bcopy(&lm->psp_measure, &ulm->psp_measure, ulm->measure_len);
571 
572 	return (0);
573 }
574 
575 int
psp_launch_finish(struct psp_softc * sc,struct psp_launch_finish * ulf)576 psp_launch_finish(struct psp_softc *sc, struct psp_launch_finish *ulf)
577 {
578 	struct psp_launch_finish *lf;
579 	int			 ret;
580 
581 	lf = (struct psp_launch_finish *)sc->sc_cmd_kva;
582 	bzero(lf, sizeof(*lf));
583 
584 	lf->handle = ulf->handle;
585 
586 	ret = ccp_docmd(sc, PSP_CMD_LAUNCH_FINISH,
587 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
588 
589 	if (ret != 0)
590 		return (EIO);
591 
592 	return (0);
593 }
594 
595 int
psp_attestation(struct psp_softc * sc,struct psp_attestation * uat)596 psp_attestation(struct psp_softc *sc, struct psp_attestation *uat)
597 {
598 	struct psp_attestation	*at;
599 	int			 ret;
600 	uint64_t		 paddr;
601 
602 	if (uat->attest_len != sizeof(uat->psp_report))
603 		return (EINVAL);
604 
605 	at = (struct psp_attestation *)sc->sc_cmd_kva;
606 	bzero(at, sizeof(*at));
607 
608 	at->handle = uat->handle;
609 	paddr = sc->sc_cmd_map->dm_segs[0].ds_addr;
610 	at->attest_paddr =
611 	    paddr + offsetof(struct psp_attestation, psp_report);
612 	bcopy(uat->attest_nonce, at->attest_nonce, sizeof(at->attest_nonce));
613 	at->attest_len = sizeof(at->psp_report);
614 
615 	ret = ccp_docmd(sc, PSP_CMD_ATTESTATION, paddr);
616 
617 	if (ret != 0 || at->attest_len != uat->attest_len)
618 		return (EIO);
619 
620 	bcopy(&at->psp_report, &uat->psp_report, uat->attest_len);
621 
622 	return (0);
623 }
624 
625 int
psp_activate(struct psp_softc * sc,struct psp_activate * uact)626 psp_activate(struct psp_softc *sc, struct psp_activate *uact)
627 {
628 	struct psp_activate	*act;
629 	int			 ret;
630 
631 	act = (struct psp_activate *)sc->sc_cmd_kva;
632 	bzero(act, sizeof(*act));
633 
634 	act->handle = uact->handle;
635 	act->asid = uact->asid;
636 
637 	ret = ccp_docmd(sc, PSP_CMD_ACTIVATE,
638 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
639 
640 	if (ret != 0)
641 		return (EIO);
642 
643 	return (0);
644 }
645 
646 int
psp_deactivate(struct psp_softc * sc,struct psp_deactivate * udeact)647 psp_deactivate(struct psp_softc *sc, struct psp_deactivate *udeact)
648 {
649 	struct psp_deactivate	*deact;
650 	int			 ret;
651 
652 	deact = (struct psp_deactivate *)sc->sc_cmd_kva;
653 	bzero(deact, sizeof(*deact));
654 
655 	deact->handle = udeact->handle;
656 
657 	ret = ccp_docmd(sc, PSP_CMD_DEACTIVATE,
658 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
659 
660 	if (ret != 0)
661 		return (EIO);
662 
663 	return (0);
664 }
665 
666 int
psp_downloadfirmware(struct psp_softc * sc,struct psp_downloadfirmware * udlfw)667 psp_downloadfirmware(struct psp_softc *sc, struct psp_downloadfirmware *udlfw)
668 {
669 	struct psp_downloadfirmware *dlfw;
670 	bus_dmamap_t		 map;
671 	bus_dma_segment_t	 seg;
672 	caddr_t			 kva;
673 	int			 nsegs;
674 	int			 ret;
675 
676 	dlfw = (struct psp_downloadfirmware *)sc->sc_cmd_kva;
677 	bzero(dlfw, sizeof(*dlfw));
678 
679 	ret = ENOMEM;
680 	if (bus_dmamap_create(sc->sc_dmat, udlfw->fw_len, 1, udlfw->fw_len, 0,
681 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &map) != 0)
682 		return (ret);
683 	if (bus_dmamem_alloc(sc->sc_dmat, udlfw->fw_len, 0, 0, &seg, 1,
684 	    &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0 || nsegs != 1)
685 		goto fail_0;
686 	if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs, udlfw->fw_len, &kva,
687 	    BUS_DMA_WAITOK) != 0)
688 		goto fail_1;
689 	if (bus_dmamap_load(sc->sc_dmat, map, kva, udlfw->fw_len, NULL,
690 	    BUS_DMA_WAITOK) != 0)
691 		goto fail_2;
692 
693 	bcopy((void *)udlfw->fw_paddr, kva, udlfw->fw_len);
694 
695 	dlfw->fw_paddr = map->dm_segs[0].ds_addr;
696 	dlfw->fw_len = map->dm_segs[0].ds_len;
697 
698 	ret = ccp_docmd(sc, PSP_CMD_DOWNLOADFIRMWARE,
699 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
700 
701 	if (ret != 0)
702 		ret = EIO;
703 
704 	bus_dmamap_unload(sc->sc_dmat, map);
705 fail_2:
706 	bus_dmamem_unmap(sc->sc_dmat, kva, udlfw->fw_len);
707 fail_1:
708 	bus_dmamem_free(sc->sc_dmat, &seg, 1);
709 fail_0:
710 	bus_dmamap_destroy(sc->sc_dmat, map);
711 
712 	return (ret);
713 }
714 
715 int
psp_guest_shutdown(struct psp_softc * sc,struct psp_guest_shutdown * ugshutdown)716 psp_guest_shutdown(struct psp_softc *sc, struct psp_guest_shutdown *ugshutdown)
717 {
718 	struct psp_deactivate	deact;
719 	struct psp_decommission	decom;
720 	int			ret;
721 
722 	bzero(&deact, sizeof(deact));
723 	deact.handle = ugshutdown->handle;
724 	if ((ret = psp_deactivate(sc, &deact)) != 0)
725 		return (ret);
726 
727 	if ((ret = psp_df_flush(sc)) != 0)
728 		return (ret);
729 
730 	bzero(&decom, sizeof(decom));
731 	decom.handle = ugshutdown->handle;
732 	if ((ret = psp_decommission(sc, &decom)) != 0)
733 		return (ret);
734 
735 	return (0);
736 }
737 
738 int
psp_snp_get_pstatus(struct psp_softc * sc,struct psp_snp_platform_status * ustatus)739 psp_snp_get_pstatus(struct psp_softc *sc,
740     struct psp_snp_platform_status *ustatus)
741 {
742 	struct psp_snp_platform_status *status;
743 	int			 ret;
744 
745 	status = (struct psp_snp_platform_status *)sc->sc_cmd_kva;
746 	bzero(status, sizeof(*status));
747 
748 	ret = ccp_docmd(sc, PSP_CMD_SNP_PLATFORMSTATUS,
749 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
750 
751 	if (ret != 0)
752 		return (EIO);
753 
754 	bcopy(status, ustatus, sizeof(*ustatus));
755 
756 	return (0);
757 }
758 
759 int
pspopen(dev_t dev,int flag,int mode,struct proc * p)760 pspopen(dev_t dev, int flag, int mode, struct proc *p)
761 {
762 	struct psp_softc *sc;
763 
764 	sc = (struct psp_softc *)device_lookup(&psp_cd, minor(dev));
765 	if (sc == NULL)
766 		return (ENXIO);
767 
768 	psp_load_ucode(sc);
769 
770 	if (!(sc->sc_flags & PSPF_INITIALIZED))
771 		return (psp_reinit(sc));
772 
773 	return (0);
774 }
775 
776 int
pspclose(dev_t dev,int flag,int mode,struct proc * p)777 pspclose(dev_t dev, int flag, int mode, struct proc *p)
778 {
779 	struct psp_softc *sc;
780 
781 	sc = (struct psp_softc *)device_lookup(&psp_cd, minor(dev));
782 	if (sc == NULL)
783 		return (ENXIO);
784 
785 	return (0);
786 }
787 
788 int
pspioctl(dev_t dev,u_long cmd,caddr_t data,int flag,struct proc * p)789 pspioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
790 {
791 	struct psp_softc *sc;
792 	int ret;
793 
794 	sc = (struct psp_softc *)device_lookup(&psp_cd, minor(dev));
795 	if (sc == NULL)
796 		return (ENXIO);
797 
798 	KERNEL_UNLOCK();
799 
800 	rw_enter_write(&sc->sc_lock);
801 
802 	switch (cmd) {
803 	case PSP_IOC_INIT:
804 		ret = psp_reinit(sc);
805 		break;
806 	case PSP_IOC_SHUTDOWN:
807 		ret = psp_shutdown(sc);
808 		break;
809 	case PSP_IOC_GET_PSTATUS:
810 		ret = psp_get_pstatus(sc, (struct psp_platform_status *)data);
811 		break;
812 	case PSP_IOC_DF_FLUSH:
813 		ret = psp_df_flush(sc);
814 		break;
815 	case PSP_IOC_DECOMMISSION:
816 		ret = psp_decommission(sc, (struct psp_decommission *)data);
817 		break;
818 	case PSP_IOC_GET_GSTATUS:
819 		ret = psp_get_gstatus(sc, (struct psp_guest_status *)data);
820 		break;
821 	case PSP_IOC_LAUNCH_START:
822 		ret = psp_launch_start(sc, (struct psp_launch_start *)data);
823 		break;
824 	case PSP_IOC_LAUNCH_UPDATE_DATA:
825 		ret = psp_launch_update_data(sc,
826 		    (struct psp_launch_update_data *)data, p);
827 		break;
828 	case PSP_IOC_LAUNCH_MEASURE:
829 		ret = psp_launch_measure(sc, (struct psp_launch_measure *)data);
830 		break;
831 	case PSP_IOC_LAUNCH_FINISH:
832 		ret = psp_launch_finish(sc, (struct psp_launch_finish *)data);
833 		break;
834 	case PSP_IOC_ATTESTATION:
835 		ret = psp_attestation(sc, (struct psp_attestation *)data);
836 		break;
837 	case PSP_IOC_ACTIVATE:
838 		ret = psp_activate(sc, (struct psp_activate *)data);
839 		break;
840 	case PSP_IOC_DEACTIVATE:
841 		ret = psp_deactivate(sc, (struct psp_deactivate *)data);
842 		break;
843 	case PSP_IOC_GUEST_SHUTDOWN:
844 		ret = psp_guest_shutdown(sc, (struct psp_guest_shutdown *)data);
845 		break;
846 	case PSP_IOC_SNP_GET_PSTATUS:
847 		ret = psp_snp_get_pstatus(sc,
848 		    (struct psp_snp_platform_status *)data);
849 		break;
850 	default:
851 		ret = ENOTTY;
852 		break;
853 	}
854 
855 	rw_exit_write(&sc->sc_lock);
856 
857 	KERNEL_LOCK();
858 
859 	return (ret);
860 }
861 
862 int
pledge_ioctl_psp(struct proc * p,long com)863 pledge_ioctl_psp(struct proc *p, long com)
864 {
865 	switch (com) {
866 	case PSP_IOC_GET_PSTATUS:
867 	case PSP_IOC_DF_FLUSH:
868 	case PSP_IOC_GET_GSTATUS:
869 	case PSP_IOC_LAUNCH_START:
870 	case PSP_IOC_LAUNCH_UPDATE_DATA:
871 	case PSP_IOC_LAUNCH_MEASURE:
872 	case PSP_IOC_LAUNCH_FINISH:
873 	case PSP_IOC_ACTIVATE:
874 	case PSP_IOC_GUEST_SHUTDOWN:
875 		return (0);
876 	default:
877 		return (pledge_fail(p, EPERM, PLEDGE_VMM));
878 	}
879 }
880 
881 int
pspprint(void * aux,const char * pnp)882 pspprint(void *aux, const char *pnp)
883 {
884 	return QUIET;
885 }
886 
887 int
pspsubmatch(struct device * parent,void * match,void * aux)888 pspsubmatch(struct device *parent, void *match, void *aux)
889 {
890 	struct psp_attach_args *arg = aux;
891 	struct cfdata *cf = match;
892 
893 	if (!(arg->capabilities & PSP_CAP_SEV))
894 		return (0);
895 	return ((*cf->cf_attach->ca_match)(parent, cf, aux));
896 }
897 
898 struct ucode {
899 	uint8_t		 family;
900 	uint8_t		 model;
901 	const char	*uname;
902 } const psp_ucode_table[] = {
903 	{ 0x17, 0x0, "amdsev/amd_sev_fam17h_model0xh.sbin" },
904 	{ 0x17, 0x3, "amdsev/amd_sev_fam17h_model3xh.sbin" },
905 	{ 0x19, 0x0, "amdsev/amd_sev_fam19h_model0xh.sbin" },
906 	{ 0x19, 0x1, "amdsev/amd_sev_fam19h_model1xh.sbin" },
907 	{ 0, 0, NULL }
908 };
909 
910 void
psp_load_ucode(struct psp_softc * sc)911 psp_load_ucode(struct psp_softc *sc)
912 {
913 	struct psp_downloadfirmware dlfw;
914 	struct cpu_info		*ci = &cpu_info_primary;
915 	const struct ucode	*uc;
916 	uint8_t			 family, model;
917 	int			 error;
918 
919 	if ((sc->sc_flags & PSPF_UCODELOADED) ||
920 	    (sc->sc_flags & PSPF_NOUCODE) ||
921 	    (sc->sc_flags & PSPF_INITIALIZED))
922 		return;
923 
924 	family = ci->ci_family;
925 	model = (ci->ci_model & 0xf0) >> 4;
926 
927 	for (uc = psp_ucode_table; uc->uname; uc++) {
928 		if ((uc->family == family) && (uc->model == model))
929 			break;
930 	}
931 
932 	if (uc->uname == NULL) {
933 		printf("%s: no firmware found, CPU family 0x%x model 0x%x\n",
934 		    sc->sc_dev.dv_xname, family, model);
935 		sc->sc_flags |= PSPF_NOUCODE;
936 		return;
937 	}
938 
939 	error = loadfirmware(uc->uname, &sc->sc_ucodebuf, &sc->sc_ucodelen);
940 	if (error) {
941 		if (error != ENOENT) {
942 			printf("%s: error %d, could not read firmware %s\n",
943 			    sc->sc_dev.dv_xname, error, uc->uname);
944 		}
945 		sc->sc_flags |= PSPF_NOUCODE;
946 		return;
947 	}
948 
949 	bzero(&dlfw, sizeof(dlfw));
950 	dlfw.fw_len = sc->sc_ucodelen;
951 	dlfw.fw_paddr = (uint64_t)sc->sc_ucodebuf;
952 
953 	if (psp_downloadfirmware(sc, &dlfw) < 0)
954 		goto out;
955 
956 	sc->sc_flags |= PSPF_UCODELOADED;
957 out:
958 	if (sc->sc_ucodebuf) {
959 		free(sc->sc_ucodebuf, M_DEVBUF, sc->sc_ucodelen);
960 		sc->sc_ucodebuf = NULL;
961 		sc->sc_ucodelen = 0;
962 	}
963 }
964