aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Pronchery <pierre@freebsdfoundation.org>2024-09-18 18:52:04 +0000
committerEd Maste <emaste@FreeBSD.org>2024-09-25 16:50:41 +0000
commit39f39a96569dc9f8ca9fc8ee351d3d6edabfb631 (patch)
treeeb4b3edd8c2e56f97c7e1ade4cdcf9cbd5d304af
parent5754008f8511ba95d84a35a1a91ff4e0682dee99 (diff)
bhyve: simplify slot validation in xHCI emulation
This is a follow-up to commit e72d86ad9c62 ("bhyve: improve input validation in pci_xhci") -- introducing a helper for slot validation. Co-authored-by: John Baldwin <jhb@FreeBSD.org> Reviewed by: markj, emaste Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46696 (cherry picked from commit f505f9a842eb3e75e16e6c7c6f67d5b592b1bc65)
-rw-r--r--usr.sbin/bhyve/pci_xhci.c90
1 files changed, 32 insertions, 58 deletions
diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c
index 77b17d525bdd..43f30c85d85f 100644
--- a/usr.sbin/bhyve/pci_xhci.c
+++ b/usr.sbin/bhyve/pci_xhci.c
@@ -348,6 +348,7 @@ static void pci_xhci_update_ep_ring(struct pci_xhci_softc *sc,
struct pci_xhci_dev_emu *dev, struct pci_xhci_dev_ep *devep,
struct xhci_endp_ctx *ep_ctx, uint32_t streamid,
uint64_t ringaddr, int ccs);
+static int pci_xhci_validate_slot(uint32_t slot);
static void
pci_xhci_set_evtrb(struct xhci_trb *evtrb, uint64_t port, uint32_t errcode,
@@ -849,17 +850,14 @@ pci_xhci_cmd_disable_slot(struct pci_xhci_softc *sc, uint32_t slot)
DPRINTF(("pci_xhci disable slot %u", slot));
- cmderr = XHCI_TRB_ERROR_NO_SLOTS;
- if (sc->portregs == NULL)
+ if (sc->portregs == NULL) {
+ cmderr = XHCI_TRB_ERROR_NO_SLOTS;
goto done;
+ }
- if (slot == 0) {
- cmderr = XHCI_TRB_ERROR_TRB;
- goto done;
- } else if (slot > XHCI_MAX_SLOTS) {
- cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
+ cmderr = pci_xhci_validate_slot(slot);
+ if (cmderr != XHCI_TRB_ERROR_SUCCESS)
goto done;
- }
dev = XHCI_SLOTDEV_PTR(sc, slot);
if (dev) {
@@ -867,7 +865,6 @@ pci_xhci_cmd_disable_slot(struct pci_xhci_softc *sc, uint32_t slot)
cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
} else {
dev->dev_slotstate = XHCI_ST_DISABLED;
- cmderr = XHCI_TRB_ERROR_SUCCESS;
/* TODO: reset events and endpoints */
}
} else
@@ -886,19 +883,16 @@ pci_xhci_cmd_reset_device(struct pci_xhci_softc *sc, uint32_t slot)
uint32_t cmderr;
int i;
- cmderr = XHCI_TRB_ERROR_NO_SLOTS;
- if (sc->portregs == NULL)
+ if (sc->portregs == NULL) {
+ cmderr = XHCI_TRB_ERROR_NO_SLOTS;
goto done;
+ }
DPRINTF(("pci_xhci reset device slot %u", slot));
- if (slot == 0) {
- cmderr = XHCI_TRB_ERROR_TRB;
+ cmderr = pci_xhci_validate_slot(slot);
+ if (cmderr != XHCI_TRB_ERROR_SUCCESS)
goto done;
- } else if (slot > XHCI_MAX_SLOTS) {
- cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
- goto done;
- }
dev = XHCI_SLOTDEV_PTR(sc, slot);
if (!dev || dev->dev_slotstate == XHCI_ST_DISABLED)
@@ -928,8 +922,6 @@ pci_xhci_cmd_reset_device(struct pci_xhci_softc *sc, uint32_t slot)
ep_ctx->dwEpCtx0 = FIELD_REPLACE( ep_ctx->dwEpCtx0,
XHCI_ST_EPCTX_DISABLED, 0x7, 0);
}
-
- cmderr = XHCI_TRB_ERROR_SUCCESS;
}
pci_xhci_reset_slot(sc, slot);
@@ -953,8 +945,6 @@ pci_xhci_cmd_address_device(struct pci_xhci_softc *sc, uint32_t slot,
islot_ctx = &input_ctx->ctx_slot;
ep0_ctx = &input_ctx->ctx_ep[1];
- cmderr = XHCI_TRB_ERROR_SUCCESS;
-
DPRINTF(("pci_xhci: address device, input ctl: D 0x%08x A 0x%08x,",
input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1));
DPRINTF((" slot %08x %08x %08x %08x",
@@ -972,13 +962,9 @@ pci_xhci_cmd_address_device(struct pci_xhci_softc *sc, uint32_t slot,
goto done;
}
- if (slot == 0) {
- cmderr = XHCI_TRB_ERROR_TRB;
+ cmderr = pci_xhci_validate_slot(slot);
+ if (cmderr != XHCI_TRB_ERROR_SUCCESS)
goto done;
- } else if (slot > XHCI_MAX_SLOTS) {
- cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
- goto done;
- }
/* assign address to slot */
dev_ctx = pci_xhci_get_dev_ctx(sc, slot);
@@ -1042,17 +1028,11 @@ pci_xhci_cmd_config_ep(struct pci_xhci_softc *sc, uint32_t slot,
uint32_t cmderr;
int i;
- cmderr = XHCI_TRB_ERROR_SUCCESS;
-
DPRINTF(("pci_xhci config_ep slot %u", slot));
- if (slot == 0) {
- cmderr = XHCI_TRB_ERROR_TRB;
+ cmderr = pci_xhci_validate_slot(slot);
+ if (cmderr != XHCI_TRB_ERROR_SUCCESS)
goto done;
- } else if (slot > XHCI_MAX_SLOTS) {
- cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
- goto done;
- }
dev = XHCI_SLOTDEV_PTR(sc, slot);
assert(dev != NULL);
@@ -1175,15 +1155,9 @@ pci_xhci_cmd_reset_ep(struct pci_xhci_softc *sc, uint32_t slot,
DPRINTF(("pci_xhci: reset ep %u: slot %u", epid, slot));
- cmderr = XHCI_TRB_ERROR_SUCCESS;
-
- if (slot == 0) {
- cmderr = XHCI_TRB_ERROR_TRB;
- goto done;
- } else if (slot > XHCI_MAX_SLOTS) {
- cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
+ cmderr = pci_xhci_validate_slot(slot);
+ if (cmderr != XHCI_TRB_ERROR_SUCCESS)
goto done;
- }
dev = XHCI_SLOTDEV_PTR(sc, slot);
assert(dev != NULL);
@@ -1272,15 +1246,9 @@ pci_xhci_cmd_set_tr(struct pci_xhci_softc *sc, uint32_t slot,
uint32_t cmderr, epid;
uint32_t streamid;
- cmderr = XHCI_TRB_ERROR_SUCCESS;
-
- if (slot == 0) {
- cmderr = XHCI_TRB_ERROR_TRB;
- goto done;
- } else if (slot > XHCI_MAX_SLOTS) {
- cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
+ cmderr = pci_xhci_validate_slot(slot);
+ if (cmderr != XHCI_TRB_ERROR_SUCCESS)
goto done;
- }
dev = XHCI_SLOTDEV_PTR(sc, slot);
assert(dev != NULL);
@@ -1362,7 +1330,6 @@ pci_xhci_cmd_eval_ctx(struct pci_xhci_softc *sc, uint32_t slot,
islot_ctx = &input_ctx->ctx_slot;
ep0_ctx = &input_ctx->ctx_ep[1];
- cmderr = XHCI_TRB_ERROR_SUCCESS;
DPRINTF(("pci_xhci: eval ctx, input ctl: D 0x%08x A 0x%08x,",
input_ctx->ctx_input.dwInCtx0, input_ctx->ctx_input.dwInCtx1));
DPRINTF((" slot %08x %08x %08x %08x",
@@ -1380,13 +1347,9 @@ pci_xhci_cmd_eval_ctx(struct pci_xhci_softc *sc, uint32_t slot,
goto done;
}
- if (slot == 0) {
- cmderr = XHCI_TRB_ERROR_TRB;
- goto done;
- } else if (slot > XHCI_MAX_SLOTS) {
- cmderr = XHCI_TRB_ERROR_SLOT_NOT_ON;
+ cmderr = pci_xhci_validate_slot(slot);
+ if (cmderr != XHCI_TRB_ERROR_SUCCESS)
goto done;
- }
/* assign address to slot; in this emulation, slot_id = address */
dev_ctx = pci_xhci_get_dev_ctx(sc, slot);
@@ -1723,6 +1686,17 @@ pci_xhci_update_ep_ring(struct pci_xhci_softc *sc,
}
}
+static int
+pci_xhci_validate_slot(uint32_t slot)
+{
+ if (slot == 0)
+ return (XHCI_TRB_ERROR_TRB);
+ else if (slot > XHCI_MAX_SLOTS)
+ return (XHCI_TRB_ERROR_SLOT_NOT_ON);
+ else
+ return (XHCI_TRB_ERROR_SUCCESS);
+}
+
/*
* Outstanding transfer still in progress (device NAK'd earlier) so retry
* the transfer again to see if it succeeds.