diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-11-20 13:36:56 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2024-11-20 13:36:56 +0000 |
commit | 9901831fff0d9529c51f31d5c6c54ed46f85dd7b (patch) | |
tree | e341216d3467e58be46dcd8427e827240673c1b2 | |
parent | b6cab35954bd0cb1925df1546d84311326a3591f (diff) |
Improve error handling of psp(4) driver.
The driver for the AMD platform security processor did use a bunch
of EINVAL error codes. It is better to propagate the error up from
the subsystem or use more specific values. Rename the variable
"ret" to "error" to make clear where we deal with an actual errno(2).
Document where and why the error code is ignored.
OK hshoexer@
-rw-r--r-- | sys/dev/ic/psp.c | 393 |
1 files changed, 193 insertions, 200 deletions
diff --git a/sys/dev/ic/psp.c b/sys/dev/ic/psp.c index 6f3a6519c61..bd991481062 100644 --- a/sys/dev/ic/psp.c +++ b/sys/dev/ic/psp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: psp.c,v 1.14 2024/11/10 06:51:59 jsg Exp $ */ +/* $OpenBSD: psp.c,v 1.15 2024/11/20 13:36:55 bluhm Exp $ */ /* * Copyright (c) 2023, 2024 Hans-Joerg Hoexer <hshoexer@genua.de> @@ -73,7 +73,7 @@ int psp_init(struct psp_softc *, struct psp_init *); int psp_reinit(struct psp_softc *); int psp_match(struct device *, void *, void *); void psp_attach(struct device *, struct device *, void *); -void psp_load_ucode(struct psp_softc *); +int psp_load_ucode(struct psp_softc *); struct cfdriver psp_cd = { NULL, "psp", DV_DULL @@ -118,7 +118,7 @@ psp_attach(struct device *parent, struct device *self, void *aux) struct psp_attach_args *arg = aux; struct psp_platform_status pst; size_t size; - int nsegs; + int nsegs, error; printf(":"); sc->sc_iot = arg->iot; @@ -145,30 +145,33 @@ psp_attach(struct device *parent, struct device *self, void *aux) /* create and map SEV command buffer */ sc->sc_cmd_size = size = PAGE_SIZE; - if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, - &sc->sc_cmd_map) != 0) - return; - - if (bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_cmd_seg, 1, - &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0) + error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, + BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &sc->sc_cmd_map); + if (error) goto fail_0; - if (bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_seg, nsegs, size, - &sc->sc_cmd_kva, BUS_DMA_WAITOK) != 0) + error = bus_dmamem_alloc(sc->sc_dmat, size, 0, 0, &sc->sc_cmd_seg, 1, + &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (error) goto fail_1; - if (bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_map, sc->sc_cmd_kva, - size, NULL, BUS_DMA_WAITOK) != 0) + error = bus_dmamem_map(sc->sc_dmat, &sc->sc_cmd_seg, nsegs, size, + &sc->sc_cmd_kva, BUS_DMA_WAITOK); + if (error) goto fail_2; + error = bus_dmamap_load(sc->sc_dmat, sc->sc_cmd_map, sc->sc_cmd_kva, + size, NULL, BUS_DMA_WAITOK); + if (error) + goto fail_3; + if (psp_get_pstatus(sc, &pst)) { printf(" platform status"); - goto fail_3; + goto fail_4; } if (pst.state != PSP_PSTATE_UNINIT) { printf(" uninitialized state"); - goto fail_3; + goto fail_4; } printf(" api %u.%u, build %u, SEV, SEV-ES", pst.api_major, pst.api_minor, pst.cfges_build >> 24); @@ -180,25 +183,23 @@ psp_attach(struct device *parent, struct device *self, void *aux) return; -fail_3: +fail_4: bus_dmamap_unload(sc->sc_dmat, sc->sc_cmd_map); -fail_2: +fail_3: bus_dmamem_unmap(sc->sc_dmat, sc->sc_cmd_kva, size); +fail_2: + bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_seg, nsegs); fail_1: - bus_dmamem_free(sc->sc_dmat, &sc->sc_cmd_seg, 1); -fail_0: bus_dmamap_destroy(sc->sc_dmat, sc->sc_cmd_map); - +fail_0: printf(" failed\n"); - - return; } static int ccp_wait(struct psp_softc *sc, uint32_t *status, int poll) { uint32_t cmdword; - int count; + int count, error; MUTEX_ASSERT_LOCKED(&sc->psp_lock); @@ -213,12 +214,12 @@ ccp_wait(struct psp_softc *sc, uint32_t *status, int poll) } /* timeout */ - return (1); + return (EWOULDBLOCK); } - if (msleep_nsec(sc, &sc->psp_lock, PWAIT, "psp", SEC_TO_NSEC(2)) - == EWOULDBLOCK) - return (1); + error = msleep_nsec(sc, &sc->psp_lock, PWAIT, "psp", SEC_TO_NSEC(2)); + if (error) + return (error); cmdword = bus_space_read_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp); done: @@ -231,7 +232,7 @@ static int ccp_docmd(struct psp_softc *sc, int cmd, uint64_t paddr) { uint32_t plo, phi, cmdword, status; - int ret; + int error; plo = ((paddr >> 0) & 0xffffffff); phi = ((paddr >> 32) & 0xffffffff); @@ -244,15 +245,15 @@ ccp_docmd(struct psp_softc *sc, int cmd, uint64_t paddr) bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_addrhi, phi); bus_space_write_4(sc->sc_iot, sc->sc_ioh, sc->sc_reg_cmdresp, cmdword); - ret = ccp_wait(sc, &status, cold); + error = ccp_wait(sc, &status, cold); mtx_leave(&sc->psp_lock); - if (ret) - return (1); + if (error) + return (error); /* Did PSP sent a response code? */ if (status & PSP_CMDRESP_RESPONSE) { if ((status & PSP_STATUS_MASK) != PSP_STATUS_SUCCESS) - return (1); + return (EIO); } return (0); @@ -262,7 +263,7 @@ int psp_init(struct psp_softc *sc, struct psp_init *uinit) { struct psp_init *init; - int ret; + int error; init = (struct psp_init *)sc->sc_cmd_kva; bzero(init, sizeof(*init)); @@ -271,9 +272,9 @@ psp_init(struct psp_softc *sc, struct psp_init *uinit) init->tmr_paddr = uinit->tmr_paddr; init->tmr_length = uinit->tmr_length; - ret = ccp_docmd(sc, PSP_CMD_INIT, sc->sc_cmd_map->dm_segs[0].ds_addr); - if (ret != 0) - return (EIO); + error = ccp_docmd(sc, PSP_CMD_INIT, sc->sc_cmd_map->dm_segs[0].ds_addr); + if (error) + return (error); wbinvd_on_all_cpus_acked(); @@ -287,71 +288,73 @@ psp_reinit(struct psp_softc *sc) { struct psp_init init; size_t size; - int nsegs; + int nsegs, error; if (sc->sc_flags & PSPF_INITIALIZED) { printf("%s: invalid flags 0x%x\n", __func__, sc->sc_flags); - return (EINVAL); + return (EBUSY); } if (sc->sc_tmr_map != NULL) - return (EINVAL); + return (EBUSY); /* * create and map Trusted Memory Region (TMR); size 1 Mbyte, * needs to be aligend to 1 Mbyte. */ sc->sc_tmr_size = size = PSP_TMR_SIZE; - if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, - BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, - &sc->sc_tmr_map) != 0) - return (ENOMEM); - - if (bus_dmamem_alloc(sc->sc_dmat, size, size, 0, &sc->sc_tmr_seg, 1, - &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0) + error = bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, + BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &sc->sc_tmr_map); + if (error) goto fail_0; - if (bus_dmamem_map(sc->sc_dmat, &sc->sc_tmr_seg, nsegs, size, - &sc->sc_tmr_kva, BUS_DMA_WAITOK) != 0) + error = bus_dmamem_alloc(sc->sc_dmat, size, size, 0, &sc->sc_tmr_seg, 1, + &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (error) goto fail_1; - if (bus_dmamap_load(sc->sc_dmat, sc->sc_tmr_map, sc->sc_tmr_kva, - size, NULL, BUS_DMA_WAITOK) != 0) + error = bus_dmamem_map(sc->sc_dmat, &sc->sc_tmr_seg, nsegs, size, + &sc->sc_tmr_kva, BUS_DMA_WAITOK); + if (error) goto fail_2; + error = bus_dmamap_load(sc->sc_dmat, sc->sc_tmr_map, sc->sc_tmr_kva, + size, NULL, BUS_DMA_WAITOK); + if (error) + goto fail_3; + memset(&init, 0, sizeof(init)); init.enable_es = 1; init.tmr_length = PSP_TMR_SIZE; init.tmr_paddr = sc->sc_tmr_map->dm_segs[0].ds_addr; - if (psp_init(sc, &init)) - goto fail_3; + if ((error = psp_init(sc, &init)) != 0) + goto fail_4; return (0); -fail_3: +fail_4: bus_dmamap_unload(sc->sc_dmat, sc->sc_tmr_map); -fail_2: +fail_3: bus_dmamem_unmap(sc->sc_dmat, sc->sc_tmr_kva, size); +fail_2: + bus_dmamem_free(sc->sc_dmat, &sc->sc_tmr_seg, nsegs); fail_1: - bus_dmamem_free(sc->sc_dmat, &sc->sc_tmr_seg, 1); -fail_0: bus_dmamap_destroy(sc->sc_dmat, sc->sc_tmr_map); - - return (ENOMEM); +fail_0: + return (error); } int psp_shutdown(struct psp_softc *sc) { - int ret; + int error; if (sc->sc_tmr_map == NULL) return (EINVAL); - ret = ccp_docmd(sc, PSP_CMD_SHUTDOWN, 0x0); - - if (ret != 0) - return (EIO); + error = ccp_docmd(sc, PSP_CMD_SHUTDOWN, 0x0); + if (error) + return (error); /* wbinvd right after SHUTDOWN */ wbinvd_on_all_cpus_acked(); @@ -372,17 +375,16 @@ psp_shutdown(struct psp_softc *sc) int psp_get_pstatus(struct psp_softc *sc, struct psp_platform_status *ustatus) { - struct psp_platform_status *status; - int ret; + struct psp_platform_status *status; + int error; status = (struct psp_platform_status *)sc->sc_cmd_kva; bzero(status, sizeof(*status)); - ret = ccp_docmd(sc, PSP_CMD_PLATFORMSTATUS, + error = ccp_docmd(sc, PSP_CMD_PLATFORMSTATUS, sc->sc_cmd_map->dm_segs[0].ds_addr); - - if (ret != 0) - return (EIO); + if (error) + return (error); bcopy(status, ustatus, sizeof(*ustatus)); @@ -392,54 +394,47 @@ psp_get_pstatus(struct psp_softc *sc, struct psp_platform_status *ustatus) int psp_df_flush(struct psp_softc *sc) { - int ret; + int error; wbinvd_on_all_cpus_acked(); - ret = ccp_docmd(sc, PSP_CMD_DF_FLUSH, 0x0); - - if (ret != 0) - return (EIO); + error = ccp_docmd(sc, PSP_CMD_DF_FLUSH, 0x0); - return (0); + return (error); } int psp_decommission(struct psp_softc *sc, struct psp_decommission *udecom) { struct psp_decommission *decom; - int ret; + int error; decom = (struct psp_decommission *)sc->sc_cmd_kva; bzero(decom, sizeof(*decom)); decom->handle = udecom->handle; - ret = ccp_docmd(sc, PSP_CMD_DECOMMISSION, + error = ccp_docmd(sc, PSP_CMD_DECOMMISSION, sc->sc_cmd_map->dm_segs[0].ds_addr); - if (ret != 0) - return (EIO); - - return (0); + return (error); } int psp_get_gstatus(struct psp_softc *sc, struct psp_guest_status *ustatus) { struct psp_guest_status *status; - int ret; + int error; status = (struct psp_guest_status *)sc->sc_cmd_kva; bzero(status, sizeof(*status)); status->handle = ustatus->handle; - ret = ccp_docmd(sc, PSP_CMD_GUESTSTATUS, + error = ccp_docmd(sc, PSP_CMD_GUESTSTATUS, sc->sc_cmd_map->dm_segs[0].ds_addr); - - if (ret != 0) - return (EIO); + if (error) + return (error); ustatus->policy = status->policy; ustatus->asid = status->asid; @@ -452,7 +447,7 @@ int psp_launch_start(struct psp_softc *sc, struct psp_launch_start *ustart) { struct psp_launch_start *start; - int ret; + int error; start = (struct psp_launch_start *)sc->sc_cmd_kva; bzero(start, sizeof(*start)); @@ -460,11 +455,10 @@ psp_launch_start(struct psp_softc *sc, struct psp_launch_start *ustart) start->handle = ustart->handle; start->policy = ustart->policy; - ret = ccp_docmd(sc, PSP_CMD_LAUNCH_START, + error = ccp_docmd(sc, PSP_CMD_LAUNCH_START, sc->sc_cmd_map->dm_segs[0].ds_addr); - - if (ret != 0) - return (EIO); + if (error) + return (error); /* If requested, return new handle. */ if (ustart->handle == 0) @@ -481,7 +475,7 @@ psp_launch_update_data(struct psp_softc *sc, pmap_t pmap; vaddr_t v, next, start, end; size_t size, len, off; - int ret; + int error; /* Ensure AES_XTS_BLOCKSIZE alignment and multiplicity. */ if ((ulud->paddr & (AES_XTS_BLOCKSIZE - 1)) != 0 || @@ -508,10 +502,9 @@ psp_launch_update_data(struct psp_softc *sc, size = ulud->length; end = start + size; - ret = EINVAL; - /* Wire mapping. */ - if (uvm_map_pageable(&p->p_vmspace->vm_map, start, end, FALSE, 0)) + error = uvm_map_pageable(&p->p_vmspace->vm_map, start, end, FALSE, 0); + if (error) goto out; for (v = ulud->paddr; v < end; v = next) { @@ -519,36 +512,37 @@ psp_launch_update_data(struct psp_softc *sc, len = MIN(PAGE_SIZE - off, size); - if (!pmap_extract(pmap, v, (paddr_t *)&ludata->paddr)) + if (!pmap_extract(pmap, v, (paddr_t *)&ludata->paddr)) { + error = EINVAL; goto out; + } ludata->length = len; - ret = ccp_docmd(sc, PSP_CMD_LAUNCH_UPDATE_DATA, + error = ccp_docmd(sc, PSP_CMD_LAUNCH_UPDATE_DATA, sc->sc_cmd_map->dm_segs[0].ds_addr); - - if (ret != 0) { - ret = EIO; + if (error) goto out; - } size -= len; next = v + len; } out: - /* Unwire again. */ - if (uvm_map_pageable(&p->p_vmspace->vm_map, start, end, TRUE, 0)) - return (EINVAL); + /* + * Unwire again. Ignore new error. Error has either been set, + * or PSP command has already succeeded. + */ + (void) uvm_map_pageable(&p->p_vmspace->vm_map, start, end, TRUE, 0); - return (ret); + return (error); } int psp_launch_measure(struct psp_softc *sc, struct psp_launch_measure *ulm) { - struct psp_launch_measure *lm; - int ret; - uint64_t paddr; + struct psp_launch_measure *lm; + uint64_t paddr; + int error; if (ulm->measure_len != sizeof(ulm->psp_measure)) return (EINVAL); @@ -562,10 +556,11 @@ psp_launch_measure(struct psp_softc *sc, struct psp_launch_measure *ulm) paddr + offsetof(struct psp_launch_measure, psp_measure); lm->measure_len = sizeof(lm->psp_measure); - ret = ccp_docmd(sc, PSP_CMD_LAUNCH_MEASURE, paddr); - - if (ret != 0 || lm->measure_len != ulm->measure_len) - return (EIO); + error = ccp_docmd(sc, PSP_CMD_LAUNCH_MEASURE, paddr); + if (error) + return (error); + if (lm->measure_len != ulm->measure_len) + return (ERANGE); bcopy(&lm->psp_measure, &ulm->psp_measure, ulm->measure_len); @@ -575,29 +570,26 @@ psp_launch_measure(struct psp_softc *sc, struct psp_launch_measure *ulm) int psp_launch_finish(struct psp_softc *sc, struct psp_launch_finish *ulf) { - struct psp_launch_finish *lf; - int ret; + struct psp_launch_finish *lf; + int error; lf = (struct psp_launch_finish *)sc->sc_cmd_kva; bzero(lf, sizeof(*lf)); lf->handle = ulf->handle; - ret = ccp_docmd(sc, PSP_CMD_LAUNCH_FINISH, + error = ccp_docmd(sc, PSP_CMD_LAUNCH_FINISH, sc->sc_cmd_map->dm_segs[0].ds_addr); - if (ret != 0) - return (EIO); - - return (0); + return (error); } int psp_attestation(struct psp_softc *sc, struct psp_attestation *uat) { struct psp_attestation *at; - int ret; uint64_t paddr; + int error; if (uat->attest_len != sizeof(uat->psp_report)) return (EINVAL); @@ -612,10 +604,11 @@ psp_attestation(struct psp_softc *sc, struct psp_attestation *uat) bcopy(uat->attest_nonce, at->attest_nonce, sizeof(at->attest_nonce)); at->attest_len = sizeof(at->psp_report); - ret = ccp_docmd(sc, PSP_CMD_ATTESTATION, paddr); - - if (ret != 0 || at->attest_len != uat->attest_len) - return (EIO); + error = ccp_docmd(sc, PSP_CMD_ATTESTATION, paddr); + if (error) + return (error); + if (at->attest_len != uat->attest_len) + return (ERANGE); bcopy(&at->psp_report, &uat->psp_report, uat->attest_len); @@ -626,7 +619,7 @@ int psp_activate(struct psp_softc *sc, struct psp_activate *uact) { struct psp_activate *act; - int ret; + int error; act = (struct psp_activate *)sc->sc_cmd_kva; bzero(act, sizeof(*act)); @@ -634,82 +627,78 @@ psp_activate(struct psp_softc *sc, struct psp_activate *uact) act->handle = uact->handle; act->asid = uact->asid; - ret = ccp_docmd(sc, PSP_CMD_ACTIVATE, + error = ccp_docmd(sc, PSP_CMD_ACTIVATE, sc->sc_cmd_map->dm_segs[0].ds_addr); - if (ret != 0) - return (EIO); - - return (0); + return (error); } int psp_deactivate(struct psp_softc *sc, struct psp_deactivate *udeact) { struct psp_deactivate *deact; - int ret; + int error; deact = (struct psp_deactivate *)sc->sc_cmd_kva; bzero(deact, sizeof(*deact)); deact->handle = udeact->handle; - ret = ccp_docmd(sc, PSP_CMD_DEACTIVATE, + error = ccp_docmd(sc, PSP_CMD_DEACTIVATE, sc->sc_cmd_map->dm_segs[0].ds_addr); - if (ret != 0) - return (EIO); - - return (0); + return (error); } int psp_downloadfirmware(struct psp_softc *sc, struct psp_downloadfirmware *udlfw) { - struct psp_downloadfirmware *dlfw; - bus_dmamap_t map; - bus_dma_segment_t seg; - caddr_t kva; - int nsegs; - int ret; + struct psp_downloadfirmware *dlfw; + bus_dmamap_t map; + bus_dma_segment_t seg; + caddr_t kva; + int nsegs, error; dlfw = (struct psp_downloadfirmware *)sc->sc_cmd_kva; bzero(dlfw, sizeof(*dlfw)); - ret = ENOMEM; - if (bus_dmamap_create(sc->sc_dmat, udlfw->fw_len, 1, udlfw->fw_len, 0, - BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &map) != 0) - return (ret); - if (bus_dmamem_alloc(sc->sc_dmat, udlfw->fw_len, 0, 0, &seg, 1, - &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO) != 0 || nsegs != 1) + error = bus_dmamap_create(sc->sc_dmat, udlfw->fw_len, 1, udlfw->fw_len, + 0, BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW | BUS_DMA_64BIT, &map); + if (error) goto fail_0; - if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs, udlfw->fw_len, &kva, - BUS_DMA_WAITOK) != 0) + + error = bus_dmamem_alloc(sc->sc_dmat, udlfw->fw_len, 0, 0, &seg, 1, + &nsegs, BUS_DMA_WAITOK | BUS_DMA_ZERO); + if (error) goto fail_1; - if (bus_dmamap_load(sc->sc_dmat, map, kva, udlfw->fw_len, NULL, - BUS_DMA_WAITOK) != 0) + + error = bus_dmamem_map(sc->sc_dmat, &seg, nsegs, udlfw->fw_len, &kva, + BUS_DMA_WAITOK); + if (error) goto fail_2; + error = bus_dmamap_load(sc->sc_dmat, map, kva, udlfw->fw_len, NULL, + BUS_DMA_WAITOK); + if (error) + goto fail_3; + bcopy((void *)udlfw->fw_paddr, kva, udlfw->fw_len); dlfw->fw_paddr = map->dm_segs[0].ds_addr; dlfw->fw_len = map->dm_segs[0].ds_len; - ret = ccp_docmd(sc, PSP_CMD_DOWNLOADFIRMWARE, + error = ccp_docmd(sc, PSP_CMD_DOWNLOADFIRMWARE, sc->sc_cmd_map->dm_segs[0].ds_addr); - if (ret != 0) - ret = EIO; - bus_dmamap_unload(sc->sc_dmat, map); -fail_2: +fail_3: bus_dmamem_unmap(sc->sc_dmat, kva, udlfw->fw_len); +fail_2: + bus_dmamem_free(sc->sc_dmat, &seg, nsegs); fail_1: - bus_dmamem_free(sc->sc_dmat, &seg, 1); -fail_0: bus_dmamap_destroy(sc->sc_dmat, map); - - return (ret); +fail_0: + return (error); } int @@ -717,20 +706,20 @@ psp_guest_shutdown(struct psp_softc *sc, struct psp_guest_shutdown *ugshutdown) { struct psp_deactivate deact; struct psp_decommission decom; - int ret; + int error; bzero(&deact, sizeof(deact)); deact.handle = ugshutdown->handle; - if ((ret = psp_deactivate(sc, &deact)) != 0) - return (ret); + if ((error = psp_deactivate(sc, &deact)) != 0) + return (error); - if ((ret = psp_df_flush(sc)) != 0) - return (ret); + if ((error = psp_df_flush(sc)) != 0) + return (error); bzero(&decom, sizeof(decom)); decom.handle = ugshutdown->handle; - if ((ret = psp_decommission(sc, &decom)) != 0) - return (ret); + if ((error = psp_decommission(sc, &decom)) != 0) + return (error); return (0); } @@ -739,17 +728,16 @@ int psp_snp_get_pstatus(struct psp_softc *sc, struct psp_snp_platform_status *ustatus) { - struct psp_snp_platform_status *status; - int ret; + struct psp_snp_platform_status *status; + int error; status = (struct psp_snp_platform_status *)sc->sc_cmd_kva; bzero(status, sizeof(*status)); - ret = ccp_docmd(sc, PSP_CMD_SNP_PLATFORMSTATUS, + error = ccp_docmd(sc, PSP_CMD_SNP_PLATFORMSTATUS, sc->sc_cmd_map->dm_segs[0].ds_addr); - - if (ret != 0) - return (EIO); + if (error) + return (error); bcopy(status, ustatus, sizeof(*ustatus)); @@ -765,7 +753,8 @@ pspopen(dev_t dev, int flag, int mode, struct proc *p) if (sc == NULL) return (ENXIO); - psp_load_ucode(sc); + /* Ignore error, proceed without new firmware. */ + (void) psp_load_ucode(sc); if (!(sc->sc_flags & PSPF_INITIALIZED)) return (psp_reinit(sc)); @@ -788,8 +777,8 @@ pspclose(dev_t dev, int flag, int mode, struct proc *p) int pspioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) { - struct psp_softc *sc; - int ret; + struct psp_softc *sc; + int error; sc = (struct psp_softc *)device_lookup(&psp_cd, minor(dev)); if (sc == NULL) @@ -801,54 +790,56 @@ pspioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) switch (cmd) { case PSP_IOC_INIT: - ret = psp_reinit(sc); + error = psp_reinit(sc); break; case PSP_IOC_SHUTDOWN: - ret = psp_shutdown(sc); + error = psp_shutdown(sc); break; case PSP_IOC_GET_PSTATUS: - ret = psp_get_pstatus(sc, (struct psp_platform_status *)data); + error = psp_get_pstatus(sc, (struct psp_platform_status *)data); break; case PSP_IOC_DF_FLUSH: - ret = psp_df_flush(sc); + error = psp_df_flush(sc); break; case PSP_IOC_DECOMMISSION: - ret = psp_decommission(sc, (struct psp_decommission *)data); + error = psp_decommission(sc, (struct psp_decommission *)data); break; case PSP_IOC_GET_GSTATUS: - ret = psp_get_gstatus(sc, (struct psp_guest_status *)data); + error = psp_get_gstatus(sc, (struct psp_guest_status *)data); break; case PSP_IOC_LAUNCH_START: - ret = psp_launch_start(sc, (struct psp_launch_start *)data); + error = psp_launch_start(sc, (struct psp_launch_start *)data); break; case PSP_IOC_LAUNCH_UPDATE_DATA: - ret = psp_launch_update_data(sc, + error = psp_launch_update_data(sc, (struct psp_launch_update_data *)data, p); break; case PSP_IOC_LAUNCH_MEASURE: - ret = psp_launch_measure(sc, (struct psp_launch_measure *)data); + error = psp_launch_measure(sc, + (struct psp_launch_measure *)data); break; case PSP_IOC_LAUNCH_FINISH: - ret = psp_launch_finish(sc, (struct psp_launch_finish *)data); + error = psp_launch_finish(sc, (struct psp_launch_finish *)data); break; case PSP_IOC_ATTESTATION: - ret = psp_attestation(sc, (struct psp_attestation *)data); + error = psp_attestation(sc, (struct psp_attestation *)data); break; case PSP_IOC_ACTIVATE: - ret = psp_activate(sc, (struct psp_activate *)data); + error = psp_activate(sc, (struct psp_activate *)data); break; case PSP_IOC_DEACTIVATE: - ret = psp_deactivate(sc, (struct psp_deactivate *)data); + error = psp_deactivate(sc, (struct psp_deactivate *)data); break; case PSP_IOC_GUEST_SHUTDOWN: - ret = psp_guest_shutdown(sc, (struct psp_guest_shutdown *)data); + error = psp_guest_shutdown(sc, + (struct psp_guest_shutdown *)data); break; case PSP_IOC_SNP_GET_PSTATUS: - ret = psp_snp_get_pstatus(sc, + error = psp_snp_get_pstatus(sc, (struct psp_snp_platform_status *)data); break; default: - ret = ENOTTY; + error = ENOTTY; break; } @@ -856,7 +847,7 @@ pspioctl(dev_t dev, u_long cmd, caddr_t data, int flag, struct proc *p) KERNEL_LOCK(); - return (ret); + return (error); } int @@ -907,7 +898,7 @@ struct ucode { { 0, 0, NULL } }; -void +int psp_load_ucode(struct psp_softc *sc) { struct psp_downloadfirmware dlfw; @@ -919,7 +910,7 @@ psp_load_ucode(struct psp_softc *sc) if ((sc->sc_flags & PSPF_UCODELOADED) || (sc->sc_flags & PSPF_NOUCODE) || (sc->sc_flags & PSPF_INITIALIZED)) - return; + return (EBUSY); family = ci->ci_family; model = (ci->ci_model & 0xf0) >> 4; @@ -933,7 +924,7 @@ psp_load_ucode(struct psp_softc *sc) printf("%s: no firmware found, CPU family 0x%x model 0x%x\n", sc->sc_dev.dv_xname, family, model); sc->sc_flags |= PSPF_NOUCODE; - return; + return (EOPNOTSUPP); } error = loadfirmware(uc->uname, &sc->sc_ucodebuf, &sc->sc_ucodelen); @@ -943,14 +934,14 @@ psp_load_ucode(struct psp_softc *sc) sc->sc_dev.dv_xname, error, uc->uname); } sc->sc_flags |= PSPF_NOUCODE; - return; + return (error); } bzero(&dlfw, sizeof(dlfw)); dlfw.fw_len = sc->sc_ucodelen; dlfw.fw_paddr = (uint64_t)sc->sc_ucodebuf; - if (psp_downloadfirmware(sc, &dlfw) < 0) + if ((error = psp_downloadfirmware(sc, &dlfw)) != 0) goto out; sc->sc_flags |= PSPF_UCODELOADED; @@ -960,4 +951,6 @@ out: sc->sc_ucodebuf = NULL; sc->sc_ucodelen = 0; } + + return (error); } |