Skip to content

Commit

Permalink
Removes scoped thread (#1209)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Dec 28, 2024
1 parent 252047a commit 9cbc994
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 56 deletions.
6 changes: 3 additions & 3 deletions gui/src/vmm/cpu/aarch64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub type GdbRegs = gdbstub_arch::aarch64::reg::AArch64CoreRegs;

pub(super) const BREAKPOINT_SIZE: NonZero<usize> = unsafe { NonZero::new_unchecked(4) };

impl<'a, 'b, H: Hypervisor> gdbstub::target::Target for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> gdbstub::target::Target for CpuManager<H> {
type Arch = gdbstub_arch::aarch64::AArch64;
type Error = GdbError;

Expand All @@ -25,13 +25,13 @@ impl<'a, 'b, H: Hypervisor> gdbstub::target::Target for CpuManager<'a, 'b, H> {
}
}

impl<'a, 'b, H: Hypervisor> Breakpoints for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> Breakpoints for CpuManager<H> {
fn support_sw_breakpoint(&mut self) -> Option<SwBreakpointOps<'_, Self>> {
Some(self)
}
}

impl<'a, 'b, H: Hypervisor> SwBreakpoint for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> SwBreakpoint for CpuManager<H> {
fn add_sw_breakpoint(&mut self, addr: u64, kind: usize) -> TargetResult<bool, Self> {
todo!()
}
Expand Down
12 changes: 6 additions & 6 deletions gui/src/vmm/cpu/controller.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: MIT OR Apache-2.0
use super::debug::Debuggee;
use std::mem::ManuallyDrop;
use std::thread::ScopedJoinHandle;
use std::thread::JoinHandle;

/// Contains objects to control a CPU from outside.
pub struct CpuController<'a> {
thread: ManuallyDrop<ScopedJoinHandle<'a, ()>>,
pub struct CpuController {
thread: ManuallyDrop<JoinHandle<()>>,
debug: ManuallyDrop<Option<Debuggee>>,
}

impl<'a> CpuController<'a> {
pub fn new(thread: ScopedJoinHandle<'a, ()>, debug: Option<Debuggee>) -> Self {
impl CpuController {
pub fn new(thread: JoinHandle<()>, debug: Option<Debuggee>) -> Self {
Self {
thread: ManuallyDrop::new(thread),
debug: ManuallyDrop::new(debug),
Expand All @@ -22,7 +22,7 @@ impl<'a> CpuController<'a> {
}
}

impl<'a> Drop for CpuController<'a> {
impl Drop for CpuController {
fn drop(&mut self) {
// We need to drop the debug channel first so it will unblock the CPU thread if it is
// waiting for a request.
Expand Down
19 changes: 7 additions & 12 deletions gui/src/vmm/cpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,29 @@ mod controller;
mod debug;

/// Manage all virtual CPUs.
pub struct CpuManager<'a, 'b, H> {
pub struct CpuManager<H> {
hv: Arc<H>,
el: EventLoopProxy<VmmEvent>,
scope: &'a std::thread::Scope<'a, 'b>,
devices: Arc<DeviceTree>,
cpus: Vec<CpuController<'a>>,
cpus: Vec<CpuController>,
breakpoint: Arc<Mutex<()>>,
sw_breakpoints: HashMap<u64, [u8; arch::BREAKPOINT_SIZE.get()]>,
shutdown: Arc<AtomicBool>,
}

impl<'a, 'b, H: Hypervisor> CpuManager<'a, 'b, H> {
impl<H: Hypervisor> CpuManager<H> {
const GDB_ENOENT: u8 = 2;
const GDB_EFAULT: u8 = 14;

pub fn new(
hv: Arc<H>,
el: EventLoopProxy<VmmEvent>,
scope: &'a std::thread::Scope<'a, 'b>,
devices: Arc<DeviceTree>,
shutdown: Arc<AtomicBool>,
) -> Self {
Self {
hv,
el,
scope,
devices,
cpus: Vec::new(),
breakpoint: Arc::default(),
Expand Down Expand Up @@ -83,9 +80,7 @@ impl<'a, 'b, H: Hypervisor> CpuManager<'a, 'b, H> {

// Spawn thread to drive vCPU.
let t = match map {
Some(map) => self
.scope
.spawn(move || Self::main_cpu(args, debugger, start, map)),
Some(map) => std::thread::spawn(move || Self::main_cpu(args, debugger, start, map)),
None => todo!(),
};

Expand Down Expand Up @@ -408,7 +403,7 @@ impl<'a, 'b, H: Hypervisor> CpuManager<'a, 'b, H> {
}
}

impl<'a, 'b, H: Hypervisor> MultiThreadBase for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> MultiThreadBase for CpuManager<H> {
fn read_registers(&mut self, regs: &mut GdbRegs, tid: Tid) -> TargetResult<(), Self> {
let cpu = self
.cpus
Expand Down Expand Up @@ -492,13 +487,13 @@ impl<'a, 'b, H: Hypervisor> MultiThreadBase for CpuManager<'a, 'b, H> {
}
}

impl<'a, 'b, H: Hypervisor> ThreadExtraInfo for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> ThreadExtraInfo for CpuManager<H> {
fn thread_extra_info(&self, tid: Tid, buf: &mut [u8]) -> Result<usize, Self::Error> {
todo!()
}
}

impl<'a, 'b, H: Hypervisor> MultiThreadResume for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> MultiThreadResume for CpuManager<H> {
fn resume(&mut self) -> Result<(), Self::Error> {
self.release();

Expand Down
6 changes: 3 additions & 3 deletions gui/src/vmm/cpu/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub type GdbRegs = gdbstub_arch::x86::reg::X86_64CoreRegs;

pub(super) const BREAKPOINT_SIZE: NonZero<usize> = unsafe { NonZero::new_unchecked(1) };

impl<'a, 'b, H: Hypervisor> gdbstub::target::Target for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> gdbstub::target::Target for CpuManager<H> {
type Arch = X86_64_SSE;
type Error = GdbError;

Expand All @@ -27,13 +27,13 @@ impl<'a, 'b, H: Hypervisor> gdbstub::target::Target for CpuManager<'a, 'b, H> {
}
}

impl<'a, 'b, H: Hypervisor> Breakpoints for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> Breakpoints for CpuManager<H> {
fn support_sw_breakpoint(&mut self) -> Option<SwBreakpointOps<'_, Self>> {
Some(self)
}
}

impl<'a, 'b, H: Hypervisor> SwBreakpoint for CpuManager<'a, 'b, H> {
impl<H: Hypervisor> SwBreakpoint for CpuManager<H> {
fn add_sw_breakpoint(&mut self, addr: u64, _kind: usize) -> TargetResult<bool, Self> {
let Entry::Vacant(entry) = self.sw_breakpoints.entry(addr) else {
return Ok(false);
Expand Down
62 changes: 30 additions & 32 deletions gui/src/vmm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,36 +33,14 @@ mod hw;
mod kernel;
mod ram;

#[cfg(unix)]
fn get_page_size() -> Result<NonZero<usize>, std::io::Error> {
let v = unsafe { libc::sysconf(libc::_SC_PAGE_SIZE) };

if v < 0 {
Err(std::io::Error::last_os_error())
} else {
Ok(v.try_into().ok().and_then(NonZero::new).unwrap())
}
}

#[cfg(windows)]
fn get_page_size() -> Result<NonZero<usize>, std::io::Error> {
use std::mem::zeroed;
use windows_sys::Win32::System::SystemInformation::GetSystemInfo;
let mut i = unsafe { zeroed() };

unsafe { GetSystemInfo(&mut i) };

Ok(i.dwPageSize.try_into().ok().and_then(NonZero::new).unwrap())
}

/// Manage a virtual machine that run the kernel.
pub struct Vmm<'a, 'b> {
cpu: CpuManager<'a, 'b, crate::hv::Default>, // Drop first.
pub struct Vmm {
cpu: CpuManager<crate::hv::Default>, // Drop first.
shutdown: Arc<AtomicBool>,
}

impl<'a, 'b> Vmm<'a, 'b> {
pub fn new(args: VmmArgs<'b>, scope: &'a std::thread::Scope<'a, 'b>) -> Result<Self, VmmError> {
impl Vmm {
pub fn new(args: VmmArgs, shutdown: Arc<AtomicBool>) -> Result<Self, VmmError> {
let path = &args.kernel;
let debugger = args.debugger;

Expand Down Expand Up @@ -207,7 +185,7 @@ impl<'a, 'b> Vmm<'a, 'b> {
let vm_page_size = vm_page_size.ok_or(VmmError::NoPageSizeInKernelNote)?;

// Get page size on the host.
let host_page_size = get_page_size().map_err(VmmError::GetHostPageSize)?;
let host_page_size = Self::get_page_size().map_err(VmmError::GetHostPageSize)?;

// Get kernel memory size.
let mut len = 0;
Expand Down Expand Up @@ -287,11 +265,9 @@ impl<'a, 'b> Vmm<'a, 'b> {
.build(&feats, vm_page_size, &devices, dynamic)
.map_err(VmmError::BuildRam)?;

// Setup CPU manager.
let shutdown = Arc::new(AtomicBool::new(false));
let mut cpu = CpuManager::new(Arc::new(hv), args.el, scope, devices, shutdown.clone());

// Spawn main CPU.
let mut cpu = CpuManager::new(Arc::new(hv), args.el, devices, shutdown.clone());

cpu.spawn(
map.kern_vaddr + kernel_img.entry(),
Some(map),
Expand All @@ -301,9 +277,31 @@ impl<'a, 'b> Vmm<'a, 'b> {
// Create VMM.
Ok(Self { cpu, shutdown })
}

#[cfg(unix)]
fn get_page_size() -> Result<NonZero<usize>, std::io::Error> {
let v = unsafe { libc::sysconf(libc::_SC_PAGE_SIZE) };

if v < 0 {
Err(std::io::Error::last_os_error())
} else {
Ok(v.try_into().ok().and_then(NonZero::new).unwrap())
}
}

#[cfg(windows)]
fn get_page_size() -> Result<NonZero<usize>, std::io::Error> {
use std::mem::zeroed;
use windows_sys::Win32::System::SystemInformation::GetSystemInfo;
let mut i = unsafe { zeroed() };

unsafe { GetSystemInfo(&mut i) };

Ok(i.dwPageSize.try_into().ok().and_then(NonZero::new).unwrap())
}
}

impl<'a, 'b> Drop for Vmm<'a, 'b> {
impl Drop for Vmm {
fn drop(&mut self) {
// Set shutdown flag before dropping the other fields so their background thread can stop
// before they try to join with it.
Expand Down

0 comments on commit 9cbc994

Please sign in to comment.