virt_mshv/x86_64/
vm_state.rs1use crate::Error;
12use crate::ErrorInner;
13use crate::MshvPartition;
14use crate::VcpuFdExt;
15use hvdef::HvPartitionPropertyCode;
16use hvdef::HvX64RegisterName;
17use hvdef::hypercall::HvRegisterAssoc;
18use virt::state::HvRegisterState;
19use virt::x86::vm;
20use virt::x86::vm::AccessVmState;
21use zerocopy::FromZeros;
22
23impl MshvPartition {
24 fn get_vm_register_state<T, const N: usize>(&self) -> Result<T, Error>
25 where
26 T: HvRegisterState<HvX64RegisterName, N>,
27 {
28 let mut regs = T::default();
29 let mut assoc = regs.names().map(|name| HvRegisterAssoc {
30 name: name.into(),
31 pad: [0; 3],
32 value: FromZeros::new_zeroed(),
33 });
34
35 self.inner
36 .bsp_vcpufd
37 .get_hvdef_regs(&mut assoc[..])
38 .map_err(ErrorInner::Register)?;
39
40 regs.set_values(assoc.iter().map(|assoc| assoc.value));
41 Ok(regs)
42 }
43
44 fn set_vm_register_state<T, const N: usize>(&self, regs: &T) -> Result<(), Error>
45 where
46 T: HvRegisterState<HvX64RegisterName, N>,
47 {
48 let mut assoc = regs.names().map(|name| HvRegisterAssoc {
49 name: name.into(),
50 pad: [0; 3],
51 value: FromZeros::new_zeroed(),
52 });
53
54 regs.get_values(assoc.iter_mut().map(|assoc| &mut assoc.value));
55
56 self.inner
57 .bsp_vcpufd
58 .set_hvdef_regs(&assoc[..])
59 .map_err(ErrorInner::Register)?;
60 Ok(())
61 }
62}
63
64impl AccessVmState for &'_ MshvPartition {
65 type Error = Error;
66
67 fn caps(&self) -> &virt::PartitionCapabilities {
68 &self.inner.caps
69 }
70
71 fn commit(&mut self) -> Result<(), Self::Error> {
72 Ok(())
73 }
74
75 fn hypercall(&mut self) -> Result<vm::HypercallMsrs, Self::Error> {
76 self.get_vm_register_state()
77 }
78
79 fn set_hypercall(&mut self, value: &vm::HypercallMsrs) -> Result<(), Self::Error> {
80 self.set_vm_register_state(value)
81 }
82
83 fn reftime(&mut self) -> Result<vm::ReferenceTime, Self::Error> {
84 let ref_time = self
85 .inner
86 .vmfd
87 .get_partition_property(HvPartitionPropertyCode::ReferenceTime.0)
88 .map_err(|e| ErrorInner::GetPartitionProperty(e.into()))?;
89 Ok(vm::ReferenceTime { value: ref_time })
90 }
91
92 fn set_reftime(&mut self, value: &vm::ReferenceTime) -> Result<(), Self::Error> {
93 self.inner
94 .vmfd
95 .set_partition_property(HvPartitionPropertyCode::ReferenceTime.0, value.value)
96 .map_err(|e| ErrorInner::SetPartitionProperty(e.into()))?;
97 Ok(())
98 }
99
100 fn reference_tsc_page(&mut self) -> Result<vm::ReferenceTscPage, Self::Error> {
101 self.get_vm_register_state()
102 }
103
104 fn set_reference_tsc_page(&mut self, value: &vm::ReferenceTscPage) -> Result<(), Self::Error> {
105 self.set_vm_register_state(value)
106 }
107}