mshv_bindings/x86_64/
unmarshal.rs

1// Copyright © 2020, Microsoft Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
4//
5use crate::bindings::*;
6use vmm_sys_util::errno;
7
8type Result<T> = std::result::Result<T, errno::Error>;
9// hv_message implementation for unmarshaling payload
10impl hv_message {
11    #[inline]
12    pub fn to_cpuid_info(&self) -> Result<hv_x64_cpuid_intercept_message> {
13        if self.header.message_type != hv_message_type_HVMSG_X64_CPUID_INTERCEPT {
14            return Err(errno::Error::new(libc::EINVAL));
15        }
16        // SAFETY: We know at this point the payload is of the correct type. The payload field is
17        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
18        // copying its content out.
19        let ret =
20            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
21        Ok(ret)
22    }
23
24    #[inline]
25    pub fn to_memory_info(&self) -> Result<hv_x64_memory_intercept_message> {
26        if self.header.message_type != hv_message_type_HVMSG_GPA_INTERCEPT
27            && self.header.message_type != hv_message_type_HVMSG_UNMAPPED_GPA
28            && self.header.message_type != hv_message_type_HVMSG_UNACCEPTED_GPA
29        {
30            return Err(errno::Error::new(libc::EINVAL));
31        }
32        // SAFETY: We know at this point the payload is of the correct type. The payload field is
33        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
34        // copying its content out.
35        let ret =
36            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
37        Ok(ret)
38    }
39
40    #[inline]
41    pub fn to_gpa_attribute_info(&self) -> Result<hv_x64_gpa_attribute_intercept_message> {
42        if self.header.message_type != hv_message_type_HVMSG_GPA_ATTRIBUTE_INTERCEPT {
43            return Err(errno::Error::new(libc::EINVAL));
44        }
45        // SAFETY: We know at this point the payload is of the correct type. The payload field is
46        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
47        // copying its content out.
48        let ret =
49            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
50        Ok(ret)
51    }
52
53    #[inline]
54    pub fn to_ioport_info(&self) -> Result<hv_x64_io_port_intercept_message> {
55        if self.header.message_type != hv_message_type_HVMSG_X64_IO_PORT_INTERCEPT {
56            return Err(errno::Error::new(libc::EINVAL));
57        }
58        // SAFETY: We know at this point the payload is of the correct type. The payload field is
59        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
60        // copying its content out.
61        let ret =
62            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
63        Ok(ret)
64    }
65
66    #[inline]
67    pub fn to_msr_info(&self) -> Result<hv_x64_msr_intercept_message> {
68        if self.header.message_type != hv_message_type_HVMSG_X64_MSR_INTERCEPT {
69            return Err(errno::Error::new(libc::EINVAL));
70        }
71        // SAFETY: We know at this point the payload is of the correct type. The payload field is
72        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
73        // copying its content out.
74        let ret =
75            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
76        Ok(ret)
77    }
78
79    #[inline]
80    pub fn to_exception_info(&self) -> Result<hv_x64_exception_intercept_message> {
81        if self.header.message_type != hv_message_type_HVMSG_X64_EXCEPTION_INTERCEPT {
82            return Err(errno::Error::new(libc::EINVAL));
83        }
84        // SAFETY: We know at this point the payload is of the correct type. The payload field is
85        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
86        // copying its content out.
87        let ret =
88            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
89        Ok(ret)
90    }
91
92    #[inline]
93    pub fn to_invalid_vp_register_info(&self) -> Result<hv_x64_invalid_vp_register_message> {
94        if self.header.message_type != hv_message_type_HVMSG_INVALID_VP_REGISTER_VALUE {
95            return Err(errno::Error::new(libc::EINVAL));
96        }
97        // SAFETY: We know at this point the payload is of the correct type. The payload field is
98        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
99        // copying its content out.
100        let ret =
101            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
102        Ok(ret)
103    }
104
105    #[inline]
106    pub fn to_unrecoverable_exception_info(
107        &self,
108    ) -> Result<hv_x64_unrecoverable_exception_message> {
109        if self.header.message_type != hv_message_type_HVMSG_UNRECOVERABLE_EXCEPTION {
110            return Err(errno::Error::new(libc::EINVAL));
111        }
112        // SAFETY: We know at this point the payload is of the correct type. The payload field is
113        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
114        // copying its content out.
115        let ret =
116            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
117        Ok(ret)
118    }
119
120    #[inline]
121    pub fn to_interruption_deliverable_info(
122        &self,
123    ) -> Result<hv_x64_interruption_deliverable_message> {
124        if self.header.message_type != hv_message_type_HVMSG_X64_INTERRUPTION_DELIVERABLE {
125            return Err(errno::Error::new(libc::EINVAL));
126        }
127        // SAFETY: We know at this point the payload is of the correct type. The payload field is
128        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
129        // copying its content out.
130        let ret =
131            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
132        Ok(ret)
133    }
134
135    #[inline]
136    pub fn to_apic_eoi_info(&self) -> Result<hv_x64_apic_eoi_message> {
137        if self.header.message_type != hv_message_type_HVMSG_X64_APIC_EOI {
138            return Err(errno::Error::new(libc::EINVAL));
139        }
140        // SAFETY: We know at this point the payload is of the correct type. The payload field is
141        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
142        // copying its content out.
143        let ret =
144            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
145        Ok(ret)
146    }
147
148    #[inline]
149    pub fn to_hypercall_intercept_info(&self) -> Result<hv_x64_hypercall_intercept_message> {
150        if self.header.message_type != hv_message_type_HVMSG_HYPERCALL_INTERCEPT {
151            return Err(errno::Error::new(libc::EINVAL));
152        }
153        // SAFETY: We know at this point the payload is of the correct type. The payload field is
154        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
155        // copying its content out.
156        let ret =
157            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
158        Ok(ret)
159    }
160
161    #[inline]
162    pub fn to_sint_deliverable_info(&self) -> Result<hv_x64_sint_deliverable_message> {
163        if self.header.message_type != hv_message_type_HVMSG_SYNIC_SINT_DELIVERABLE {
164            return Err(errno::Error::new(libc::EINVAL));
165        }
166        // SAFETY: We know at this point the payload is of the correct type. The payload field is
167        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
168        // copying its content out.
169        let ret =
170            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
171        Ok(ret)
172    }
173
174    #[inline]
175    pub fn to_vmg_intercept_info(&self) -> Result<hv_x64_vmgexit_intercept_message> {
176        if self.header.message_type != hv_message_type_HVMSG_X64_SEV_VMGEXIT_INTERCEPT {
177            return Err(errno::Error::new(libc::EINVAL));
178        }
179        // SAFETY: We know at this point the payload is of the correct type. The payload field is
180        // unaligned. We use addr_of! to safely create a pointer, then call read_unaligned for
181        // copying its content out.
182        let ret =
183            unsafe { std::ptr::read_unaligned(std::ptr::addr_of!(self.u.payload) as *const _) };
184        Ok(ret)
185    }
186}