123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- use alloc::{
- boxed::Box,
- string::String,
- sync::{Arc, Weak},
- };
- use crate::{
- arch::{
- vm::{
- kvm_host::{vcpu::VirtCpuRequest, KvmReg},
- vmx::VmxVCpuPriv,
- },
- VirtCpuArch, VirtCpuStat,
- },
- libs::spinlock::{SpinLock, SpinLockGuard},
- process::Pid,
- smp::cpu::ProcessorId,
- virt::vm::user_api::UapiKvmRun,
- };
- use super::{
- mem::{GfnToHvaCache, KvmMemSlot},
- LockedVm,
- };
- #[derive(Debug)]
- pub struct LockedVirtCpu {
- inner: SpinLock<VirtCpu>,
- }
- impl LockedVirtCpu {
- pub fn new(vcpu: VirtCpu) -> Self {
- Self {
- inner: SpinLock::new(vcpu),
- }
- }
- pub fn lock(&self) -> SpinLockGuard<VirtCpu> {
- self.inner.lock()
- }
- }
- #[derive(Debug, PartialEq)]
- #[allow(dead_code)]
- pub enum VcpuMode {
- OutsideGuestMode,
- InGuestMode,
- ExitingGuestMode,
- ReadingShadowPageTables,
- }
- #[derive(Debug)]
- pub struct VirtCpu {
- pub cpu: ProcessorId,
- pub kvm: Option<Weak<LockedVm>>,
- /// 从用户层获取
- pub vcpu_id: usize,
- /// id alloctor获取
- pub vcpu_idx: usize,
- pub pid: Option<Pid>,
- pub preempted: bool,
- pub ready: bool,
- pub last_used_slot: Option<Arc<KvmMemSlot>>,
- pub stats_id: String,
- pub pv_time: GfnToHvaCache,
- pub arch: VirtCpuArch,
- pub stat: VirtCpuStat,
- pub mode: VcpuMode,
- pub guest_debug: GuestDebug,
- #[cfg(target_arch = "x86_64")]
- pub private: Option<VmxVCpuPriv>,
- /// 记录请求
- pub request: VirtCpuRequest,
- pub run: Option<Box<UapiKvmRun>>,
- }
- impl VirtCpu {
- #[inline]
- pub fn kvm(&self) -> Arc<LockedVm> {
- self.kvm.as_ref().unwrap().upgrade().unwrap()
- }
- #[cfg(target_arch = "x86_64")]
- pub fn vmx(&self) -> &VmxVCpuPriv {
- self.private.as_ref().unwrap()
- }
- #[cfg(target_arch = "x86_64")]
- pub fn vmx_mut(&mut self) -> &mut VmxVCpuPriv {
- self.private.as_mut().unwrap()
- }
- //https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/kvm/vmx/vmx.h?fi=vmx_get_exit_qual#677
- #[inline]
- pub fn get_exit_qual(&mut self) -> u64 {
- if !self
- .arch
- .test_and_mark_available(KvmReg::VcpuExregExitInfo1)
- {
- self.vmx_mut().vmread_exit_qual();
- }
- let vmx = self.vmx();
- vmx.get_exit_qual()
- //vmx.
- }
- }
- bitflags! {
- pub struct GuestDebug: usize {
- const ENABLE = 0x00000001;
- const SINGLESTEP = 0x00000002;
- const USE_SW_BP = 0x00010000;
- }
- }
|