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