summary refs log tree commit diff
path: root/devices/src/i8042.rs
diff options
context:
space:
mode:
authorSlava Malyugin <slavamn@google.com>2018-02-26 16:26:31 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-27 20:17:37 -0800
commitae5878bef11d603c17e2b970816b8298d2f570ee (patch)
treecbfd0ebc11128928738fa59c65fc6b5b008ae0d8 /devices/src/i8042.rs
parent93b00ecca772569727679e5026850810021be1ec (diff)
downloadcrosvm-ae5878bef11d603c17e2b970816b8298d2f570ee.tar
crosvm-ae5878bef11d603c17e2b970816b8298d2f570ee.tar.gz
crosvm-ae5878bef11d603c17e2b970816b8298d2f570ee.tar.bz2
crosvm-ae5878bef11d603c17e2b970816b8298d2f570ee.tar.lz
crosvm-ae5878bef11d603c17e2b970816b8298d2f570ee.tar.xz
crosvm-ae5878bef11d603c17e2b970816b8298d2f570ee.tar.zst
crosvm-ae5878bef11d603c17e2b970816b8298d2f570ee.zip
crosvm: make port 0x61 return 0x20, preventing Guest kernel hang
Harmonize small 8042 implementation with kvmtool by making read from
port 0x61 return 0x20. This prevents infinite loop in
pit_calibrate_tsc() on small Intel cores.

BUG=none
TEST=reproduced problem on Celeraon N3150 (Braswell), verified
     VM boots further with the fix

Change-Id: Ifbee2bc72c4f5acd2551d8dcab466dc5f4907975
Reviewed-on: https://chromium-review.googlesource.com/938759
Commit-Ready: Slava Malyugin <slavamn@chromium.org>
Tested-by: Slava Malyugin <slavamn@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src/i8042.rs')
-rw-r--r--devices/src/i8042.rs7
1 files changed, 7 insertions, 0 deletions
diff --git a/devices/src/i8042.rs b/devices/src/i8042.rs
index b046184..c23dd03 100644
--- a/devices/src/i8042.rs
+++ b/devices/src/i8042.rs
@@ -18,10 +18,17 @@ impl I8042Device {
     }
 }
 
+// i8042 device is mapped I/O address 0x61. We partially implement two 8-bit
+// registers: port 0x61 (I8042_PORT_B_REG, offset 0 from base of 0x61), and
+// port 0x64 (I8042_COMMAND_REG, offset 3 from base of 0x61).
 impl BusDevice for I8042Device {
     fn read(&mut self, offset: u64, data: &mut [u8]) {
         if data.len() == 1 && offset == 3 {
             data[0] = 0x0;
+        } else if data.len() == 1 && offset == 0 {
+            // Like kvmtool, we return bit 5 set in I8042_PORT_B_REG to
+            // avoid hang in pit_calibrate_tsc() in Linux kernel.
+            data[0] = 0x20;
         }
     }