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