summary refs log tree commit diff
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2020-05-14 14:49:10 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-16 01:12:26 +0000
commit9a0ffde0537136c97c82fb76a004c7e1322e069b (patch)
treeb6b5226c5de71b933849e8498dad2fd3e91877d2
parent1182090a3eaeac27d476436c3588f58e5564f61f (diff)
downloadcrosvm-9a0ffde0537136c97c82fb76a004c7e1322e069b.tar
crosvm-9a0ffde0537136c97c82fb76a004c7e1322e069b.tar.gz
crosvm-9a0ffde0537136c97c82fb76a004c7e1322e069b.tar.bz2
crosvm-9a0ffde0537136c97c82fb76a004c7e1322e069b.tar.lz
crosvm-9a0ffde0537136c97c82fb76a004c7e1322e069b.tar.xz
crosvm-9a0ffde0537136c97c82fb76a004c7e1322e069b.tar.zst
crosvm-9a0ffde0537136c97c82fb76a004c7e1322e069b.zip
devices: usb: ignore busy flag in interrupter
This works around an issue where the xhci controller hangs from the
guest's point of view, with the guest kernel eventually timing out and
disabling the controller.

The xHCI spec says that the EHB (Event Handler Busy) bit should be
cleared before signalling another interrupt.  This bit is set by the
controller before triggering an interrupt, and it is meant to be cleared
by the guest (via write-1-to-clear) when it is done handling the
interrupt.  However, it seems that there is a race going on between the
clearing and setting of this bit.  Removing the check seems to avoid the
issue, since we never get into the state where we think EHB is set but
the guest thinks it is clear (where no further interrupts would be
triggered).  This will potentially trigger more interrupts than strictly
necessary, but the Linux kernel xhci driver handles interrupts with no
events available gracefully.

BUG=chromium:1082930
TEST=`while adb shell echo hi; do : ; done` for 8+ hours without hangs

Change-Id: I3c08f0c5675be10d8e46f73714d684f7ba3a3903
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2202745
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
-rw-r--r--devices/src/usb/xhci/interrupter.rs3
1 files changed, 2 insertions, 1 deletions
diff --git a/devices/src/usb/xhci/interrupter.rs b/devices/src/usb/xhci/interrupter.rs
index 6366050..cf79fd8 100644
--- a/devices/src/usb/xhci/interrupter.rs
+++ b/devices/src/usb/xhci/interrupter.rs
@@ -187,7 +187,8 @@ impl Interrupter {
     }
 
     fn interrupt_if_needed(&mut self) -> Result<()> {
-        if self.enabled && !self.event_ring.is_empty() && !self.event_handler_busy {
+        // TODO(dverkamp): re-add !self.event_handler_busy after solving https://crbug.com/1082930
+        if self.enabled && !self.event_ring.is_empty() {
             self.interrupt()?;
         }
         Ok(())