+From 04d46122655ea02ca47a9572bcce87a23c458e9a Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Mon, 18 Apr 2016 09:11:38 +0200
+Subject: [PATCH] ehci: apply limit to iTD/sidt descriptors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit "156a2e4 ehci: make idt processing more robust" tries to avoid a
+DoS by the guest (create a circular iTD queue and let qemu ehci
+emulation run in circles forever). Unfortunately this has two problems:
+First it misses the case of siTDs, and second it reportedly breaks
+FreeBSD.
+
+So lets go for a different approach: just count the number of iTDs and
+siTDs we have seen per frame and apply a limit. That should really
+catch all cases now.
+
+Reported-by: 杜少博 <dushaobo@360.cn>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-ehci.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
+index 9b7ef92..99ae453 100644
+--- a/hw/usb/hcd-ehci.c
++++ b/hw/usb/hcd-ehci.c
+@@ -2009,6 +2009,7 @@ static int ehci_state_writeback(EHCIQueue *q)
+ static void ehci_advance_state(EHCIState *ehci, int async)
+ {
+ EHCIQueue *q = NULL;
++ int itd_count = 0;
+ int again;
+
+ do {
+@@ -2033,10 +2034,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
+
+ case EST_FETCHITD:
+ again = ehci_state_fetchitd(ehci, async);
++ itd_count++;
+ break;
+
+ case EST_FETCHSITD:
+ again = ehci_state_fetchsitd(ehci, async);
++ itd_count++;
+ break;
+
+ case EST_ADVANCEQUEUE:
+@@ -2085,7 +2088,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
+ break;
+ }
+
+- if (again < 0) {
++ if (again < 0 || itd_count > 16) {
++ /* TODO: notify guest (raise HSE irq?) */
+ fprintf(stderr, "processing error - resetting ehci HC\n");
+ ehci_reset(ehci);
+ again = 0;
+--
+2.1.4
+