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
436 changes: 164 additions & 272 deletions Cargo.lock

Large diffs are not rendered by default.

34 changes: 19 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,37 +32,41 @@ timer_list = "0.1"
toml = "0.9"

# System dependent modules provided by ArceOS.
axstd = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1", features = [
# FIXME: pin to a specific tag!
axstd = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202", features = [
"alloc-level-1",
"paging",
"irq",
"multitask",
"task-ext",
"smp", # "page-alloc-64g",
]}

axalloc = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axconfig = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axdisplay = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axdriver = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axfs = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axhal = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axipi = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axlog = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axmm = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axnet = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axtask = {git = "https://github.com/arceos-hypervisor/arceos.git", tag = "hv-0.4.1"}
axalloc = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axconfig = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axdisplay = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axdriver = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axfs = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axhal = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axipi = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axlog = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axmm = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axnet = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}
axtask = {git = "https://github.com/arceos-org/arceos.git", tag = "dev-251202"}

axplat = {git = "https://github.com/arceos-hypervisor/axplat_crates.git", tag = "vmm-v0.3.0"}
axcpu = {git = "https://github.com/arceos-org/axcpu.git", tag = "dev-v03"}
axplat = {git = "https://github.com/arceos-org/axplat_crates.git", tag = "dev-v03"}

# System dependent modules provided by ArceOS-Hypervisor.
axaddrspace = "0.1.1"
axhvc = {git = "https://github.com/arceos-hypervisor/axhvc.git"}
axklib = {git = "https://github.com/arceos-hypervisor/axklib.git"}
axruntime = {path = "modules/axruntime"}
axvcpu = "0.1"
axvm = {git = "https://github.com/arceos-hypervisor/axvm.git", branch = "next"}

