You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.7 KiB
88 lines
2.7 KiB
7 years ago
|
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: 李强 <address@hidden>
|
||
|
Signed-off-by: Gerd Hoffmann <address@hidden>
|
||
|
---
|
||
|
hw/usb/hcd-xhci.c | 15 ++++++++++++++-
|
||
|
hw/usb/trace-events | 1 +
|
||
|
2 files changed, 15 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
|
||
|
index fbf8a8b..28dd2f2 100644
|
||
|
--- a/hw/usb/hcd-xhci.c
|
||
|
+++ b/hw/usb/hcd-xhci.c
|
||
|
@@ -51,6 +51,8 @@
|
||
|
#define EV_QUEUE (((3 * 24) + 16) * MAXSLOTS)
|
||
|
|
||
|
#define TRB_LINK_LIMIT 4
|
||
|
+#define COMMAND_LIMIT 256
|
||
|
+#define TRANSFER_LIMIT 256
|
||
|
|
||
|
#define LEN_CAP 0x40
|
||
|
#define LEN_OPER (0x400 + 0x10 * MAXPORTS)
|
||
|
@@ -943,6 +945,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);
|
||
|
@@ -2060,6 +2063,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;
|
||
|
|
||
|
@@ -2172,6 +2176,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--;
|
||
|
|
||
|
@@ -2618,7 +2626,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)) {
|
||
|
@@ -2735,6 +2743,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;
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff --git a/hw/usb/trace-events b/hw/usb/trace-events
|
||
|
index fdd1d29..0c323d4 100644
|
||
|
--- a/hw/usb/trace-events
|
||
|
+++ b/hw/usb/trace-events
|
||
|
@@ -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"
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|