Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ percpu = { version = "0.2.0", features = ["arm-el2"] }
# System dependent modules provided by ArceOS-Hypervisor.
axvcpu = "0.1"
axaddrspace = "0.1"
axdevice = { git = "https://github.com/arceos-hypervisor/axdevice.git" }
axdevice = { git = "https://github.com/arceos-hypervisor/axdevice.git", branch = "next"}
axdevice_base = "0.1"
axvmconfig = { version = "0.1", default-features = false }

[target.'cfg(target_arch = "x86_64")'.dependencies]
x86_vcpu = "0.1"

[target.'cfg(target_arch = "riscv64")'.dependencies]
riscv_vcpu = "0.1"
riscv_vcpu = { git = "https://github.com/arceos-hypervisor/riscv_vcpu.git", branch = "master" }

[target.'cfg(target_arch = "aarch64")'.dependencies]
arm_vcpu = { git = "https://github.com/arceos-hypervisor/arm_vcpu", branch = "next" }
Expand Down
19 changes: 19 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ pub struct AxVMConfig {
#[allow(dead_code)]
vm_type: VMType,
pub(crate) phys_cpu_ls: PhysCpuList,
/// vCPU configuration.
pub cpu_config: AxVCpuConfig,
/// VM image configuration.
pub image_config: VMImageConfig,
emu_devices: Vec<EmulatedDeviceConfig>,
pass_through_devices: Vec<PassThroughDeviceConfig>,
Expand Down Expand Up @@ -122,14 +124,17 @@ impl AxVMConfig {
self.cpu_config.ap_entry
}

/// Returns a mutable reference to the physical CPU list.
pub fn phys_cpu_ls_mut(&mut self) -> &mut PhysCpuList {
&mut self.phys_cpu_ls
}

/// Returns the list of excluded devices.
pub fn excluded_devices(&self) -> &Vec<Vec<String>> {
&self.excluded_devices
}

/// Returns the list of passthrough address configurations.
pub fn pass_through_addresses(&self) -> &Vec<PassThroughAddressConfig> {
&self.pass_through_addresses
}
Expand Down Expand Up @@ -191,6 +196,7 @@ impl AxVMConfig {
}
}

