diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 3b25abcacdf48eaaf2395f240d629622adacda39..7a318eb9679c9dd6f3c8a78bdcc2a4e6fb9091c4 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -22,6 +22,7 @@ #include "qemu/osdep.h" #include "hw/hw.h" #include "qemu/timer.h" +#include "qemu/log.h" #include "qemu/module.h" #include "qemu/queue.h" #include "hw/usb.h" @@ -770,7 +771,7 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) bool control_td_set = 0; uint32_t link_cnt = 0; - while (1) { + do { TRBType type; pci_dma_read(pci_dev, dequeue, &trb, TRB_SIZE); le64_to_cpus(&trb.parameter); @@ -806,7 +807,17 @@ static int xhci_ring_chain_length(XHCIState *xhci, const XHCIRing *ring) if (!control_td_set && !(trb.control & TRB_TR_CH)) { return length; } - } + + /* + * According to the xHCI spec, Transfer Ring segments should have + * a maximum size of 64 kB (see chapter "6 Data Structures") + */ + } while (length < TRB_LINK_LIMIT * 65536 / TRB_SIZE); + + qemu_log_mask(LOG_GUEST_ERROR, "%s: exceeded maximum tranfer ring size!\n", + __func__); + + return -1; } static void xhci_er_reset(XHCIState *xhci, int v)