Add an extra patch to really fix (bz #890320)

This commit is contained in:
Hans de Goede 2013-04-08 23:42:51 +02:00
parent 6a0fe9263d
commit 4a0d0c08f7
2 changed files with 91 additions and 6 deletions

View File

@ -0,0 +1,80 @@
From 2d608503da16560546ed6c0f04cac87601856412 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Fri, 5 Apr 2013 12:05:49 +0200
Subject: [PATCH] ehci_free_packet: Discard finished packets when the queue is
halted
With pipelining it is possible to encounter a finished packet when cleaning
the queue due to a halt. This happens when a non stall error happens while
talking to a real device. In this case the queue on the usb-host side will
continue processing packets, and we can have completed packets waiting in
the queue after an error condition packet causing a halt.
There are 2 reasons to discard the completed packets at this point, rather
then writing them back to the guest:
1) The guest expect to be able to cancel and/or change packets after the
packet with the error without doing an unlink, so writing them back may
confuse the guest.
2) Since the queue does not advance when halted, the writing back of these
packets will trigger an assert because p->qtdaddr != q->qtdaddr, causing qemu
to abort.
Note that discarding these packets means that the guest driver and the device
will get out of sync! This is unfortunate, but should not be a problem since
with a non stall error (iow an io-error) the 2 are out of sync already anyways.
Still this patch adds a warning printf to signal this happening.
Note that sofar this has only been seen with a DVB-T receiver, which gives
of a MPEG-2 stream, which allows for recovering from lost packets, see:
https://bugzilla.redhat.com/show_bug.cgi?id=890320
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
hw/usb/hcd-ehci.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index 6be11c5..6a787aa 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -752,11 +752,10 @@ static EHCIPacket *ehci_alloc_packet(EHCIQueue *q)
static void ehci_free_packet(EHCIPacket *p)
{
- if (p->async == EHCI_ASYNC_FINISHED) {
+ if (p->async == EHCI_ASYNC_FINISHED &&
+ !(p->queue->qh.token & QTD_TOKEN_HALT)) {
EHCIQueue *q = p->queue;
int state = ehci_get_state(q->ehci, q->async);
- /* This is a normal, but rare condition (cancel racing completion) */
- fprintf(stderr, "EHCI: Warning packet completed but not processed\n");
ehci_state_executing(q);
ehci_state_writeback(q);
if (!(q->qh.token & QTD_TOKEN_HALT)) {
@@ -767,12 +766,17 @@ static void ehci_free_packet(EHCIPacket *p)
return;
}
trace_usb_ehci_packet_action(p->queue, p, "free");
- if (p->async == EHCI_ASYNC_INITIALIZED) {
- usb_packet_unmap(&p->packet, &p->sgl);
- qemu_sglist_destroy(&p->sgl);
- }
if (p->async == EHCI_ASYNC_INFLIGHT) {
usb_cancel_packet(&p->packet);
+ }
+ if (p->async == EHCI_ASYNC_FINISHED) {
+ fprintf(stderr,
+ "EHCI: Dropping completed packet from halted %s ep %02X\n",
+ (p->pid == USB_TOKEN_IN) ? "in" : "out",
+ get_field(p->queue->qh.epchar, QH_EPCHAR_EP));
+
+ }
+ if (p->async != EHCI_ASYNC_NONE) {
usb_packet_unmap(&p->packet, &p->sgl);
qemu_sglist_destroy(&p->sgl);
}
--
1.8.2

View File

@ -109,7 +109,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 1.2.2
Release: 9%{?dist}
Release: 10%{?dist}
# Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
@ -548,6 +548,7 @@ Patch0717: 0717-qxl-Add-rom_size-compat-property-fix-migration-from-.patch
# Fix use after free + assert in ehci (bz #890320)
Patch0718: 0718-ehci-Don-t-access-packet-after-freeing-it.patch
Patch0719: 0719-ehci-Fixup-q-qtdaddr-after-cancelling-an-already-com.patch
Patch0720: 0720-ehci_free_packet-Discard-finished-packets-when-the-q.patch
BuildRequires: SDL-devel
@ -1383,6 +1384,7 @@ CAC emulation development files.
# Fix use after free + assert in ehci (bz #890320)
%patch0718 -p1
%patch0719 -p1
%patch0720 -p1
%build
@ -1992,6 +1994,9 @@ getent passwd qemu >/dev/null || \
%{_libdir}/pkgconfig/libcacard.pc
%changelog
* Mon Apr 08 2013 Hans de Goede <hdegoede@redhat.com> - 2:1.2.2-10
- Add an extra patch to really fix (bz #890320)
* Wed Apr 03 2013 Hans de Goede <hdegoede@redhat.com> - 2:1.2.2-9
- Fix use after free in ehci code (bz #890320)
@ -2394,7 +2399,7 @@ getent passwd qemu >/dev/null || \
* Thu Apr 15 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-5
- Update virtio console patches from upstream
* Mon Mar 11 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-4
* Thu Mar 11 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.3-4
- Detect cdrom via ioctl (#473154)
- re add increased buffer for USB control requests (#546483)
@ -2431,7 +2436,7 @@ getent passwd qemu >/dev/null || \
* Mon Jan 25 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.2-1
- Update to 0.12.2 upstream
* Fri Jan 10 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.1.2-3
* Sun Jan 10 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.1.2-3
- Point to seabios instead of bochs, and add a requires for seabios
* Mon Jan 4 2010 Justin M. Forbes <jforbes@redhat.com> - 2:0.12.1.2-2
@ -2879,7 +2884,7 @@ getent passwd qemu >/dev/null || \
- Update to 0.7.0
- Fix dyngen for PPC functions which end in unconditional branch
* Fri Apr 7 2005 Michael Schwendt <mschwendt[AT]users.sf.net>
* Thu Apr 7 2005 Michael Schwendt <mschwendt[AT]users.sf.net>
- rebuilt
* Sun Feb 13 2005 David Woodhouse <dwmw2@infradead.org> 0.6.1-2
@ -2891,13 +2896,13 @@ getent passwd qemu >/dev/null || \
* Tue Jul 20 2004 David Woodhouse <dwmw2@redhat.com> 0.6.0-2
- Compile fix from qemu CVS, add x86_64 host support
* Mon May 12 2004 David Woodhouse <dwmw2@redhat.com> 0.6.0-1
* Wed May 12 2004 David Woodhouse <dwmw2@redhat.com> 0.6.0-1
- Update to 0.6.0.
* Sat May 8 2004 David Woodhouse <dwmw2@redhat.com> 0.5.5-1
- Update to 0.5.5.
* Thu May 2 2004 David Woodhouse <dwmw2@redhat.com> 0.5.4-1
* Sun May 2 2004 David Woodhouse <dwmw2@redhat.com> 0.5.4-1
- Update to 0.5.4.
* Thu Apr 22 2004 David Woodhouse <dwmw2@redhat.com> 0.5.3-1