* [Qemu-devel] [PATCH 1/4] xhci: only free completed transfers
2017-01-30 15:36 [Qemu-devel] [PATCH 0/4] xhci: fix misc regressions Gerd Hoffmann
@ 2017-01-30 15:36 ` Gerd Hoffmann
2017-01-30 15:36 ` [Qemu-devel] [PATCH 2/4] xhci: rename xhci_complete_packet to xhci_try_complete_packet Gerd Hoffmann
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2017-01-30 15:36 UTC (permalink / raw)
To: qemu-devel; +Cc: 1653384, fabian, Gerd Hoffmann
Most callsites check already, one was missed.
Cc: 1653384@bugs.launchpad.net
Fixes: 94b037f2a451b3dc855f9f2c346e5049a361bd55
Reported-by: Fabian Lesniak <fabian@lesniak-it.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/hcd-xhci.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index e0b5169..dd429dc 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2198,7 +2198,9 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
xhci_complete_packet(xfer);
}
assert(!xfer->running_retry);
- xhci_ep_free_xfer(epctx->retry);
+ if (xfer->complete) {
+ xhci_ep_free_xfer(epctx->retry);
+ }
epctx->retry = NULL;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 2/4] xhci: rename xhci_complete_packet to xhci_try_complete_packet
2017-01-30 15:36 [Qemu-devel] [PATCH 0/4] xhci: fix misc regressions Gerd Hoffmann
2017-01-30 15:36 ` [Qemu-devel] [PATCH 1/4] xhci: only free completed transfers Gerd Hoffmann
@ 2017-01-30 15:36 ` Gerd Hoffmann
2017-01-30 15:36 ` [Qemu-devel] [PATCH 3/4] xhci: don't kick in xhci_submit and xhci_fire_ctl_transfer Gerd Hoffmann
2017-01-30 15:36 ` [Qemu-devel] [PATCH 4/4] xhci: guard xhci_kick_epctx against recursive calls Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2017-01-30 15:36 UTC (permalink / raw)
To: qemu-devel; +Cc: 1653384, fabian, Gerd Hoffmann
Make clear that this isn't guaranteed to actually complete the transfer,
the usb packet can still be in flight after calling that function.
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/hcd-xhci.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index dd429dc..4e2807e 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -1897,7 +1897,7 @@ static int xhci_setup_packet(XHCITransfer *xfer)
return 0;
}
-static int xhci_complete_packet(XHCITransfer *xfer)
+static int xhci_try_complete_packet(XHCITransfer *xfer)
{
if (xfer->packet.status == USB_RET_ASYNC) {
trace_usb_xhci_xfer_async(xfer);
@@ -2002,7 +2002,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
- xhci_complete_packet(xfer);
+ xhci_try_complete_packet(xfer);
if (!xfer->running_async && !xfer->running_retry) {
xhci_kick_epctx(xfer->epctx, 0);
}
@@ -2106,7 +2106,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
}
usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
- xhci_complete_packet(xfer);
+ xhci_try_complete_packet(xfer);
if (!xfer->running_async && !xfer->running_retry) {
xhci_kick_epctx(xfer->epctx, xfer->streamid);
}
@@ -2185,7 +2185,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
}
usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
assert(xfer->packet.status != USB_RET_NAK);
- xhci_complete_packet(xfer);
+ xhci_try_complete_packet(xfer);
} else {
/* retry nak'ed transfer */
if (xhci_setup_packet(xfer) < 0) {
@@ -2195,7 +2195,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
if (xfer->packet.status == USB_RET_NAK) {
return;
}
- xhci_complete_packet(xfer);
+ xhci_try_complete_packet(xfer);
}
assert(!xfer->running_retry);
if (xfer->complete) {
@@ -3492,7 +3492,7 @@ static void xhci_complete(USBPort *port, USBPacket *packet)
xhci_ep_nuke_one_xfer(xfer, 0);
return;
}
- xhci_complete_packet(xfer);
+ xhci_try_complete_packet(xfer);
xhci_kick_epctx(xfer->epctx, xfer->streamid);
if (xfer->complete) {
xhci_ep_free_xfer(xfer);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 3/4] xhci: don't kick in xhci_submit and xhci_fire_ctl_transfer
2017-01-30 15:36 [Qemu-devel] [PATCH 0/4] xhci: fix misc regressions Gerd Hoffmann
2017-01-30 15:36 ` [Qemu-devel] [PATCH 1/4] xhci: only free completed transfers Gerd Hoffmann
2017-01-30 15:36 ` [Qemu-devel] [PATCH 2/4] xhci: rename xhci_complete_packet to xhci_try_complete_packet Gerd Hoffmann
@ 2017-01-30 15:36 ` Gerd Hoffmann
2017-01-30 15:36 ` [Qemu-devel] [PATCH 4/4] xhci: guard xhci_kick_epctx against recursive calls Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2017-01-30 15:36 UTC (permalink / raw)
To: qemu-devel; +Cc: 1653384, fabian, Gerd Hoffmann
xhci_submit and xhci_fire_ctl_transfer are is called from
xhci_kick_epctx processing loop only, so there is no need to call
xhci_kick_epctx make sure processing continues. Also eecursive calls
into xhci_kick_epctx can cause trouble.
Drop the xhci_kick_epctx calls.
Cc: 1653384@bugs.launchpad.net
Fixes: 94b037f2a451b3dc855f9f2c346e5049a361bd55
Reported-by: Fabian Lesniak <fabian@lesniak-it.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/hcd-xhci.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 4e2807e..899a410 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -2001,11 +2001,7 @@ static int xhci_fire_ctl_transfer(XHCIState *xhci, XHCITransfer *xfer)
xfer->packet.parameter = trb_setup->parameter;
usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
-
xhci_try_complete_packet(xfer);
- if (!xfer->running_async && !xfer->running_retry) {
- xhci_kick_epctx(xfer->epctx, 0);
- }
return 0;
}
@@ -2105,11 +2101,7 @@ static int xhci_submit(XHCIState *xhci, XHCITransfer *xfer, XHCIEPContext *epctx
return -1;
}
usb_handle_packet(xfer->packet.ep->dev, &xfer->packet);
-
xhci_try_complete_packet(xfer);
- if (!xfer->running_async && !xfer->running_retry) {
- xhci_kick_epctx(xfer->epctx, xfer->streamid);
- }
return 0;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [Qemu-devel] [PATCH 4/4] xhci: guard xhci_kick_epctx against recursive calls
2017-01-30 15:36 [Qemu-devel] [PATCH 0/4] xhci: fix misc regressions Gerd Hoffmann
` (2 preceding siblings ...)
2017-01-30 15:36 ` [Qemu-devel] [PATCH 3/4] xhci: don't kick in xhci_submit and xhci_fire_ctl_transfer Gerd Hoffmann
@ 2017-01-30 15:36 ` Gerd Hoffmann
3 siblings, 0 replies; 5+ messages in thread
From: Gerd Hoffmann @ 2017-01-30 15:36 UTC (permalink / raw)
To: qemu-devel; +Cc: 1653384, fabian, Gerd Hoffmann
Track xhci_kick_epctx processing being active in a variable. Check the
variable before calling xhci_kick_epctx from xhci_kick_ep. Add an
assert to make sure we don't call recursively into xhci_kick_epctx.
Cc: 1653384@bugs.launchpad.net
Fixes: 94b037f2a451b3dc855f9f2c346e5049a361bd55
Reported-by: Fabian Lesniak <fabian@lesniak-it.de>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
hw/usb/hcd-xhci.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 899a410..12cac89 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -390,6 +390,7 @@ struct XHCIEPContext {
dma_addr_t pctx;
unsigned int max_psize;
uint32_t state;
+ uint32_t kick_active;
/* streams */
unsigned int max_pstreams;
@@ -2131,6 +2132,9 @@ static void xhci_kick_ep(XHCIState *xhci, unsigned int slotid,
return;
}
+ if (!epctx->kick_active) {
+ return;
+ }
xhci_kick_epctx(epctx, streamid);
}
@@ -2155,6 +2159,9 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
return;
}
+ assert(!epctx->kick_active);
+ epctx->kick_active++;
+
if (epctx->retry) {
XHCITransfer *xfer = epctx->retry;
@@ -2253,6 +2260,7 @@ static void xhci_kick_epctx(XHCIEPContext *epctx, unsigned int streamid)
break;
}
}
+ epctx->kick_active--;
ep = xhci_epid_to_usbep(epctx);
if (ep) {
--
1.8.3.1
^ permalink raw reply related [flat|nested] 5+ messages in thread