# System independent crates provided by ArceOS, these crates could be imported by remote url.
axerrno = "0.1.0"
axerrno = "0.2"
byte-unit = {version = "5", default-features = false, features = ["byte"]}
crate_interface = "0.1"
fdt-parser = "0.4"
Expand All @@ -88,6 +92,6 @@ axvmconfig = {git = "https://github.com/arceos-hypervisor/axvmconfig.git", branc
axvcpu = {git = "https://github.com/arceos-hypervisor/axvcpu.git", branch = "next"}
axvmconfig = {git = "https://github.com/arceos-hypervisor/axvmconfig.git", branch = "next"}

[patch."https://github.com/arceos-hypervisor/arceos"]
[patch."https://github.com/arceos-org/arceos"]
axconfig = {path = "modules/axconfig"}
axruntime = {path = "modules/axruntime"}
3 changes: 2 additions & 1 deletion kernel/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ axvm.workspace = true
axerrno.workspace = true
byte-unit = {version = "5", default-features = false, features = ["byte"]}
crate_interface.workspace = true
extern-trait = "0.2"
fdt-parser = "0.4"
memory_addr.workspace = true
page_table_entry = {version = "0.5", features = ["arm-el2"]}
Expand All @@ -62,7 +63,7 @@ aarch64-cpu-ext = "0.1"
arm-gic-driver = {version = "0.15.5", features = ["rdif"]}

[build-dependencies]
axconfig = {git = "https://github.com/arceos-hypervisor/arceos.git", branch = "vmm-dev"}
axconfig.workspace = true
prettyplease = "0.2"
quote = "1.0"
syn = "2.0"
Expand Down
13 changes: 5 additions & 8 deletions kernel/src/hal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
use std::os::arceos::{
self,
modules::{
axhal::percpu::this_cpu_id,
axtask::{self, TaskExtRef},
},
modules::{axhal::percpu::this_cpu_id, axtask},
};

use axerrno::{AxResult, ax_err_type};
Expand All @@ -19,7 +16,7 @@ use axvm::{AxVMHal, AxVMPerCpu};
#[cfg_attr(target_arch = "x86_64", path = "arch/x86_64/mod.rs")]
pub mod arch;

use crate::{hal::arch::hardware_check, vmm};
use crate::{hal::arch::hardware_check, task::AsVCpuTask, vmm};

#[allow(unused)]
#[repr(C)]
Expand Down Expand Up @@ -48,11 +45,11 @@ impl AxVMHal for AxVMHalImpl {
}

fn current_vm_id() -> usize {
axtask::current().task_ext().vm().id()
axtask::current().as_vcpu_task().vm().id()
}

fn current_vcpu_id() -> usize {
axtask::current().task_ext().vcpu.id()
axtask::current().as_vcpu_task().vcpu.id()
}

fn current_pcpu_id() -> usize {
Expand All @@ -64,7 +61,7 @@ impl AxVMHal for AxVMHalImpl {
.ok_or_else(|| ax_err_type!(NotFound))
}

fn inject_irq_to_vcpu(vm_id: usize, vcpu_id: usize, irq: usize) -> axerrno::AxResult {
fn inject_irq_to_vcpu(vm_id: usize, vcpu_id: usize, irq: usize) -> AxResult {
vmm::with_vm_and_vcpu_on_pcpu(vm_id, vcpu_id, move |_, vcpu| {
vcpu.inject_interrupt(irq).unwrap();
})
Expand Down
39 changes: 25 additions & 14 deletions kernel/src/task.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
use crate::vmm::{VCpuRef, VM, VMRef};
use alloc::sync::{Arc, Weak};
use std::os::arceos::modules::axtask::def_task_ext;
use std::os::arceos::modules::axtask::{TaskExt, TaskInner};

use crate::vmm::{VCpuRef, VM, VMRef};

/// Task extended data for the hypervisor.
pub struct TaskExt {
pub struct VCpuTask {
/// The VM (Weak reference to avoid keeping VM alive).
pub vm: Weak<VM>,
/// The virtual CPU.
pub vcpu: VCpuRef,
}

impl TaskExt {
/// Create TaskExt with a Weak reference from a VMRef
pub const fn new(vm: Weak<VM>, vcpu: VCpuRef) -> Self {
Self { vm, vcpu }
impl VCpuTask {
/// Create a new [`HvTask`].
pub fn new(vm: &VMRef, vcpu: VCpuRef) -> Self {
Self {
vm: Arc::downgrade(vm),
vcpu,
}
}

/// Get a strong reference to the VM if it's still alive.
/// Returns None if the VM has been dropped.
pub fn vm(&self) -> VMRef {
self.vm.upgrade().expect("VM has been dropped")
}
}

/// Helper to create TaskExt from a VMRef by downgrading to Weak.
pub fn from_vm_ref(vm: VMRef, vcpu: VCpuRef) -> Self {
Self {
vm: Arc::downgrade(&vm),
vcpu,
#[extern_trait::extern_trait]
unsafe impl TaskExt for VCpuTask {}

pub trait AsVCpuTask {
fn as_vcpu_task(&self) -> &VCpuTask;
}

impl AsVCpuTask for TaskInner {
fn as_vcpu_task(&self) -> &VCpuTask {
unsafe {
self.task_ext()
.expect("Not a VCpuTask")
.downcast_ref::<VCpuTask>()
}
}
}

def_task_ext!(TaskExt);
11 changes: 7 additions & 4 deletions kernel/src/vmm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ pub mod fdt;
use core::sync::atomic::{AtomicUsize, Ordering};
use std::os::arceos::{
api::task::{self, AxWaitQueueHandle},
modules::axtask::{self, TaskExtRef},
modules::axtask,
};

use axerrno::{AxResult, ax_err_type};

use crate::hal::{AxVCpuHalImpl, AxVMHalImpl};
use crate::{
hal::{AxVCpuHalImpl, AxVMHalImpl},
task::AsVCpuTask,
};
pub use timer::init_percpu as init_timer_percpu;

/// The instantiated VM type.
Expand Down Expand Up @@ -107,8 +110,8 @@ pub fn with_vm_and_vcpu_on_pcpu(
// Disables preemption and IRQs to prevent the current task from being preempted or re-scheduled.
let guard = kernel_guard::NoPreemptIrqSave::new();

let current_vm = axtask::current().task_ext().vm().id();
let current_vcpu = axtask::current().task_ext().vcpu.id();
let current_vm = axtask::current().as_vcpu_task().vm().id();
let current_vcpu = axtask::current().as_vcpu_task().vcpu.id();

// The target vCPU is the current task, execute the closure directly.
if current_vm == vm_id && current_vcpu == vcpu_id {
Expand Down
38 changes: 21 additions & 17 deletions kernel/src/vmm/vcpus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ use std::os::arceos::{
api::task::{AxCpuMask, ax_wait_queue_wake},
modules::{
axhal::{self, time::busy_wait},
axtask,
axtask::{self, AxTaskExt},
},
};

use axaddrspace::GuestPhysAddr;
use axtask::{AxTaskRef, TaskExtRef, TaskInner, WaitQueue};
use axtask::{AxTaskRef, TaskInner, WaitQueue};
use axvcpu::{AxVCpuExitReason, VCpuState};

use crate::vmm::{VCpuRef, VMRef, sub_running_vm_count};
use crate::{hal::arch::inject_interrupt, task::TaskExt};
use crate::{hal::arch::inject_interrupt, task::VCpuTask};
use crate::{
task::AsVCpuTask,
vmm::{VCpuRef, VMRef, sub_running_vm_count},
};

const KERNEL_STACK_SIZE: usize = 0x40000; // 256 KiB

Expand Down Expand Up @@ -139,7 +142,8 @@ impl VMVCpus {

#[allow(dead_code)]
fn notify_one(&mut self) {
info!("Current wait queue length: {}", self.wait_queue.len());
// FIXME: `WaitQueue::len` is removed
// info!("Current wait queue length: {}", self.wait_queue.len());
self.wait_queue.notify_one(false);
}

Expand Down Expand Up @@ -250,12 +254,11 @@ pub(crate) fn cleanup_vm_vcpus(vm_id: usize) {
idx,
task.id_name()
);
if let Some(exit_code) = task.join() {
debug!(
"VM[{}] VCpu task[{}] exited with code: {}",
vm_id, idx, exit_code
);
}
let exit_code = task.join();
debug!(
"VM[{}] VCpu task[{}] exited with code: {}",
vm_id, idx, exit_code
);
}

info!(
Expand Down Expand Up @@ -318,7 +321,7 @@ fn vcpu_on(vm: VMRef, vcpu_id: usize, entry_point: GuestPhysAddr, arg: usize) {
vcpu.set_gpr(1, arg);
}

let vcpu_task = alloc_vcpu_task(vm.clone(), vcpu);
let vcpu_task = alloc_vcpu_task(&vm, vcpu);

VM_VCPU_TASK_WAIT_QUEUE
.get_mut(&vm.id())
Expand All @@ -342,7 +345,7 @@ pub fn setup_vm_primary_vcpu(vm: VMRef) {
let primary_vcpu_id = 0;

let primary_vcpu = vm.vcpu_list()[primary_vcpu_id].clone();
let primary_vcpu_task = alloc_vcpu_task(vm.clone(), primary_vcpu);
let primary_vcpu_task = alloc_vcpu_task(&vm, primary_vcpu);
vm_vcpus.add_vcpu_task(primary_vcpu_task);

VM_VCPU_TASK_WAIT_QUEUE.insert(vm_id, vm_vcpus);
Expand Down Expand Up @@ -383,7 +386,7 @@ pub fn with_vcpu_task<T, F: FnOnce(&AxTaskRef) -> T>(
/// * The task associated with the VCpu is created with a kernel stack size of 256 KiB.
/// * The task is created in blocked state and added to the wait queue directly,
/// instead of being added to the ready queue. It will be woken up by notify_primary_vcpu().
fn alloc_vcpu_task(vm: VMRef, vcpu: VCpuRef) -> AxTaskRef {
fn alloc_vcpu_task(vm: &VMRef, vcpu: VCpuRef) -> AxTaskRef {
info!("Spawning task for VM[{}] VCpu[{}]", vm.id(), vcpu.id());
let mut vcpu_task = TaskInner::new(
vcpu_run,
Expand All @@ -396,7 +399,8 @@ fn alloc_vcpu_task(vm: VMRef, vcpu: VCpuRef) -> AxTaskRef {
}

// Use Weak reference in TaskExt to avoid keeping VM alive
vcpu_task.init_task_ext(TaskExt::from_vm_ref(vm.clone(), vcpu));
let inner = VCpuTask::new(vm, vcpu);
*vcpu_task.task_ext_mut() = Some(unsafe { AxTaskExt::from_impl(inner) });

info!(
"VCpu task {} created {:?}",
Expand All @@ -414,8 +418,8 @@ fn alloc_vcpu_task(vm: VMRef, vcpu: VCpuRef) -> AxTaskRef {
fn vcpu_run() {
let curr = axtask::current();

let vm = curr.task_ext().vm();
let vcpu = curr.task_ext().vcpu.clone();
let vm = curr.as_vcpu_task().vm();
let vcpu = curr.as_vcpu_task().vcpu.clone();
let vm_id = vm.id();
let vcpu_id = vcpu.id();

Expand Down
2 changes: 1 addition & 1 deletion modules/axruntime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ chrono = {version = "0.4.38", default-features = false}
axplat-x86-qemu-q35 = {workspace = true}

[target.'cfg(target_arch = "aarch64")'.dependencies]
axplat-aarch64-dyn = {git = "https://github.com/arceos-hypervisor/axplat-aarch64-dyn", tag = "v0.3.3", features = ["irq", "smp", "hv"]}
axplat-aarch64-dyn = {git = "https://github.com/arceos-hypervisor/axplat-aarch64-dyn.git", branch = "v03", features = ["irq", "smp", "hv"]}
somehal = "0.4"
2 changes: 1 addition & 1 deletion modules/axruntime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ fn is_init_ok() -> bool {
#[cfg_attr(not(test), axplat::main)]
pub fn rust_main(cpu_id: usize, arg: usize) -> ! {
unsafe { axhal::mem::clear_bss() };
axhal::init_percpu(cpu_id);
axhal::percpu::init_primary(cpu_id);
axhal::init_early(cpu_id, arg);

ax_println!("{}", LOGO);
Expand Down
2 changes: 1 addition & 1 deletion modules/axruntime/src/mp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub fn start_secondary_cpus(primary_cpu_id: usize) {
/// It is called from the bootstrapping code in the specific platform crate.
#[axplat::secondary_main]
pub fn rust_main_secondary(cpu_id: usize) -> ! {
axhal::init_percpu_secondary(cpu_id);
axhal::percpu::init_secondary(cpu_id);
axhal::init_early_secondary(cpu_id);

ENTERED_CPUS.fetch_add(1, Ordering::Release);
Expand Down
2 changes: 1 addition & 1 deletion modules/driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ rockchip-pm = ["dep:rockchip-pm"]
phytium-blk = ["dep:phytium-mci"]

[dependencies]
axklib = {git = "https://github.com/arceos-hypervisor/axklib"}
axklib.workspace = true
log.workspace = true
rdif-block = "0.6.2"
rdif-clk = "0.4"
Expand Down
2 changes: 1 addition & 1 deletion platform/x86-qemu-q35/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ smp = ["axplat/smp", "kspin/smp"]

[dependencies]
axconfig-macros = "0.2"
axcpu = "0.2"
axcpu = {workspace = true}
axplat = {workspace = true}
bitflags = "2.6"
heapless = "0.9"
Expand Down
2 changes: 1 addition & 1 deletion platform/x86-qemu-q35/linker.lds.S
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,6 @@ SECTIONS {
linkm2_PAGE_FAULT : { *(linkm2_PAGE_FAULT) }
linkme_SYSCALL : { *(linkme_SYSCALL) }
linkm2_SYSCALL : { *(linkm2_SYSCALL) }
axns_resource : { *(axns_resource) }
scope_local : { *(scope_local) }
}
INSERT AFTER .tbss;
3 changes: 2 additions & 1 deletion platform/x86-qemu-q35/src/apic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,13 @@ mod irq_impl {
/// It is called by the common interrupt handler. It should look up in the
/// IRQ handler table and calls the corresponding handler. If necessary, it
/// also acknowledges the interrupt controller after handling.
fn handle(vector: usize) {
fn handle(vector: usize) -> Option<usize> {
trace!("IRQ {}", vector);
if !IRQ_HANDLER_TABLE.handle(vector) {
warn!("Unhandled IRQ {vector}");
}
unsafe { super::local_apic().end_of_interrupt() };
Some(vector)
}

/// Sends an inter-processor interrupt (IPI) to the specified target CPU or all CPUs.
Expand Down
8 changes: 8 additions & 0 deletions platform/x86-qemu-q35/src/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,12 @@ impl ConsoleIf for ConsoleIfImpl {
}
read_len
}

/// Returns the IRQ number for the console input interrupt.
///
/// Returns `None` if input interrupt is not supported.
#[cfg(feature = "irq")]
fn irq_num() -> Option<usize> {
None
}
}
Loading