mirror of https://github.com/xqemu/xqemu.git
xhci: apply limits to loops
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: 李强 <liqiang6-s@360.cn> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> Message-id: 1486383669-6421-1-git-send-email-kraxel@redhat.com
This commit is contained in:
parent
95ed56939e
commit
f89b60f6e5
|
@ -54,6 +54,8 @@
|
||||||
#define ER_FULL_HACK
|
#define ER_FULL_HACK
|
||||||
|
|
||||||
#define TRB_LINK_LIMIT 4
|
#define TRB_LINK_LIMIT 4
|
||||||
|
#define COMMAND_LIMIT 256
|
||||||
|
#define TRANSFER_LIMIT 256
|
||||||
|
|
||||||
#define LEN_CAP 0x40
|
#define LEN_CAP 0x40
|
||||||
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
|
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
|
||||||
|
@ -1032,6 +1034,7 @@ static TRBType xhci_ring_fetch(XHCIState *xhci, XHCIRing *ring, XHCITRB *trb,
|
||||||
return type;
|
return type;
|
||||||
} else {
|
} else {
|
||||||
if (++link_cnt > TRB_LINK_LIMIT) {
|
if (++link_cnt > TRB_LINK_LIMIT) {
|
||||||
|
trace_usb_xhci_enforced_limit("trb-link");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
ring->dequeue = xhci_mask64(trb->parameter);
|
ring->dequeue = xhci_mask64(trb->parameter);
|
||||||
|
@ -2150,6 +2153,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
|
||||||
XHCIRing *ring;
|
XHCIRing *ring;
|
||||||
USBEndpoint *ep = NULL;
|
USBEndpoint *ep = NULL;
|
||||||
uint64_t mfindex;
|
uint64_t mfindex;
|
||||||
|
unsigned int count = 0;
|
||||||
int length;
|
int length;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -2262,6 +2266,10 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
|
||||||
epctx->retry = xfer;
|
epctx->retry = xfer;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (count++ > TRANSFER_LIMIT) {
|
||||||
|
trace_usb_xhci_enforced_limit("transfers");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
epctx->kick_active--;
|
epctx->kick_active--;
|
||||||
|
|
||||||
|
@ -2734,7 +2742,7 @@ static void xhci_process_commands(XHCIState *xhci)
|
||||||
TRBType type;
|
TRBType type;
|
||||||
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
|
XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
|
||||||
dma_addr_t addr;
|
dma_addr_t addr;
|
||||||
unsigned int i, slotid = 0;
|
unsigned int i, slotid = 0, count = 0;
|
||||||
|
|
||||||
DPRINTF("xhci_process_commands()\n");
|
DPRINTF("xhci_process_commands()\n");
|
||||||
if (!xhci_running(xhci)) {
|
if (!xhci_running(xhci)) {
|
||||||
|
@ -2848,6 +2856,11 @@ static void xhci_process_commands(XHCIState *xhci)
|
||||||
}
|
}
|
||||||
event.slotid = slotid;
|
event.slotid = slotid;
|
||||||
xhci_event(xhci, &event, 0);
|
xhci_event(xhci, &event, 0);
|
||||||
|
|
||||||
|
if (count++ > COMMAND_LIMIT) {
|
||||||
|
trace_usb_xhci_enforced_limit("commands");
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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_success(void *xfer, uint32_t bytes) "%p: len %d"
|
||||||
usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %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_unimplemented(const char *item, int nr) "%s (0x%x)"
|
||||||
|
usb_xhci_enforced_limit(const char *item) "%s"
|
||||||
|
|
||||||
# hw/usb/desc.c
|
# hw/usb/desc.c
|
||||||
usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
|
usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
|
||||||
|
|
Loading…
Reference in New Issue