virt_mshv/
vp_state.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4use 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    // SAFETY: HvRegisterAssoc and hv_register_assoc have compatible definitions.
69    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    // SAFETY: HvRegisterAssoc and hv_register_assoc have compatible definitions.
83    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}