vmm: Don't store GuestMemoryMmap for "guest_debug" functionality

This removes the storage of the GuestMemoryMmap on the CpuManager
further allowing the decoupling of the CpuManager from the
MemoryManager.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2022-12-01 14:23:50 +00:00
parent c7b22156da
commit c5eac2e822
3 changed files with 34 additions and 17 deletions

View File

@ -418,8 +418,6 @@ pub struct CpuManager {
config: CpusConfig, config: CpusConfig,
#[cfg_attr(target_arch = "aarch64", allow(dead_code))] #[cfg_attr(target_arch = "aarch64", allow(dead_code))]
interrupt_controller: Option<Arc<Mutex<dyn InterruptController>>>, interrupt_controller: Option<Arc<Mutex<dyn InterruptController>>>,
#[cfg(feature = "guest_debug")]
guest_memory: GuestMemoryAtomic<GuestMemoryMmap>,
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
cpuid: Vec<CpuIdEntry>, cpuid: Vec<CpuIdEntry>,
#[cfg_attr(target_arch = "aarch64", allow(dead_code))] #[cfg_attr(target_arch = "aarch64", allow(dead_code))]
@ -589,7 +587,6 @@ impl CpuManager {
#[cfg(feature = "tdx")] tdx_enabled: bool, #[cfg(feature = "tdx")] tdx_enabled: bool,
numa_nodes: &NumaNodes, numa_nodes: &NumaNodes,
) -> Result<Arc<Mutex<CpuManager>>> { ) -> Result<Arc<Mutex<CpuManager>>> {
let guest_memory = memory_manager.lock().unwrap().guest_memory();
let mut vcpu_states = Vec::with_capacity(usize::from(config.max_vcpus)); let mut vcpu_states = Vec::with_capacity(usize::from(config.max_vcpus));
vcpu_states.resize_with(usize::from(config.max_vcpus), VcpuState::default); vcpu_states.resize_with(usize::from(config.max_vcpus), VcpuState::default);
let hypervisor_type = hypervisor.hypervisor_type(); let hypervisor_type = hypervisor.hypervisor_type();
@ -680,8 +677,6 @@ impl CpuManager {
hypervisor_type, hypervisor_type,
config: config.clone(), config: config.clone(),
interrupt_controller: None, interrupt_controller: None,
#[cfg(feature = "guest_debug")]
guest_memory,
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
cpuid, cpuid,
vm, vm,
@ -1484,7 +1479,12 @@ impl CpuManager {
} }
#[cfg(all(target_arch = "x86_64", feature = "guest_debug"))] #[cfg(all(target_arch = "x86_64", feature = "guest_debug"))]
fn translate_gva(&self, cpu_id: u8, gva: u64) -> Result<u64> { fn translate_gva(
&self,
_guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: u8,
gva: u64,
) -> Result<u64> {
let (gpa, _) = self.vcpus[usize::from(cpu_id)] let (gpa, _) = self.vcpus[usize::from(cpu_id)]
.lock() .lock()
.unwrap() .unwrap()
@ -1511,7 +1511,12 @@ impl CpuManager {
/// - FEAT_LPA2 /// - FEAT_LPA2
/// ///
#[cfg(all(target_arch = "aarch64", feature = "guest_debug"))] #[cfg(all(target_arch = "aarch64", feature = "guest_debug"))]
fn translate_gva(&self, cpu_id: u8, gva: u64) -> Result<u64> { fn translate_gva(
&self,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: u8,
gva: u64,
) -> Result<u64> {
let tcr_el1: u64 = self.vcpus[usize::from(cpu_id)] let tcr_el1: u64 = self.vcpus[usize::from(cpu_id)]
.lock() .lock()
.unwrap() .unwrap()
@ -1615,7 +1620,7 @@ impl CpuManager {
descaddr &= !7u64; descaddr &= !7u64;
let mut buf = [0; 8]; let mut buf = [0; 8];
self.guest_memory guest_memory
.memory() .memory()
.read(&mut buf, GuestAddress(descaddr)) .read(&mut buf, GuestAddress(descaddr))
.map_err(|e| Error::TranslateVirtualAddress(e.into()))?; .map_err(|e| Error::TranslateVirtualAddress(e.into()))?;
@ -2232,6 +2237,7 @@ impl Debuggable for CpuManager {
fn read_mem( fn read_mem(
&self, &self,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: usize, cpu_id: usize,
vaddr: GuestAddress, vaddr: GuestAddress,
len: usize, len: usize,
@ -2241,14 +2247,14 @@ impl Debuggable for CpuManager {
while total_read < len as u64 { while total_read < len as u64 {
let gaddr = vaddr.0 + total_read; let gaddr = vaddr.0 + total_read;
let paddr = match self.translate_gva(cpu_id as u8, gaddr) { let paddr = match self.translate_gva(guest_memory, cpu_id as u8, gaddr) {
Ok(paddr) => paddr, Ok(paddr) => paddr,
Err(_) if gaddr == u64::MIN => gaddr, // Silently return GVA as GPA if GVA == 0. Err(_) if gaddr == u64::MIN => gaddr, // Silently return GVA as GPA if GVA == 0.
Err(e) => return Err(DebuggableError::TranslateGva(e)), Err(e) => return Err(DebuggableError::TranslateGva(e)),
}; };
let psize = arch::PAGE_SIZE as u64; let psize = arch::PAGE_SIZE as u64;
let read_len = std::cmp::min(len as u64 - total_read, psize - (paddr & (psize - 1))); let read_len = std::cmp::min(len as u64 - total_read, psize - (paddr & (psize - 1)));
self.guest_memory guest_memory
.memory() .memory()
.read( .read(
&mut buf[total_read as usize..total_read as usize + read_len as usize], &mut buf[total_read as usize..total_read as usize + read_len as usize],
@ -2262,6 +2268,7 @@ impl Debuggable for CpuManager {
fn write_mem( fn write_mem(
&self, &self,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: usize, cpu_id: usize,
vaddr: &GuestAddress, vaddr: &GuestAddress,
data: &[u8], data: &[u8],
@ -2270,7 +2277,7 @@ impl Debuggable for CpuManager {
while total_written < data.len() as u64 { while total_written < data.len() as u64 {
let gaddr = vaddr.0 + total_written; let gaddr = vaddr.0 + total_written;
let paddr = match self.translate_gva(cpu_id as u8, gaddr) { let paddr = match self.translate_gva(guest_memory, cpu_id as u8, gaddr) {
Ok(paddr) => paddr, Ok(paddr) => paddr,
Err(_) if gaddr == u64::MIN => gaddr, // Silently return GVA as GPA if GVA == 0. Err(_) if gaddr == u64::MIN => gaddr, // Silently return GVA as GPA if GVA == 0.
Err(e) => return Err(DebuggableError::TranslateGva(e)), Err(e) => return Err(DebuggableError::TranslateGva(e)),
@ -2280,7 +2287,7 @@ impl Debuggable for CpuManager {
data.len() as u64 - total_written, data.len() as u64 - total_written,
psize - (paddr & (psize - 1)), psize - (paddr & (psize - 1)),
); );
self.guest_memory guest_memory
.memory() .memory()
.write( .write(
&data[total_written as usize..total_written as usize + write_len as usize], &data[total_written as usize..total_written as usize + write_len as usize],

View File

@ -5,6 +5,7 @@
// //
// SPDX-License-Identifier: BSD-3-Clause // SPDX-License-Identifier: BSD-3-Clause
use crate::GuestMemoryMmap;
use gdbstub::{ use gdbstub::{
arch::Arch, arch::Arch,
common::{Signal, Tid}, common::{Signal, Tid},
@ -33,7 +34,7 @@ use gdbstub_arch::x86::reg::X86_64CoreRegs as CoreRegs;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use gdbstub_arch::x86::X86_64_SSE as GdbArch; use gdbstub_arch::x86::X86_64_SSE as GdbArch;
use std::{os::unix::net::UnixListener, sync::mpsc}; use std::{os::unix::net::UnixListener, sync::mpsc};
use vm_memory::{GuestAddress, GuestMemoryError}; use vm_memory::{GuestAddress, GuestMemoryAtomic, GuestMemoryError};
type ArchUsize = u64; type ArchUsize = u64;
@ -67,12 +68,14 @@ pub trait Debuggable: vm_migration::Pausable {
) -> std::result::Result<(), DebuggableError>; ) -> std::result::Result<(), DebuggableError>;
fn read_mem( fn read_mem(
&self, &self,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: usize, cpu_id: usize,
vaddr: GuestAddress, vaddr: GuestAddress,
len: usize, len: usize,
) -> std::result::Result<Vec<u8>, DebuggableError>; ) -> std::result::Result<Vec<u8>, DebuggableError>;
fn write_mem( fn write_mem(
&self, &self,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: usize, cpu_id: usize,
vaddr: &GuestAddress, vaddr: &GuestAddress,
data: &[u8], data: &[u8],

View File

@ -2311,11 +2311,16 @@ impl Vm {
self.write_regs(cpu_id, regs).map_err(Error::Debug)?; self.write_regs(cpu_id, regs).map_err(Error::Debug)?;
} }
ReadMem(vaddr, len) => { ReadMem(vaddr, len) => {
let mem = self.read_mem(cpu_id, *vaddr, *len).map_err(Error::Debug)?; let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
let mem = self
.read_mem(&guest_memory, cpu_id, *vaddr, *len)
.map_err(Error::Debug)?;
return Ok(GdbResponsePayload::MemoryRegion(mem)); return Ok(GdbResponsePayload::MemoryRegion(mem));
} }
WriteMem(vaddr, data) => { WriteMem(vaddr, data) => {
self.write_mem(cpu_id, vaddr, data).map_err(Error::Debug)?; let guest_memory = self.memory_manager.lock().as_ref().unwrap().guest_memory();
self.write_mem(&guest_memory, cpu_id, vaddr, data)
.map_err(Error::Debug)?;
} }
ActiveVcpus => { ActiveVcpus => {
let active_vcpus = self.active_vcpus(); let active_vcpus = self.active_vcpus();
@ -2656,6 +2661,7 @@ impl Debuggable for Vm {
fn read_mem( fn read_mem(
&self, &self,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: usize, cpu_id: usize,
vaddr: GuestAddress, vaddr: GuestAddress,
len: usize, len: usize,
@ -2663,11 +2669,12 @@ impl Debuggable for Vm {
self.cpu_manager self.cpu_manager
.lock() .lock()
.unwrap() .unwrap()
.read_mem(cpu_id, vaddr, len) .read_mem(guest_memory, cpu_id, vaddr, len)
} }
fn write_mem( fn write_mem(
&self, &self,
guest_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
cpu_id: usize, cpu_id: usize,
vaddr: &GuestAddress, vaddr: &GuestAddress,
data: &[u8], data: &[u8],
@ -2675,7 +2682,7 @@ impl Debuggable for Vm {
self.cpu_manager self.cpu_manager
.lock() .lock()
.unwrap() .unwrap()
.write_mem(cpu_id, vaddr, data) .write_mem(guest_memory, cpu_id, vaddr, data)
} }
fn active_vcpus(&self) -> usize { fn active_vcpus(&self) -> usize {