vcpu.rs 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. use alloc::{
  2. boxed::Box,
  3. string::String,
  4. sync::{Arc, Weak},
  5. };
  6. use crate::{
  7. arch::{
  8. vm::{
  9. kvm_host::{vcpu::VirtCpuRequest, KvmReg},
  10. vmx::VmxVCpuPriv,
  11. },
  12. VirtCpuArch, VirtCpuStat,
  13. },
  14. libs::spinlock::{SpinLock, SpinLockGuard},
  15. process::Pid,
  16. smp::cpu::ProcessorId,
  17. virt::vm::user_api::UapiKvmRun,
  18. };
  19. use super::{
  20. mem::{GfnToHvaCache, KvmMemSlot},
  21. LockedVm,
  22. };
  23. #[derive(Debug)]
  24. pub struct LockedVirtCpu {
  25. inner: SpinLock<VirtCpu>,
  26. }
  27. impl LockedVirtCpu {
  28. pub fn new(vcpu: VirtCpu) -> Self {
  29. Self {
  30. inner: SpinLock::new(vcpu),
  31. }
  32. }
  33. pub fn lock(&self) -> SpinLockGuard<VirtCpu> {
  34. self.inner.lock()
  35. }
  36. }
  37. #[derive(Debug, PartialEq)]
  38. #[allow(dead_code)]
  39. pub enum VcpuMode {
  40. OutsideGuestMode,
  41. InGuestMode,
  42. ExitingGuestMode,
  43. ReadingShadowPageTables,
  44. }
  45. #[derive(Debug)]
  46. pub struct VirtCpu {
  47. pub cpu: ProcessorId,
  48. pub kvm: Option<Weak<LockedVm>>,
  49. /// 从用户层获取
  50. pub vcpu_id: usize,
  51. /// id alloctor获取
  52. pub vcpu_idx: usize,
  53. pub pid: Option<Pid>,
  54. pub preempted: bool,
  55. pub ready: bool,
  56. pub last_used_slot: Option<Arc<KvmMemSlot>>,
  57. pub stats_id: String,
  58. pub pv_time: GfnToHvaCache,
  59. pub arch: VirtCpuArch,
  60. pub stat: VirtCpuStat,
  61. pub mode: VcpuMode,
  62. pub guest_debug: GuestDebug,
  63. #[cfg(target_arch = "x86_64")]
  64. pub private: Option<VmxVCpuPriv>,
  65. /// 记录请求
  66. pub request: VirtCpuRequest,
  67. pub run: Option<Box<UapiKvmRun>>,
  68. }
  69. impl VirtCpu {
  70. #[inline]
  71. pub fn kvm(&self) -> Arc<LockedVm> {
  72. self.kvm.as_ref().unwrap().upgrade().unwrap()
  73. }
  74. #[cfg(target_arch = "x86_64")]
  75. pub fn vmx(&self) -> &VmxVCpuPriv {
  76. self.private.as_ref().unwrap()
  77. }
  78. #[cfg(target_arch = "x86_64")]
  79. pub fn vmx_mut(&mut self) -> &mut VmxVCpuPriv {
  80. self.private.as_mut().unwrap()
  81. }
  82. //https://code.dragonos.org.cn/xref/linux-6.6.21/arch/x86/kvm/vmx/vmx.h?fi=vmx_get_exit_qual#677
  83. #[inline]
  84. pub fn get_exit_qual(&mut self) -> u64 {
  85. if !self
  86. .arch
  87. .test_and_mark_available(KvmReg::VcpuExregExitInfo1)
  88. {
  89. self.vmx_mut().vmread_exit_qual();
  90. }
  91. let vmx = self.vmx();
  92. vmx.get_exit_qual()
  93. //vmx.
  94. }
  95. }
  96. bitflags! {
  97. pub struct GuestDebug: usize {
  98. const ENABLE = 0x00000001;
  99. const SINGLESTEP = 0x00000002;
  100. const USE_SW_BP = 0x00010000;
  101. }
  102. }