Skip to content

Commit

Permalink
xhci: apply limits to loops
Browse files Browse the repository at this point in the history
Limits should be big enough that normal guest should not hit it.
Add a tracepoint to log them, just in case.  Also, while being
at it, log the existing link trb limit too.

Reported-by: 李强 <[email protected]>
Signed-off-by: Gerd Hoffmann <[email protected]>
Message-id: [email protected]
  • Loading branch information
kraxel committed Feb 21, 2017
1 parent 95ed569 commit f89b60f
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
15 changes: 14 additions & 1 deletion hw/usb/hcd-xhci.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@
#define ER_FULL_HACK

#define TRB_LINK_LIMIT 4
#define COMMAND_LIMIT 256
#define TRANSFER_LIMIT 256

#define LEN_CAP 0x40
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
Expand Down Expand Up @@ -1032,6 +1034,7 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
return type;
} else {
if (++link_cnt > TRB_LINK_LIMIT) {
trace_usb_xhci_enforced_limit("trb-link");
return 0;
}
ring->dequeue = xhci_mask64(trb->parameter);
Expand Down Expand Up @@ -2150,6 +2153,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
XHCIRing *ring;
USBEndpoint *ep = NULL;
uint64_t mfindex;
unsigned int count = 0;
int length;
int i;

Expand Down Expand Up @@ -2262,6 +2266,10 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
epctx->retry = xfer;
break;
}
if (count++ > TRANSFER_LIMIT) {
trace_usb_xhci_enforced_limit("transfers");
break;
}
}
epctx->kick_active--;

Expand Down Expand Up @@ -2734,7 +2742,7 @@ static void xhci_process_commands(XHCIState *xhci)
TRBType type;
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
dma_addr_t addr;
unsigned int i, slotid = 0;
unsigned int i, slotid = 0, count = 0;

DPRINTF("xhci_process_commands()\n");
if (!xhci_running(xhci)) {
Expand Down Expand Up @@ -2848,6 +2856,11 @@ static void xhci_process_commands(XHCIState *xhci)
}
event.slotid = slotid;
xhci_event(xhci, &event, 0);

if (count++ > COMMAND_LIMIT) {
trace_usb_xhci_enforced_limit("commands");
return;
}
}
}

Expand Down
1 change: 1 addition & 0 deletions hw/usb/trace-events
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ usb_xhci_xfer_retry(void *xfer) "%p"
usb_xhci_xfer_success(void *xfer, uint32_t bytes) "%p: len %d"
usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d"
usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)"
usb_xhci_enforced_limit(const char *item) "%s"

# hw/usb/desc.c
usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
Expand Down

0 comments on commit f89b60f

Please sign in to comment.