From e8ee29b4feabd5a6cc3b77d819444c2e7b6537c7 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 29 Mar 2021 13:20:00 +0200 Subject: [PATCH] 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 (cherry picked from commit 9e9aba7c0ba31319e63b33ec5a99aba103a97b55) Signed-off-by: Rob Bradford --- vmm/src/cpu.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index 67bf9015a..7a0fa163b 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -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; }