xen/ctrl/domain/
mod.rs

1mod info;
2use xen_sys::{
3    xc_domain_debug_control, xc_domain_decrease_reservation, xc_domain_decrease_reservation_exact,
4    xc_domain_getinfolist, xc_domain_increase_reservation, xc_domain_increase_reservation_exact,
5    xc_domain_maximum_gpfn, xc_domain_pause, xc_domain_populate_physmap,
6    xc_domain_populate_physmap_exact, xc_domain_set_access_required, xc_domain_setmaxmem,
7    xc_domain_unpause, xc_get_mem_access, xc_set_mem_access, xen_domctl_getdomaininfo,
8};
9
10pub use self::info::XenDomainInfo;
11use crate::{
12    Architecture, MemoryAccess, VcpuId, XenAltP2M, XenDeviceModel, XenDomainId, XenError,
13    XenInterface, XenMonitor, ctrl::VmEventRing, xc_check_error,
14};
15
16pub struct XenDomain<Arch>
17where
18    Arch: Architecture,
19{
20    pub(crate) interface: XenInterface,
21    pub(crate) domain_id: XenDomainId,
22    _marker: std::marker::PhantomData<Arch>,
23}
24
25impl<Arch> XenDomain<Arch>
26where
27    Arch: Architecture,
28{
29    pub(crate) fn new(interface: XenInterface, domain_id: XenDomainId) -> Result<Self, XenError> {
30        Ok(Self {
31            interface,
32            domain_id,
33            _marker: std::marker::PhantomData,
34        })
35    }
36
37    pub fn id(&self) -> XenDomainId {
38        self.domain_id
39    }
40
41    pub fn info(&self) -> Result<XenDomainInfo, XenError> {
42        let mut info = xen_domctl_getdomaininfo::default();
43        let rc = unsafe {
44            xc_domain_getinfolist(
45                self.interface.handle.0,
46                self.domain_id.0,
47                1,
48                &mut info as *mut _,
49            )
50        };
51        xc_check_error!(self.interface.handle.0, rc);
52        Ok(info.into())
53    }
54
55    pub fn maximum_gpfn(&self) -> Result<u64, XenError> {
56        let mut gpfn = 0;
57        let rc =
58            unsafe { xc_domain_maximum_gpfn(self.interface.handle.0, self.domain_id.0, &mut gpfn) };
59        xc_check_error!(self.interface.handle.0, rc);
60        Ok(gpfn)
61    }
62
63    pub fn pause(&self) -> Result<(), XenError> {
64        let rc = unsafe { xc_domain_pause(self.interface.handle.0, self.domain_id.0) };
65        xc_check_error!(self.interface.handle.0, rc);
66        Ok(())
67    }
68
69    pub fn unpause(&self) -> Result<(), XenError> {
70        let rc = unsafe { xc_domain_unpause(self.interface.handle.0, self.domain_id.0) };
71        xc_check_error!(self.interface.handle.0, rc);
72        Ok(())
73    }
74
75    pub fn get_mem_access(&self, gfn: u64) -> Result<MemoryAccess, XenError> {
76        let mut access = 0;
77        let rc = unsafe {
78            xc_get_mem_access(self.interface.handle.0, self.domain_id.0, gfn, &mut access)
79        };
80        xc_check_error!(self.interface.handle.0, rc);
81        Ok(MemoryAccess::from_bits_truncate(access as _))
82    }
83
84    pub fn set_mem_access(&self, gfn: u64, access: MemoryAccess) -> Result<(), XenError> {
85        let rc = unsafe {
86            xc_set_mem_access(
87                self.interface.handle.0,
88                self.domain_id.0,
89                access.bits().into(),
90                gfn,
91                1,
92            )
93        };
94        xc_check_error!(self.interface.handle.0, rc);
95        Ok(())
96    }
97
98    pub fn set_access_required(&self, required: bool) -> Result<(), XenError> {
99        let rc = unsafe {
100            xc_domain_set_access_required(
101                self.interface.handle.0,
102                self.domain_id.0,
103                required.into(),
104            )
105        };
106        xc_check_error!(self.interface.handle.0, rc);
107        Ok(())
108    }
109
110    pub fn debug_control(&self, vcpu: VcpuId, operation: u32) -> Result<(), XenError> {
111        let rc = unsafe {
112            xc_domain_debug_control(
113                self.interface.handle.0,
114                self.domain_id.0,
115                operation,
116                vcpu.0.into(),
117            )
118        };
119        xc_check_error!(self.interface.handle.0, rc);
120        Ok(())
121    }
122
123    pub fn set_max_mem(&self, max_memkb: u64) -> Result<(), XenError> {
124        let rc =
125            unsafe { xc_domain_setmaxmem(self.interface.handle.0, self.domain_id.0, max_memkb) };
126        xc_check_error!(self.interface.handle.0, rc);
127        Ok(())
128    }
129
130    pub fn increase_reservation(
131        &self,
132        extent_order: u32,
133        mem_flags: u32,
134        extents: &[u64],
135    ) -> Result<(), XenError> {
136        let rc = unsafe {
137            xc_domain_increase_reservation(
138                self.interface.handle.0,
139                self.domain_id.0,
140                extents.len() as u64,
141                extent_order,
142                mem_flags,
143                extents.as_ptr() as *mut _,
144            )
145        };
146        xc_check_error!(self.interface.handle.0, rc);
147        Ok(())
148    }
149
150    pub fn increase_reservation_exact(
151        &self,
152        extent_order: u32,
153        mem_flags: u32,
154        extents: &[u64],
155    ) -> Result<(), XenError> {
156        let rc = unsafe {
157            xc_domain_increase_reservation_exact(
158                self.interface.handle.0,
159                self.domain_id.0,
160                extents.len() as u64,
161                extent_order,
162                mem_flags,
163                extents.as_ptr() as *mut _,
164            )
165        };
166        xc_check_error!(self.interface.handle.0, rc);
167        Ok(())
168    }
169
170    pub fn decrease_reservation(&self, extent_order: u32, extents: &[u64]) -> Result<(), XenError> {
171        let rc = unsafe {
172            xc_domain_decrease_reservation(
173                self.interface.handle.0,
174                self.domain_id.0,
175                extents.len() as u64,
176                extent_order,
177                extents.as_ptr() as *mut _,
178            )
179        };
180        xc_check_error!(self.interface.handle.0, rc);
181        Ok(())
182    }
183
184    pub fn decrease_reservation_exact(
185        &self,
186        extent_order: u32,
187        extents: &[u64],
188    ) -> Result<(), XenError> {
189        let rc = unsafe {
190            xc_domain_decrease_reservation_exact(
191                self.interface.handle.0,
192                self.domain_id.0,
193                extents.len() as u64,
194                extent_order,
195                extents.as_ptr() as *mut _,
196            )
197        };
198        xc_check_error!(self.interface.handle.0, rc);
199        Ok(())
200    }
201
202    pub fn populate_physmap(
203        &self,
204        extent_order: u32,
205        mem_flags: u32,
206        extents: &[u64],
207    ) -> Result<(), XenError> {
208        let rc = unsafe {
209            xc_domain_populate_physmap(
210                self.interface.handle.0,
211                self.domain_id.0,
212                extents.len() as u64,
213                extent_order,
214                mem_flags,
215                extents.as_ptr() as _,
216            )
217        };
218        xc_check_error!(self.interface.handle.0, rc);
219        Ok(())
220    }
221
222    pub fn populate_physmap_exact(
223        &self,
224        extent_order: u32,
225        mem_flags: u32,
226        extents: &[u64],
227    ) -> Result<(), XenError> {
228        let rc = unsafe {
229            xc_domain_populate_physmap_exact(
230                self.interface.handle.0,
231                self.domain_id.0,
232                extents.len() as u64,
233                extent_order,
234                mem_flags,
235                extents.as_ptr() as _,
236            )
237        };
238        xc_check_error!(self.interface.handle.0, rc);
239        Ok(())
240    }
241
242    pub fn altp2m(&self) -> Result<XenAltP2M, XenError> {
243        XenAltP2M::new(self.interface.clone(), self.domain_id)
244    }
245
246    pub fn monitor(&self) -> Result<(XenMonitor, VmEventRing), XenError> {
247        XenMonitor::new(self.interface.clone(), self.domain_id)
248    }
249
250    pub fn device_model(&self) -> Result<XenDeviceModel, XenError> {
251        XenDeviceModel::new(self.domain_id)
252    }
253}