diff options
author | Daniel Verkamp <dverkamp@chromium.org> | 2018-10-24 11:30:34 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-11-21 01:25:28 -0800 |
commit | e81a3e66cc266821fa5faec258d33c2eb3d8e102 (patch) | |
tree | e968ec22d1db178aa08ffc3f4d067c47a9dc88b1 /devices/src/virtio/virtio_pci_common_config.rs | |
parent | 5c4ad02dd4865949e7f4df1a04f4c1cc603e6c64 (diff) | |
download | crosvm-e81a3e66cc266821fa5faec258d33c2eb3d8e102.tar crosvm-e81a3e66cc266821fa5faec258d33c2eb3d8e102.tar.gz crosvm-e81a3e66cc266821fa5faec258d33c2eb3d8e102.tar.bz2 crosvm-e81a3e66cc266821fa5faec258d33c2eb3d8e102.tar.lz crosvm-e81a3e66cc266821fa5faec258d33c2eb3d8e102.tar.xz crosvm-e81a3e66cc266821fa5faec258d33c2eb3d8e102.tar.zst crosvm-e81a3e66cc266821fa5faec258d33c2eb3d8e102.zip |
devices: convert virtio features to a u64
The virtio specification only defines feature bits in the 0-63 range currently, so we can represent the features as a u64. The Linux kernel makes the same simplifying assumption, and very few features have been defined beyond the first 32 bits, so this is probably safe for a while. This allows the device models to be simplified, since they no longer need to deal with the features paging mechanism (it is handled by the generic virtio transport code). BUG=None TEST=build_test; boot termina on kevin Change-Id: I6fd86907b2bdf494466c205e85072ebfeb7f5b73 Signed-off-by: Daniel Verkamp <dverkamp@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1313012 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Dylan Reid <dgreid@chromium.org> Reviewed-by: Zach Reizner <zachr@chromium.org>
Diffstat (limited to 'devices/src/virtio/virtio_pci_common_config.rs')
-rw-r--r-- | devices/src/virtio/virtio_pci_common_config.rs | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/devices/src/virtio/virtio_pci_common_config.rs b/devices/src/virtio/virtio_pci_common_config.rs index 8596563..efbfbe0 100644 --- a/devices/src/virtio/virtio_pci_common_config.rs +++ b/devices/src/virtio/virtio_pci_common_config.rs @@ -138,10 +138,13 @@ impl VirtioPciCommonConfig { // TODO(dverkamp): This hack (copied from MmioDevice) unconditionally // reports support for VIRTIO_F_VERSION_1; once all devices have been // fixed to report VIRTIO_F_VERSION_1, remove this workaround. - device.features(self.device_feature_select) | if self.device_feature_select == 1 { - 0x1 + let features = device.features() | 1 << VIRTIO_F_VERSION_1; + // Only 64 bits of features (2 pages) are defined for now, so limit + // device_feature_select to avoid shifting by 64 or more bits. + if self.device_feature_select < 2 { + (features >> (self.device_feature_select * 32)) as u32 } else { - 0x0 + 0 } } 0x08 => self.driver_feature_select, @@ -167,7 +170,16 @@ impl VirtioPciCommonConfig { match offset { 0x00 => self.device_feature_select = value, 0x08 => self.driver_feature_select = value, - 0x0c => device.ack_features(self.driver_feature_select, value), + 0x0c => { + if self.driver_feature_select < 2 { + device.ack_features((value as u64) << (self.driver_feature_select * 32)); + } else { + warn!( + "invalid ack_features (page {}, value 0x{:x})", + self.driver_feature_select, value + ); + } + } 0x20 => self.with_queue_mut(queues, |q| lo(&mut q.desc_table, value)), 0x24 => self.with_queue_mut(queues, |q| hi(&mut q.desc_table, value)), 0x28 => self.with_queue_mut(queues, |q| lo(&mut q.avail_ring, value)), @@ -221,7 +233,7 @@ mod tests { struct DummyDevice(u32); const QUEUE_SIZE: u16 = 256; const QUEUE_SIZES: &'static [u16] = &[QUEUE_SIZE]; - const DUMMY_FEATURES: u32 = 0x5555_aaaa; + const DUMMY_FEATURES: u64 = 0x5555_aaaa; impl VirtioDevice for DummyDevice { fn keep_fds(&self) -> Vec<RawFd> { Vec::new() @@ -242,7 +254,7 @@ mod tests { _queue_evts: Vec<EventFd>, ) { } - fn features(&self, _page: u32) -> u32 { + fn features(&self) -> u64 { DUMMY_FEATURES } } @@ -276,7 +288,7 @@ mod tests { regs.write(0x04, &[0, 0, 0, 0], &mut queues, &mut dev); let mut read_back = vec![0, 0, 0, 0]; regs.read(0x04, &mut read_back, &mut queues, &mut dev); - assert_eq!(LittleEndian::read_u32(&read_back), DUMMY_FEATURES); + assert_eq!(LittleEndian::read_u32(&read_back), DUMMY_FEATURES as u32); // Feature select registers are read/write. regs.write(0x00, &[1, 2, 3, 4], &mut queues, &mut dev); |