CpuManager: Fix MMIO read handling

There are two parts:

- Unconditionally zero the output area. The length of the incoming
  vector has been seen from 1 to 4 bytes, even though just the first
  byte might need to be handled. But also, this ensures any possibly
  unhandled offset will return zeroed result to the caller. The former
  implementation used an I/O port which seems to behave differently from
  MMIO and wouldn't require explicit output zeroing.
- An access with zero offset still takes place and needs to be handled.

Fixes #2437.

Signed-off-by: Anatol Belski <anbelski@linux.microsoft.com>
(cherry picked from commit 9e9aba7c0b)
Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Anatol Belski 2021-03-29 13:20:00 +02:00 committed by Rob Bradford
parent 498939c297
commit e8ee29b4fe

View File

@ -433,12 +433,16 @@ const CPU_SELECTION_OFFSET: u64 = 0;
impl BusDevice for CpuManager {
fn read(&mut self, _base: u64, offset: u64, data: &mut [u8]) {
// The Linux kernel, quite reasonably, doesn't zero the memory it gives us.
data.copy_from_slice(&[0; 8][0..data.len()]);
match offset {
CPU_SELECTION_OFFSET => {
data[0] = self.selected_cpu;
}
CPU_STATUS_OFFSET => {
if self.selected_cpu < self.present_vcpus() {
let state = &self.vcpu_states[usize::from(self.selected_cpu)];
// The Linux kernel, quite reasonably, doesn't zero the memory it gives us.
data.copy_from_slice(&[0; 8][0..data.len()]);
if state.active() {
data[0] |= 1 << CPU_ENABLE_FLAG;
}