/// Represents the list of physical CPUs available for the VM.
#[derive(Debug, Default, Clone)]
pub struct PhysCpuList {
cpu_num: usize,
Expand All @@ -209,6 +215,7 @@ impl PhysCpuList {
/// - The physical id of the vCpu, equal to vCpu id if not provided.
pub fn get_vcpu_affinities_pcpu_ids(&self) -> Vec<(usize, Option<usize>, usize)> {
let mut vcpu_pcpu_tuples = Vec::new();
let mut pcpu_mask_flag = false;

if let Some(phys_cpu_ids) = &self.phys_cpu_ids
&& self.cpu_num != phys_cpu_ids.len()
Expand All @@ -224,6 +231,7 @@ impl PhysCpuList {
}

if let Some(phys_cpu_sets) = &self.phys_cpu_sets {
pcpu_mask_flag = true;
for (vcpu_id, pcpu_mask_bitmap) in phys_cpu_sets.iter().enumerate() {
vcpu_pcpu_tuples[vcpu_id].1 = Some(*pcpu_mask_bitmap);
}
Expand All @@ -232,23 +240,34 @@ impl PhysCpuList {
if let Some(phys_cpu_ids) = &self.phys_cpu_ids {
for (vcpu_id, phys_id) in phys_cpu_ids.iter().enumerate() {
vcpu_pcpu_tuples[vcpu_id].2 = *phys_id;
#[cfg(target_arch = "riscv64")]
{
if pcpu_mask_flag == false {
// if don't assign pcpu mask yet, assign it manually
vcpu_pcpu_tuples[vcpu_id].1 = Some(1 << (*phys_id));
}
}
}
}
vcpu_pcpu_tuples
}

/// Returns the number of CPUs.
pub fn cpu_num(&self) -> usize {
self.cpu_num
}

/// Returns the physical CPU IDs.
pub fn phys_cpu_ids(&self) -> &Option<Vec<usize>> {
&self.phys_cpu_ids
}

/// Returns the physical CPU sets.
pub fn phys_cpu_sets(&self) -> &Option<Vec<usize>> {
&self.phys_cpu_sets
}

/// Sets the guest CPU sets.
pub fn set_guest_cpu_sets(&mut self, phys_cpu_sets: Vec<usize>) {
self.phys_cpu_sets = Some(phys_cpu_sets);
}
Expand Down
18 changes: 17 additions & 1 deletion src/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,26 @@ struct AxVMInnerConst<U: AxVCpuHal> {
unsafe impl<U: AxVCpuHal> Send for AxVMInnerConst<U> {}
unsafe impl<U: AxVCpuHal> Sync for AxVMInnerConst<U> {}

/// Represents a memory region in a virtual machine.
#[derive(Debug, Clone)]
pub struct VMMemoryRegion {
/// Guest physical address.
pub gpa: GuestPhysAddr,
/// Host virtual address.
pub hva: HostVirtAddr,
/// Memory layout of the region.
pub layout: Layout,
/// Whether this region was allocated by the allocator and needs to be deallocated
pub needs_dealloc: bool,
}

impl VMMemoryRegion {
/// Returns the size of the memory region.
pub fn size(&self) -> usize {
self.layout.size()
}

/// Returns `true` if the guest physical address is identical to the host virtual address.
pub fn is_identical(&self) -> bool {
self.gpa.as_usize() == self.hva.as_usize()
}
Expand Down Expand Up @@ -167,6 +173,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
let dtb_addr = inner_mut.config.image_config().dtb_load_gpa;
let vcpu_id_pcpu_sets = inner_mut.config.phys_cpu_ls.get_vcpu_affinities_pcpu_ids();

info!("dtb_load_gpa: {:?}", dtb_addr);
debug!("id: {}, VCpuIdPCpuSets: {vcpu_id_pcpu_sets:#x?}", self.id());

let mut vcpu_list = Vec::with_capacity(vcpu_id_pcpu_sets.len());
Expand All @@ -179,7 +186,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
#[cfg(target_arch = "riscv64")]
let arch_config = AxVCpuCreateConfig {
hart_id: vcpu_id as _,
dtb_addr: dtb_addr.unwrap_or_default(),
dtb_addr: dtb_addr.unwrap_or_default().as_usize(),
};
#[cfg(target_arch = "x86_64")]
let arch_config = AxVCpuCreateConfig::default();
Expand Down Expand Up @@ -336,11 +343,13 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
Ok(())
}

/// Sets the VM status.
pub fn set_vm_status(&self, status: VMStatus) {
let mut inner_mut = self.inner_mut.lock();
inner_mut.vm_status = status;
}

/// Returns the current VM status.
pub fn vm_status(&self) -> VMStatus {
let inner_mut = self.inner_mut.lock();
inner_mut.vm_status
Expand Down Expand Up @@ -501,8 +510,12 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
}
AxVCpuExitReason::IoRead { port, width } => {
let val = self.get_devices().handle_port_read(*port, *width)?;
#[cfg(not(target_arch = "riscv64"))]
vcpu.set_gpr(0, val); // The target is always eax/ax/al, todo: handle access_width correctly

#[cfg(target_arch = "riscv64")]
vcpu.set_gpr(riscv_vcpu::GprIndex::A0 as usize, val);

true
}
AxVCpuExitReason::IoWrite { port, width, data } => {
Expand Down Expand Up @@ -698,6 +711,7 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
Ok(())
}

/// Allocates a new memory region for the VM.
pub fn alloc_memory_region(
&self,
layout: Layout,
Expand Down Expand Up @@ -736,10 +750,12 @@ impl<H: AxVMHal, U: AxVCpuHal> AxVM<H, U> {
Ok(s)
}

/// Returns a list of all memory regions in the VM.
pub fn memory_regions(&self) -> Vec<VMMemoryRegion> {
self.inner_mut.lock().memory_regions.clone()
}

/// Maps a reserved memory region for the VM.
pub fn map_reserved_memory_region(
&self,
layout: Layout,
Expand Down