xref: /openbsd/sys/dev/ic/psp.c (revision e283d8fb)
1 /*	$OpenBSD: psp.c,v 1.15 2024/11/20 13:36:55 bluhm 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 int	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, error;
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 	error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
149 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &sc->sc_cmd_map);
150 	if (error)
151 		goto fail_0;
152 
153 	error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_cmd_seg, 1,
154 	    &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO);
155 	if (error)
156 		goto fail_1;
157 
158 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_seg, nsegs, size,
159 	    &sc->sc_cmd_kva, BUS_DMA_WAITOK);
160 	if (error)
161 		goto fail_2;
162 
163 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_map, sc->sc_cmd_kva,
164 	    size, NULL, BUS_DMA_WAITOK);
165 	if (error)
166 		goto fail_3;
167 
168 	if (psp_get_pstatus(sc, &pst)) {
169 		printf(" platform status");
170 		goto fail_4;
171 	}
172 	if (pst.state != PSP_PSTATE_UNINIT) {
173 		printf(" uninitialized state");
174 		goto fail_4;
175 	}
176 	printf(" api %u.%u, build %u, SEV, SEV-ES",
177 	    pst.api_major, pst.api_minor, pst.cfges_build >> 24);
178 
179 	/* enable interrupts */
180 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_inten, -1);
181 
182 	printf("\n");
183 
184 	return;
185 
186 fail_4:
187 	bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_map);
188 fail_3:
189 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_cmd_kva, size);
190 fail_2:
191 	bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_seg, nsegs);
192 fail_1:
193 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmd_map);
194 fail_0:
195 	printf(" failed\n");
196 }
197 
198 static int
ccp_wait(struct psp_softc * sc,uint32_t * status,int poll)199 ccp_wait(struct psp_softc *sc, uint32_t *status, int poll)
200 {
201 	uint32_t	cmdword;
202 	int		count, error;
203 
204 	MUTEX_ASSERT_LOCKED(&sc->psp_lock);
205 
206 	if (poll) {
207 		count = 0;
208 		while (count++ < 400) {
209 			cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
210 			    sc->sc_reg_cmdresp);
211 			if (cmdword & PSP_CMDRESP_RESPONSE)
212 				goto done;
213 			delay(5000);
214 		}
215 
216 		/* timeout */
217 		return (EWOULDBLOCK);
218 	}
219 
220 	error = msleep_nsec(sc, &sc->psp_lock, PWAIT, "psp", SEC_TO_NSEC(2));
221 	if (error)
222 		return (error);
223 
224 	cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp);
225 done:
226 	if (status != NULL)
227 		*status = cmdword;
228 	return (0);
229 }
230 
231 static int
ccp_docmd(struct psp_softc * sc,int cmd,uint64_t paddr)232 ccp_docmd(struct psp_softc *sc, int cmd, uint64_t paddr)
233 {
234 	uint32_t	plo, phi, cmdword, status;
235 	int		error;
236 
237 	plo = ((paddr >> 0) & 0xffffffff);
238 	phi = ((paddr >> 32) & 0xffffffff);
239 	cmdword = (cmd & 0x3ff) << 16;
240 	if (!cold)
241 		cmdword |= PSP_CMDRESP_IOC;
242 
243 	mtx_enter(&sc->psp_lock);
244 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_addrlo, plo);
245 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_addrhi, phi);
246 	bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp, cmdword);
247 
248 	error = ccp_wait(sc, &status, cold);
249 	mtx_leave(&sc->psp_lock);
250 	if (error)
251 		return (error);
252 
253 	/* Did PSP sent a response code? */
254 	if (status & PSP_CMDRESP_RESPONSE) {
255 		if ((status & PSP_STATUS_MASK) != PSP_STATUS_SUCCESS)
256 			return (EIO);
257 	}
258 
259 	return (0);
260 }
261 
262 int
psp_init(struct psp_softc * sc,struct psp_init * uinit)263 psp_init(struct psp_softc *sc, struct psp_init *uinit)
264 {
265 	struct psp_init		*init;
266 	int			 error;
267 
268 	init = (struct psp_init *)sc->sc_cmd_kva;
269 	bzero(init, sizeof(*init));
270 
271 	init->enable_es = uinit->enable_es;
272 	init->tmr_paddr = uinit->tmr_paddr;
273 	init->tmr_length = uinit->tmr_length;
274 
275 	error = ccp_docmd(sc, PSP_CMD_INIT, sc->sc_cmd_map->dm_segs[0].ds_addr);
276 	if (error)
277 		return (error);
278 
279 	wbinvd_on_all_cpus_acked();
280 
281 	sc->sc_flags |= PSPF_INITIALIZED;
282 
283 	return (0);
284 }
285 
286 int
psp_reinit(struct psp_softc * sc)287 psp_reinit(struct psp_softc *sc)
288 {
289 	struct psp_init	init;
290 	size_t		size;
291 	int		nsegs, error;
292 
293 	if (sc->sc_flags & PSPF_INITIALIZED) {
294 		printf("%s: invalid flags 0x%x\n", __func__, sc->sc_flags);
295 		return (EBUSY);
296 	}
297 
298 	if (sc->sc_tmr_map != NULL)
299 		return (EBUSY);
300 
301 	/*
302 	 * create and map Trusted Memory Region (TMR); size 1 Mbyte,
303 	 * needs to be aligend to 1 Mbyte.
304 	 */
305 	sc->sc_tmr_size = size = PSP_TMR_SIZE;
306 	error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0,
307 	    BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &sc->sc_tmr_map);
308 	if (error)
309 		goto fail_0;
310 
311 	error = bus_dmamem_alloc(sc->sc_dmat, size, size, 0, &sc->sc_tmr_seg, 1,
312 	    &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO);
313 	if (error)
314 		goto fail_1;
315 
316 	error = bus_dmamem_map(sc->sc_dmat, &sc->sc_tmr_seg, nsegs, size,
317 	    &sc->sc_tmr_kva, BUS_DMA_WAITOK);
318 	if (error)
319 		goto fail_2;
320 
321 	error = bus_dmamap_load(sc->sc_dmat, sc->sc_tmr_map, sc->sc_tmr_kva,
322 	    size, NULL, BUS_DMA_WAITOK);
323 	if (error)
324 		goto fail_3;
325 
326 	memset(&init, 0, sizeof(init));
327 	init.enable_es = 1;
328 	init.tmr_length = PSP_TMR_SIZE;
329 	init.tmr_paddr = sc->sc_tmr_map->dm_segs[0].ds_addr;
330 	if ((error = psp_init(sc, &init)) != 0)
331 		goto fail_4;
332 
333 	return (0);
334 
335 fail_4:
336 	bus_dmamap_unload(sc->sc_dmat, sc->sc_tmr_map);
337 fail_3:
338 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_tmr_kva, size);
339 fail_2:
340 	bus_dmamem_free(sc->sc_dmat, &sc->sc_tmr_seg, nsegs);
341 fail_1:
342 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_tmr_map);
343 fail_0:
344 	return (error);
345 }
346 
347 int
psp_shutdown(struct psp_softc * sc)348 psp_shutdown(struct psp_softc *sc)
349 {
350 	int error;
351 
352 	if (sc->sc_tmr_map == NULL)
353 		return (EINVAL);
354 
355 	error = ccp_docmd(sc, PSP_CMD_SHUTDOWN, 0x0);
356 	if (error)
357 		return (error);
358 
359 	/* wbinvd right after SHUTDOWN */
360 	wbinvd_on_all_cpus_acked();
361 
362 	/* release TMR */
363 	bus_dmamap_unload(sc->sc_dmat, sc->sc_tmr_map);
364 	bus_dmamem_unmap(sc->sc_dmat, sc->sc_tmr_kva, sc->sc_tmr_size);
365 	bus_dmamem_free(sc->sc_dmat, &sc->sc_tmr_seg, 1);
366 	bus_dmamap_destroy(sc->sc_dmat, sc->sc_tmr_map);
367 	sc->sc_tmr_map = NULL;
368 
369 	/* reset flags */
370 	sc->sc_flags = 0;
371 
372 	return (0);
373 }
374 
375 int
psp_get_pstatus(struct psp_softc * sc,struct psp_platform_status * ustatus)376 psp_get_pstatus(struct psp_softc *sc, struct psp_platform_status *ustatus)
377 {
378 	struct psp_platform_status	*status;
379 	int				 error;
380 
381 	status = (struct psp_platform_status *)sc->sc_cmd_kva;
382 	bzero(status, sizeof(*status));
383 
384 	error = ccp_docmd(sc, PSP_CMD_PLATFORMSTATUS,
385 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
386 	if (error)
387 		return (error);
388 
389 	bcopy(status, ustatus, sizeof(*ustatus));
390 
391 	return (0);
392 }
393 
394 int
psp_df_flush(struct psp_softc * sc)395 psp_df_flush(struct psp_softc *sc)
396 {
397 	int error;
398 
399 	wbinvd_on_all_cpus_acked();
400 
401 	error = ccp_docmd(sc, PSP_CMD_DF_FLUSH, 0x0);
402 
403 	return (error);
404 }
405 
406 int
psp_decommission(struct psp_softc * sc,struct psp_decommission * udecom)407 psp_decommission(struct psp_softc *sc, struct psp_decommission *udecom)
408 {
409 	struct psp_decommission	*decom;
410 	int			 error;
411 
412 	decom = (struct psp_decommission *)sc->sc_cmd_kva;
413 	bzero(decom, sizeof(*decom));
414 
415 	decom->handle = udecom->handle;
416 
417 	error = ccp_docmd(sc, PSP_CMD_DECOMMISSION,
418 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
419 
420 	return (error);
421 }
422 
423 int
psp_get_gstatus(struct psp_softc * sc,struct psp_guest_status * ustatus)424 psp_get_gstatus(struct psp_softc *sc, struct psp_guest_status *ustatus)
425 {
426 	struct psp_guest_status	*status;
427 	int			 error;
428 
429 	status = (struct psp_guest_status *)sc->sc_cmd_kva;
430 	bzero(status, sizeof(*status));
431 
432 	status->handle = ustatus->handle;
433 
434 	error = ccp_docmd(sc, PSP_CMD_GUESTSTATUS,
435 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
436 	if (error)
437 		return (error);
438 
439 	ustatus->policy = status->policy;
440 	ustatus->asid = status->asid;
441 	ustatus->state = status->state;
442 
443 	return (0);
444 }
445 
446 int
psp_launch_start(struct psp_softc * sc,struct psp_launch_start * ustart)447 psp_launch_start(struct psp_softc *sc, struct psp_launch_start *ustart)
448 {
449 	struct psp_launch_start	*start;
450 	int			 error;
451 
452 	start = (struct psp_launch_start *)sc->sc_cmd_kva;
453 	bzero(start, sizeof(*start));
454 
455 	start->handle = ustart->handle;
456 	start->policy = ustart->policy;
457 
458 	error = ccp_docmd(sc, PSP_CMD_LAUNCH_START,
459 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
460 	if (error)
461 		return (error);
462 
463 	/* If requested, return new handle. */
464 	if (ustart->handle == 0)
465 		ustart->handle = start->handle;
466 
467 	return (0);
468 }
469 
470 int
psp_launch_update_data(struct psp_softc * sc,struct psp_launch_update_data * ulud,struct proc * p)471 psp_launch_update_data(struct psp_softc *sc,
472     struct psp_launch_update_data *ulud, struct proc *p)
473 {
474 	struct psp_launch_update_data	*ludata;
475 	pmap_t				 pmap;
476 	vaddr_t				 v, next, start, end;
477 	size_t				 size, len, off;
478 	int				 error;
479 
480 	/* Ensure AES_XTS_BLOCKSIZE alignment and multiplicity. */
481 	if ((ulud->paddr & (AES_XTS_BLOCKSIZE - 1)) != 0 ||
482 	    (ulud->length % AES_XTS_BLOCKSIZE) != 0)
483 		return (EINVAL);
484 
485 	ludata = (struct psp_launch_update_data *)sc->sc_cmd_kva;
486 	bzero(ludata, sizeof(*ludata));
487 
488 	ludata->handle = ulud->handle;
489 
490 	/* Drain caches before we encrypt memory. */
491 	wbinvd_on_all_cpus_acked();
492 
493 	/*
494 	 * Launch update one physical page at a time.  We could
495 	 * optimise this for contiguous pages of physical memory.
496 	 *
497 	 * vmd(8) provides the guest physical address, thus convert
498 	 * to system physical address.
499 	 */
500 	pmap = vm_map_pmap(&p->p_vmspace->vm_map);
501 	start = ulud->paddr;
502 	size = ulud->length;
503 	end = start + size;
504 
505 	/* Wire mapping. */
506 	error = uvm_map_pageable(&p->p_vmspace->vm_map, start, end, FALSE, 0);
507 	if (error)
508 		goto out;
509 
510 	for (v = ulud->paddr; v < end; v = next) {
511 		off = v & PAGE_MASK;
512 
513 		len = MIN(PAGE_SIZE - off, size);
514 
515 		if (!pmap_extract(pmap, v, (paddr_t *)&ludata->paddr)) {
516 			error = EINVAL;
517 			goto out;
518 		}
519 		ludata->length = len;
520 
521 		error = ccp_docmd(sc, PSP_CMD_LAUNCH_UPDATE_DATA,
522 		    sc->sc_cmd_map->dm_segs[0].ds_addr);
523 		if (error)
524 			goto out;
525 
526 		size -= len;
527 		next = v + len;
528 	}
529 
530 out:
531 	/*
532 	 * Unwire again.  Ignore new error.  Error has either been set,
533 	 * or PSP command has already succeeded.
534 	 */
535 	(void) uvm_map_pageable(&p->p_vmspace->vm_map, start, end, TRUE, 0);
536 
537 	return (error);
538 }
539 
540 int
psp_launch_measure(struct psp_softc * sc,struct psp_launch_measure * ulm)541 psp_launch_measure(struct psp_softc *sc, struct psp_launch_measure *ulm)
542 {
543 	struct psp_launch_measure	*lm;
544 	uint64_t			 paddr;
545 	int				 error;
546 
547 	if (ulm->measure_len != sizeof(ulm->psp_measure))
548 		return (EINVAL);
549 
550 	lm = (struct psp_launch_measure *)sc->sc_cmd_kva;
551 	bzero(lm, sizeof(*lm));
552 
553 	lm->handle = ulm->handle;
554 	paddr = sc->sc_cmd_map->dm_segs[0].ds_addr;
555 	lm->measure_paddr =
556 	    paddr + offsetof(struct psp_launch_measure, psp_measure);
557 	lm->measure_len = sizeof(lm->psp_measure);
558 
559 	error = ccp_docmd(sc, PSP_CMD_LAUNCH_MEASURE, paddr);
560 	if (error)
561 		return (error);
562 	if (lm->measure_len != ulm->measure_len)
563 		return (ERANGE);
564 
565 	bcopy(&lm->psp_measure, &ulm->psp_measure, ulm->measure_len);
566 
567 	return (0);
568 }
569 
570 int
psp_launch_finish(struct psp_softc * sc,struct psp_launch_finish * ulf)571 psp_launch_finish(struct psp_softc *sc, struct psp_launch_finish *ulf)
572 {
573 	struct psp_launch_finish	*lf;
574 	int				 error;
575 
576 	lf = (struct psp_launch_finish *)sc->sc_cmd_kva;
577 	bzero(lf, sizeof(*lf));
578 
579 	lf->handle = ulf->handle;
580 
581 	error = ccp_docmd(sc, PSP_CMD_LAUNCH_FINISH,
582 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
583 
584 	return (error);
585 }
586 
587 int
psp_attestation(struct psp_softc * sc,struct psp_attestation * uat)588 psp_attestation(struct psp_softc *sc, struct psp_attestation *uat)
589 {
590 	struct psp_attestation	*at;
591 	uint64_t		 paddr;
592 	int			 error;
593 
594 	if (uat->attest_len != sizeof(uat->psp_report))
595 		return (EINVAL);
596 
597 	at = (struct psp_attestation *)sc->sc_cmd_kva;
598 	bzero(at, sizeof(*at));
599 
600 	at->handle = uat->handle;
601 	paddr = sc->sc_cmd_map->dm_segs[0].ds_addr;
602 	at->attest_paddr =
603 	    paddr + offsetof(struct psp_attestation, psp_report);
604 	bcopy(uat->attest_nonce, at->attest_nonce, sizeof(at->attest_nonce));
605 	at->attest_len = sizeof(at->psp_report);
606 
607 	error = ccp_docmd(sc, PSP_CMD_ATTESTATION, paddr);
608 	if (error)
609 		return (error);
610 	if (at->attest_len != uat->attest_len)
611 		return (ERANGE);
612 
613 	bcopy(&at->psp_report, &uat->psp_report, uat->attest_len);
614 
615 	return (0);
616 }
617 
618 int
psp_activate(struct psp_softc * sc,struct psp_activate * uact)619 psp_activate(struct psp_softc *sc, struct psp_activate *uact)
620 {
621 	struct psp_activate	*act;
622 	int			 error;
623 
624 	act = (struct psp_activate *)sc->sc_cmd_kva;
625 	bzero(act, sizeof(*act));
626 
627 	act->handle = uact->handle;
628 	act->asid = uact->asid;
629 
630 	error = ccp_docmd(sc, PSP_CMD_ACTIVATE,
631 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
632 
633 	return (error);
634 }
635 
636 int
psp_deactivate(struct psp_softc * sc,struct psp_deactivate * udeact)637 psp_deactivate(struct psp_softc *sc, struct psp_deactivate *udeact)
638 {
639 	struct psp_deactivate	*deact;
640 	int			 error;
641 
642 	deact = (struct psp_deactivate *)sc->sc_cmd_kva;
643 	bzero(deact, sizeof(*deact));
644 
645 	deact->handle = udeact->handle;
646 
647 	error = ccp_docmd(sc, PSP_CMD_DEACTIVATE,
648 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
649 
650 	return (error);
651 }
652 
653 int
psp_downloadfirmware(struct psp_softc * sc,struct psp_downloadfirmware * udlfw)654 psp_downloadfirmware(struct psp_softc *sc, struct psp_downloadfirmware *udlfw)
655 {
656 	struct psp_downloadfirmware	*dlfw;
657 	bus_dmamap_t			 map;
658 	bus_dma_segment_t		 seg;
659 	caddr_t				 kva;
660 	int				 nsegs, error;
661 
662 	dlfw = (struct psp_downloadfirmware *)sc->sc_cmd_kva;
663 	bzero(dlfw, sizeof(*dlfw));
664 
665 	error = bus_dmamap_create(sc->sc_dmat, udlfw->fw_len, 1, udlfw->fw_len,
666 	    0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &map);
667 	if (error)
668 		goto fail_0;
669 
670 	error = bus_dmamem_alloc(sc->sc_dmat, udlfw->fw_len, 0, 0, &seg, 1,
671 	    &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO);
672 	if (error)
673 		goto fail_1;
674 
675 	error = bus_dmamem_map(sc->sc_dmat, &seg, nsegs, udlfw->fw_len, &kva,
676 	    BUS_DMA_WAITOK);
677 	if (error)
678 		goto fail_2;
679 
680 	error = bus_dmamap_load(sc->sc_dmat, map, kva, udlfw->fw_len, NULL,
681 	    BUS_DMA_WAITOK);
682 	if (error)
683 		goto fail_3;
684 
685 	bcopy((void *)udlfw->fw_paddr, kva, udlfw->fw_len);
686 
687 	dlfw->fw_paddr = map->dm_segs[0].ds_addr;
688 	dlfw->fw_len = map->dm_segs[0].ds_len;
689 
690 	error = ccp_docmd(sc, PSP_CMD_DOWNLOADFIRMWARE,
691 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
692 
693 	bus_dmamap_unload(sc->sc_dmat, map);
694 fail_3:
695 	bus_dmamem_unmap(sc->sc_dmat, kva, udlfw->fw_len);
696 fail_2:
697 	bus_dmamem_free(sc->sc_dmat, &seg, nsegs);
698 fail_1:
699 	bus_dmamap_destroy(sc->sc_dmat, map);
700 fail_0:
701 	return (error);
702 }
703 
704 int
psp_guest_shutdown(struct psp_softc * sc,struct psp_guest_shutdown * ugshutdown)705 psp_guest_shutdown(struct psp_softc *sc, struct psp_guest_shutdown *ugshutdown)
706 {
707 	struct psp_deactivate	deact;
708 	struct psp_decommission	decom;
709 	int			error;
710 
711 	bzero(&deact, sizeof(deact));
712 	deact.handle = ugshutdown->handle;
713 	if ((error = psp_deactivate(sc, &deact)) != 0)
714 		return (error);
715 
716 	if ((error = psp_df_flush(sc)) != 0)
717 		return (error);
718 
719 	bzero(&decom, sizeof(decom));
720 	decom.handle = ugshutdown->handle;
721 	if ((error = psp_decommission(sc, &decom)) != 0)
722 		return (error);
723 
724 	return (0);
725 }
726 
727 int
psp_snp_get_pstatus(struct psp_softc * sc,struct psp_snp_platform_status * ustatus)728 psp_snp_get_pstatus(struct psp_softc *sc,
729     struct psp_snp_platform_status *ustatus)
730 {
731 	struct psp_snp_platform_status	*status;
732 	int				 error;
733 
734 	status = (struct psp_snp_platform_status *)sc->sc_cmd_kva;
735 	bzero(status, sizeof(*status));
736 
737 	error = ccp_docmd(sc, PSP_CMD_SNP_PLATFORMSTATUS,
738 	    sc->sc_cmd_map->dm_segs[0].ds_addr);
739 	if (error)
740 		return (error);
741 
742 	bcopy(status, ustatus, sizeof(*ustatus));
743 
744 	return (0);
745 }
746 
747 int
pspopen(dev_t dev,int flag,int mode,struct proc * p)748 pspopen(dev_t dev, int flag, int mode, struct proc *p)
749 {
750 	struct psp_softc *sc;
751 
752 	sc = (struct psp_softc *)device_lookup(&psp_cd, minor(dev));
753 	if (sc == NULL)
754 		return (ENXIO);
755 
756 	/* Ignore error, proceed without new firmware. */
757 	(void) psp_load_ucode(sc);
758 
759 	if (!(sc->sc_flags & PSPF_INITIALIZED))
760 		return (psp_reinit(sc));
761 
762 	return (0);
763 }
764 
765 int
pspclose(dev_t dev,int flag,int mode,struct proc * p)766 pspclose(dev_t dev, int flag, int mode, struct proc *p)
767 {
768 	struct psp_softc *sc;
769 
770 	sc = (struct psp_softc *)device_lookup(&psp_cd, minor(dev));
771 	if (sc == NULL)
772 		return (ENXIO);
773 
774 	return (0);
775 }
776 
777 int
pspioctl(dev_t dev,u_long cmd,caddr_t data,int flag,struct proc * p)778 pspioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p)
779 {
780 	struct psp_softc	*sc;
781 	int			 error;
782 
783 	sc = (struct psp_softc *)device_lookup(&psp_cd, minor(dev));
784 	if (sc == NULL)
785 		return (ENXIO);
786 
787 	KERNEL_UNLOCK();
788 
789 	rw_enter_write(&sc->sc_lock);
790 
791 	switch (cmd) {
792 	case PSP_IOC_INIT:
793 		error = psp_reinit(sc);
794 		break;
795 	case PSP_IOC_SHUTDOWN:
796 		error = psp_shutdown(sc);
797 		break;
798 	case PSP_IOC_GET_PSTATUS:
799 		error = psp_get_pstatus(sc, (struct psp_platform_status *)data);
800 		break;
801 	case PSP_IOC_DF_FLUSH:
802 		error = psp_df_flush(sc);
803 		break;
804 	case PSP_IOC_DECOMMISSION:
805 		error = psp_decommission(sc, (struct psp_decommission *)data);
806 		break;
807 	case PSP_IOC_GET_GSTATUS:
808 		error = psp_get_gstatus(sc, (struct psp_guest_status *)data);
809 		break;
810 	case PSP_IOC_LAUNCH_START:
811 		error = psp_launch_start(sc, (struct psp_launch_start *)data);
812 		break;
813 	case PSP_IOC_LAUNCH_UPDATE_DATA:
814 		error = psp_launch_update_data(sc,
815 		    (struct psp_launch_update_data *)data, p);
816 		break;
817 	case PSP_IOC_LAUNCH_MEASURE:
818 		error = psp_launch_measure(sc,
819 		    (struct psp_launch_measure *)data);
820 		break;
821 	case PSP_IOC_LAUNCH_FINISH:
822 		error = psp_launch_finish(sc, (struct psp_launch_finish *)data);
823 		break;
824 	case PSP_IOC_ATTESTATION:
825 		error = psp_attestation(sc, (struct psp_attestation *)data);
826 		break;
827 	case PSP_IOC_ACTIVATE:
828 		error = psp_activate(sc, (struct psp_activate *)data);
829 		break;
830 	case PSP_IOC_DEACTIVATE:
831 		error = psp_deactivate(sc, (struct psp_deactivate *)data);
832 		break;
833 	case PSP_IOC_GUEST_SHUTDOWN:
834 		error = psp_guest_shutdown(sc,
835 		    (struct psp_guest_shutdown *)data);
836 		break;
837 	case PSP_IOC_SNP_GET_PSTATUS:
838 		error = psp_snp_get_pstatus(sc,
839 		    (struct psp_snp_platform_status *)data);
840 		break;
841 	default:
842 		error = ENOTTY;
843 		break;
844 	}
845 
846 	rw_exit_write(&sc->sc_lock);
847 
848 	KERNEL_LOCK();
849 
850 	return (error);
851 }
852 
853 int
pledge_ioctl_psp(struct proc * p,long com)854 pledge_ioctl_psp(struct proc *p, long com)
855 {
856 	switch (com) {
857 	case PSP_IOC_GET_PSTATUS:
858 	case PSP_IOC_DF_FLUSH:
859 	case PSP_IOC_GET_GSTATUS:
860 	case PSP_IOC_LAUNCH_START:
861 	case PSP_IOC_LAUNCH_UPDATE_DATA:
862 	case PSP_IOC_LAUNCH_MEASURE:
863 	case PSP_IOC_LAUNCH_FINISH:
864 	case PSP_IOC_ACTIVATE:
865 	case PSP_IOC_GUEST_SHUTDOWN:
866 		return (0);
867 	default:
868 		return (pledge_fail(p, EPERM, PLEDGE_VMM));
869 	}
870 }
871 
872 int
pspprint(void * aux,const char * pnp)873 pspprint(void *aux, const char *pnp)
874 {
875 	return QUIET;
876 }
877 
878 int
pspsubmatch(struct device * parent,void * match,void * aux)879 pspsubmatch(struct device *parent, void *match, void *aux)
880 {
881 	struct psp_attach_args *arg = aux;
882 	struct cfdata *cf = match;
883 
884 	if (!(arg->capabilities & PSP_CAP_SEV))
885 		return (0);
886 	return ((*cf->cf_attach->ca_match)(parent, cf, aux));
887 }
888 
889 struct ucode {
890 	uint8_t		 family;
891 	uint8_t		 model;
892 	const char	*uname;
893 } const psp_ucode_table[] = {
894 	{ 0x17, 0x0, "amdsev/amd_sev_fam17h_model0xh.sbin" },
895 	{ 0x17, 0x3, "amdsev/amd_sev_fam17h_model3xh.sbin" },
896 	{ 0x19, 0x0, "amdsev/amd_sev_fam19h_model0xh.sbin" },
897 	{ 0x19, 0x1, "amdsev/amd_sev_fam19h_model1xh.sbin" },
898 	{ 0, 0, NULL }
899 };
900 
901 int
psp_load_ucode(struct psp_softc * sc)902 psp_load_ucode(struct psp_softc *sc)
903 {
904 	struct psp_downloadfirmware dlfw;
905 	struct cpu_info		*ci = &cpu_info_primary;
906 	const struct ucode	*uc;
907 	uint8_t			 family, model;
908 	int			 error;
909 
910 	if ((sc->sc_flags & PSPF_UCODELOADED) ||
911 	    (sc->sc_flags & PSPF_NOUCODE) ||
912 	    (sc->sc_flags & PSPF_INITIALIZED))
913 		return (EBUSY);
914 
915 	family = ci->ci_family;
916 	model = (ci->ci_model & 0xf0) >> 4;
917 
918 	for (uc = psp_ucode_table; uc->uname; uc++) {
919 		if ((uc->family == family) && (uc->model == model))
920 			break;
921 	}
922 
923 	if (uc->uname == NULL) {
924 		printf("%s: no firmware found, CPU family 0x%x model 0x%x\n",
925 		    sc->sc_dev.dv_xname, family, model);
926 		sc->sc_flags |= PSPF_NOUCODE;
927 		return (EOPNOTSUPP);
928 	}
929 
930 	error = loadfirmware(uc->uname, &sc->sc_ucodebuf, &sc->sc_ucodelen);
931 	if (error) {
932 		if (error != ENOENT) {
933 			printf("%s: error %d, could not read firmware %s\n",
934 			    sc->sc_dev.dv_xname, error, uc->uname);
935 		}
936 		sc->sc_flags |= PSPF_NOUCODE;
937 		return (error);
938 	}
939 
940 	bzero(&dlfw, sizeof(dlfw));
941 	dlfw.fw_len = sc->sc_ucodelen;
942 	dlfw.fw_paddr = (uint64_t)sc->sc_ucodebuf;
943 
944 	if ((error = psp_downloadfirmware(sc, &dlfw)) != 0)
945 		goto out;
946 
947 	sc->sc_flags |= PSPF_UCODELOADED;
948 out:
949 	if (sc->sc_ucodebuf) {
950 		free(sc->sc_ucodebuf, M_DEVBUF, sc->sc_ucodelen);
951 		sc->sc_ucodebuf = NULL;
952 		sc->sc_ucodelen = 0;
953 	}
954 
955 	return (error);
956 }
957