virt/x86/
vm.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Per-VM state.
5
6use super::X86PartitionCapabilities;
7use crate::state::HvRegisterState;
8use crate::state::StateElement;
9use crate::state::state_trait;
10use hvdef::HvRegisterValue;
11use hvdef::HvX64RegisterName;
12use inspect::Inspect;
13use mesh_protobuf::Protobuf;
14use vm_topology::processor::x86::X86VpInfo;
15
16#[repr(C)]
17#[derive(Debug, Default, PartialEq, Eq, Protobuf, Inspect)]
18#[mesh(package = "virt.x86")]
19pub struct HypercallMsrs {
20    #[mesh(1)]
21    #[inspect(hex)]
22    pub guest_os_id: u64,
23    #[mesh(2)]
24    #[inspect(hex)]
25    pub hypercall: u64,
26}
27
28impl HvRegisterState<HvX64RegisterName, 2> for HypercallMsrs {
29    fn names(&self) -> &'static [HvX64RegisterName; 2] {
30        &[HvX64RegisterName::GuestOsId, HvX64RegisterName::Hypercall]
31    }
32
33    fn get_values<'a>(&self, it: impl Iterator<Item = &'a mut HvRegisterValue>) {
34        for (dest, src) in it.zip([self.guest_os_id, self.hypercall]) {
35            *dest = src.into();
36        }
37    }
38
39    fn set_values(&mut self, it: impl Iterator<Item = HvRegisterValue>) {
40        for (src, dest) in it.zip([&mut self.guest_os_id, &mut self.hypercall]) {
41            *dest = src.as_u64();
42        }
43    }
44}
45
46impl StateElement<X86PartitionCapabilities, X86VpInfo> for HypercallMsrs {
47    fn is_present(caps: &X86PartitionCapabilities) -> bool {
48        caps.hv1
49    }
50
51    fn at_reset(_caps: &X86PartitionCapabilities, _vp_info: &X86VpInfo) -> Self {
52        Self::default()
53    }
54}
55
56#[repr(C)]
57#[derive(Debug, Default, PartialEq, Eq, Protobuf, Inspect)]
58#[mesh(package = "virt.x86")]
59pub struct ReferenceTscPage {
60    #[mesh(1)]
61    #[inspect(hex)]
62    pub tsc_reference_page: u64,
63}
64
65impl HvRegisterState<HvX64RegisterName, 1> for ReferenceTscPage {
66    fn names(&self) -> &'static [HvX64RegisterName; 1] {
67        &[HvX64RegisterName::ReferenceTsc]
68    }
69
70    fn get_values<'a>(&self, it: impl Iterator<Item = &'a mut HvRegisterValue>) {
71        for (dest, src) in it.zip([self.tsc_reference_page]) {
72            *dest = src.into();
73        }
74    }
75
76    fn set_values(&mut self, it: impl Iterator<Item = HvRegisterValue>) {
77        for (src, dest) in it.zip([&mut self.tsc_reference_page]) {
78            *dest = src.as_u64();
79        }
80    }
81}
82
83impl StateElement<X86PartitionCapabilities, X86VpInfo> for ReferenceTscPage {
84    fn is_present(caps: &X86PartitionCapabilities) -> bool {
85        caps.hv1_reference_tsc_page
86    }
87
88    fn at_reset(_caps: &X86PartitionCapabilities, _vp_info: &X86VpInfo) -> Self {
89        Self::default()
90    }
91}
92
93#[repr(C)]
94#[derive(Debug, Default, PartialEq, Eq, Protobuf, Inspect)]
95#[mesh(package = "virt.x86")]
96pub struct ReferenceTime {
97    #[mesh(1)]
98    #[inspect(hex)]
99    pub value: u64,
100}
101
102impl HvRegisterState<HvX64RegisterName, 1> for ReferenceTime {
103    fn names(&self) -> &'static [HvX64RegisterName; 1] {
104        &[HvX64RegisterName::TimeRefCount]
105    }
106
107    fn get_values<'a>(&self, it: impl Iterator<Item = &'a mut HvRegisterValue>) {
108        for (dest, src) in it.zip([self.value]) {
109            *dest = src.into();
110        }
111    }
112
113    fn set_values(&mut self, it: impl Iterator<Item = HvRegisterValue>) {
114        for (src, dest) in it.zip([&mut self.value]) {
115            *dest = src.as_u64();
116        }
117    }
118}
119
120impl StateElement<X86PartitionCapabilities, X86VpInfo> for ReferenceTime {
121    fn is_present(caps: &X86PartitionCapabilities) -> bool {
122        caps.hv1
123    }
124
125    fn at_reset(_caps: &X86PartitionCapabilities, _vp_info: &X86VpInfo) -> Self {
126        Self { value: 0 }
127    }
128
129    fn can_compare(caps: &X86PartitionCapabilities) -> bool {
130        caps.can_freeze_time
131    }
132}
133
134state_trait!(
135    "Access to per-VM state.",
136    AccessVmState,
137    X86PartitionCapabilities,
138    X86VpInfo,
139    VmSavedState,
140    "virt.x86",
141    (1, "hypercall", hypercall, set_hypercall, HypercallMsrs),
142    (2, "reftime", reftime, set_reftime, ReferenceTime),
143    (
144        3,
145        "reference_tsc_page",
146        reference_tsc_page,
147        set_reference_tsc_page,
148        ReferenceTscPage,
149    ),
150);