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}