1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//! Host task extension data used by AxVM vCPU tasks.
extern crate alloc;
use alloc::sync::{Arc, Weak};
use crate::{
host::task::{TaskExt, TaskInner},
vm::{AxVCpuRef, AxVMRef},
};
/// Task extended data for a vCPU host task.
pub struct VCpuTask {
/// The VM. Stored weakly to avoid keeping a VM alive through its task.
pub vm: Weak<crate::AxVM>,
/// The virtual CPU.
pub vcpu: AxVCpuRef,
}
impl VCpuTask {
/// Create a new vCPU task extension.
pub fn new(vm: &AxVMRef, vcpu: AxVCpuRef) -> Self {
Self {
vm: Arc::downgrade(vm),
vcpu,
}
}
/// Get a strong reference to the VM.
///
/// # Panics
///
/// Panics if the VM has already been dropped.
pub fn vm(&self) -> AxVMRef {
self.vm.upgrade().expect("VM has been dropped")
}
}
#[extern_trait::extern_trait]
impl TaskExt for VCpuTask {}
/// Access a vCPU task extension from an ArceOS task.
pub trait AsVCpuTask {
/// Return this task's vCPU extension if it has one.
fn try_as_vcpu_task(&self) -> Option<&VCpuTask>;
/// Return this task's vCPU extension.
fn as_vcpu_task(&self) -> &VCpuTask;
}
impl AsVCpuTask for TaskInner {
fn try_as_vcpu_task(&self) -> Option<&VCpuTask> {
self.task_ext().map(|ext| ext.downcast_ref::<VCpuTask>())
}
fn as_vcpu_task(&self) -> &VCpuTask {
self.try_as_vcpu_task().expect("Not a VCpuTask")
}
}