1use super::Error;
5use crate::MshvProcessor;
6use hvdef::HvX64RegisterName;
7use hvdef::hypercall::HvRegisterAssoc;
8use mshv_bindings::hv_register_assoc;
9use static_assertions::assert_eq_size;
10use std::mem::offset_of;
11use virt::state::HvRegisterState;
12use virt::x86::vp;
13use virt::x86::vp::AccessVpState;
14use zerocopy::FromZeros;
15
16impl MshvProcessor<'_> {
17 pub(crate) fn set_register_state<T, const N: usize>(&self, regs: &T) -> Result<(), Error>
18 where
19 T: HvRegisterState<HvX64RegisterName, N>,
20 {
21 let mut assoc = regs.names().map(|name| HvRegisterAssoc {
22 name: name.into(),
23 pad: [0; 3],
24 value: FromZeros::new_zeroed(),
25 });
26
27 regs.get_values(assoc.iter_mut().map(|assoc| &mut assoc.value));
28
29 self.inner
30 .vcpufd
31 .set_reg(hvdef_to_mshv(&assoc[..]))
32 .map_err(Error::Register)?;
33
34 Ok(())
35 }
36
37 pub(crate) fn get_register_state<T, const N: usize>(&self) -> Result<T, Error>
38 where
39 T: HvRegisterState<HvX64RegisterName, N>,
40 {
41 let mut regs = T::default();
42 let mut assoc = regs.names().map(|name| HvRegisterAssoc {
43 name: name.into(),
44 pad: [0; 3],
45 value: FromZeros::new_zeroed(),
46 });
47
48 self.inner
49 .vcpufd
50 .get_reg(hvdef_to_mshv_mut(&mut assoc[..]))
51 .map_err(Error::Register)?;
52
53 regs.set_values(assoc.iter().map(|assoc| assoc.value));
54 Ok(regs)
55 }
56}
57
58fn hvdef_to_mshv(regs: &[HvRegisterAssoc]) -> &[hv_register_assoc] {
59 assert_eq_size!(HvRegisterAssoc, hv_register_assoc);
60 assert_eq!(
61 offset_of!(HvRegisterAssoc, name),
62 offset_of!(hv_register_assoc, name)
63 );
64 assert_eq!(
65 offset_of!(HvRegisterAssoc, value),
66 offset_of!(hv_register_assoc, value)
67 );
68 unsafe { std::mem::transmute(regs) }
70}
71
72fn hvdef_to_mshv_mut(regs: &mut [HvRegisterAssoc]) -> &mut [hv_register_assoc] {
73 assert_eq_size!(HvRegisterAssoc, hv_register_assoc);
74 assert_eq!(
75 offset_of!(HvRegisterAssoc, name),
76 offset_of!(hv_register_assoc, name)
77 );
78 assert_eq!(
79 offset_of!(HvRegisterAssoc, value),
80 offset_of!(hv_register_assoc, value)
81 );
82 unsafe { std::mem::transmute(regs) }
84}
85
86impl AccessVpState for &'_ mut MshvProcessor<'_> {
87 type Error = Error;
88
89 fn caps(&self) -> &virt::PartitionCapabilities {
90 &self.partition.caps
91 }
92
93 fn commit(&mut self) -> Result<(), Self::Error> {
94 Ok(())
95 }
96
97 fn registers(&mut self) -> Result<vp::Registers, Self::Error> {
98 self.get_register_state()
99 }
100
101 fn set_registers(&mut self, value: &vp::Registers) -> Result<(), Self::Error> {
102 self.set_register_state(value)
103 }
104
105 fn activity(&mut self) -> Result<vp::Activity, Self::Error> {
106 self.get_register_state()
107 }
108
109 fn set_activity(&mut self, value: &vp::Activity) -> Result<(), Self::Error> {
110 self.set_register_state(value)
111 }
112
113 fn xsave(&mut self) -> Result<vp::Xsave, Self::Error> {
114 todo!()
115 }
116
117 fn set_xsave(&mut self, _value: &vp::Xsave) -> Result<(), Self::Error> {
118 todo!()
119 }
120
121 fn apic(&mut self) -> Result<vp::Apic, Self::Error> {
122 todo!()
123 }
124
125 fn set_apic(&mut self, _value: &vp::Apic) -> Result<(), Self::Error> {
126 todo!()
127 }
128
129 fn xcr(&mut self) -> Result<vp::Xcr0, Self::Error> {
130 self.get_register_state()
131 }
132
133 fn set_xcr(&mut self, value: &vp::Xcr0) -> Result<(), Self::Error> {
134 self.set_register_state(value)
135 }
136
137 fn xss(&mut self) -> Result<vp::Xss, Self::Error> {
138 self.get_register_state()
139 }
140
141 fn set_xss(&mut self, value: &vp::Xss) -> Result<(), Self::Error> {
142 self.set_register_state(value)
143 }
144
145 fn mtrrs(&mut self) -> Result<vp::Mtrrs, Self::Error> {
146 self.get_register_state()
147 }
148
149 fn set_mtrrs(&mut self, value: &vp::Mtrrs) -> Result<(), Self::Error> {
150 self.set_register_state(value)
151 }
152
153 fn pat(&mut self) -> Result<vp::Pat, Self::Error> {
154 self.get_register_state()
155 }
156
157 fn set_pat(&mut self, value: &vp::Pat) -> Result<(), Self::Error> {
158 self.set_register_state(value)
159 }
160
161 fn virtual_msrs(&mut self) -> Result<vp::VirtualMsrs, Self::Error> {
162 self.get_register_state()
163 }
164
165 fn set_virtual_msrs(&mut self, value: &vp::VirtualMsrs) -> Result<(), Self::Error> {
166 self.set_register_state(value)
167 }
168
169 fn debug_regs(&mut self) -> Result<vp::DebugRegisters, Self::Error> {
170 self.get_register_state()
171 }
172
173 fn set_debug_regs(&mut self, value: &vp::DebugRegisters) -> Result<(), Self::Error> {
174 self.set_register_state(value)
175 }
176
177 fn tsc(&mut self) -> Result<vp::Tsc, Self::Error> {
178 self.get_register_state()
179 }
180
181 fn set_tsc(&mut self, value: &vp::Tsc) -> Result<(), Self::Error> {
182 self.set_register_state(value)
183 }
184
185 fn cet(&mut self) -> Result<vp::Cet, Self::Error> {
186 self.get_register_state()
187 }
188
189 fn set_cet(&mut self, value: &vp::Cet) -> Result<(), Self::Error> {
190 self.set_register_state(value)
191 }
192
193 fn cet_ss(&mut self) -> Result<vp::CetSs, Self::Error> {
194 self.get_register_state()
195 }
196
197 fn set_cet_ss(&mut self, value: &vp::CetSs) -> Result<(), Self::Error> {
198 self.set_register_state(value)
199 }
200
201 fn tsc_aux(&mut self) -> Result<vp::TscAux, Self::Error> {
202 self.get_register_state()
203 }
204
205 fn set_tsc_aux(&mut self, value: &vp::TscAux) -> Result<(), Self::Error> {
206 self.set_register_state(value)
207 }
208
209 fn synic_msrs(&mut self) -> Result<vp::SyntheticMsrs, Self::Error> {
210 self.get_register_state()
211 }
212
213 fn set_synic_msrs(&mut self, value: &vp::SyntheticMsrs) -> Result<(), Self::Error> {
214 self.set_register_state(value)
215 }
216
217 fn synic_timers(&mut self) -> Result<vp::SynicTimers, Self::Error> {
218 todo!()
219 }
220
221 fn set_synic_timers(&mut self, _value: &vp::SynicTimers) -> Result<(), Self::Error> {
222 todo!()
223 }
224
225 fn synic_message_queues(&mut self) -> Result<vp::SynicMessageQueues, Self::Error> {
226 todo!()
227 }
228
229 fn set_synic_message_queues(
230 &mut self,
231 _value: &vp::SynicMessageQueues,
232 ) -> Result<(), Self::Error> {
233 todo!()
234 }
235
236 fn synic_message_page(&mut self) -> Result<vp::SynicMessagePage, Self::Error> {
237 todo!()
238 }
239
240 fn set_synic_message_page(&mut self, _value: &vp::SynicMessagePage) -> Result<(), Self::Error> {
241 todo!()
242 }
243
244 fn synic_event_flags_page(&mut self) -> Result<vp::SynicEventFlagsPage, Self::Error> {
245 todo!()
246 }
247
248 fn set_synic_event_flags_page(
249 &mut self,
250 _value: &vp::SynicEventFlagsPage,
251 ) -> Result<(), Self::Error> {
252 todo!()
253 }
254}