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