@@ -26,16 +26,45 @@ impl IommuFd {
2626 Ok ( IommuFd { iommufd } )
2727 }
2828
29+ pub fn destroy_iommufd ( & self , id : u32 ) -> Result < ( ) > {
30+ let destroy_data = iommu_destroy {
31+ size : std:: mem:: size_of :: < iommu_destroy > ( ) as u32 ,
32+ id,
33+ } ;
34+ iommufd_syscall:: destroy_iommufd ( self , & destroy_data)
35+ }
36+
2937 pub fn alloc_iommu_ioas ( & self , alloc_data : & mut iommu_ioas_alloc ) -> Result < ( ) > {
3038 iommufd_syscall:: alloc_iommu_ioas ( self , alloc_data)
3139 }
3240
3341 pub fn map_iommu_ioas ( & self , map : & iommu_ioas_map ) -> Result < ( ) > {
3442 iommufd_syscall:: map_iommu_ioas ( self , map)
3543 }
44+
3645 pub fn unmap_iommu_ioas ( & self , unmap : & mut iommu_ioas_unmap ) -> Result < ( ) > {
3746 iommufd_syscall:: unmap_iommu_ioas ( self , unmap)
3847 }
48+
49+ pub fn alloc_iommu_hwpt ( & self , hwpt_alloc : & mut iommu_hwpt_alloc ) -> Result < ( ) > {
50+ iommufd_syscall:: alloc_iommu_hwpt ( self , hwpt_alloc)
51+ }
52+
53+ pub fn get_hw_info ( & self , hw_info : & mut iommu_hw_info ) -> Result < ( ) > {
54+ iommufd_syscall:: get_hw_info ( self , hw_info)
55+ }
56+
57+ pub fn invalidate_hwpt ( & self , hwpt_invalidate : & mut iommu_hwpt_invalidate ) -> Result < ( ) > {
58+ iommufd_syscall:: invalidate_hwpt ( self , hwpt_invalidate)
59+ }
60+
61+ pub fn alloc_iommu_viommu ( & self , viommu_alloc : & mut iommu_viommu_alloc ) -> Result < ( ) > {
62+ iommufd_syscall:: alloc_iommu_viommu ( self , viommu_alloc)
63+ }
64+
65+ pub fn alloc_iommu_vdevice ( & self , vdevice_alloc : & mut iommu_vdevice_alloc ) -> Result < ( ) > {
66+ iommufd_syscall:: alloc_iommu_vdevice ( self , vdevice_alloc)
67+ }
3968}
4069
4170impl AsRawFd for IommuFd {
@@ -44,6 +73,7 @@ impl AsRawFd for IommuFd {
4473 }
4574}
4675
76+ ioctl_io_nr ! ( IOMMU_DESTROY , IOMMUFD_TYPE as u32 , IOMMUFD_CMD_DESTROY ) ;
4777ioctl_io_nr ! (
4878 IOMMU_IOAS_ALLOC ,
4979 IOMMUFD_TYPE as u32 ,
@@ -55,6 +85,31 @@ ioctl_io_nr!(
5585 IOMMUFD_TYPE as u32 ,
5686 IOMMUFD_CMD_IOAS_UNMAP
5787) ;
88+ ioctl_io_nr ! (
89+ IOMMU_HWPT_ALLOC ,
90+ IOMMUFD_TYPE as u32 ,
91+ IOMMUFD_CMD_HWPT_ALLOC
92+ ) ;
93+ ioctl_io_nr ! (
94+ IOMMUFD_GET_HW_INFO ,
95+ IOMMUFD_TYPE as u32 ,
96+ IOMMUFD_CMD_GET_HW_INFO
97+ ) ;
98+ ioctl_io_nr ! (
99+ IOMMUFD_HWPT_INVALIDATE ,
100+ IOMMUFD_TYPE as u32 ,
101+ IOMMUFD_CMD_HWPT_INVALIDATE
102+ ) ;
103+ ioctl_io_nr ! (
104+ IOMMU_VIOMMU_ALLOC ,
105+ IOMMUFD_TYPE as u32 ,
106+ IOMMUFD_CMD_VIOMMU_ALLOC
107+ ) ;
108+ ioctl_io_nr ! (
109+ IOMMU_VDEVICE_ALLOC ,
110+ IOMMUFD_TYPE as u32 ,
111+ IOMMUFD_CMD_VDEVICE_ALLOC
112+ ) ;
58113
59114// Safety:
60115// - absolutely trust the underlying kernel
@@ -64,6 +119,19 @@ pub(crate) mod iommufd_syscall {
64119 use super :: * ;
65120 use vmm_sys_util:: ioctl:: { ioctl_with_mut_ref, ioctl_with_ref} ;
66121
122+ pub ( crate ) fn destroy_iommufd ( iommufd : & IommuFd , destroy_data : & iommu_destroy ) -> Result < ( ) > {
123+ // SAFETY:
124+ // 1. The file descriptor provided by 'iommufd' is valid and open.
125+ // 2. The 'destroy_data' points to initialized memory with expected data structure,
126+ // and remains valid for the duration of sysca
127+ // 3. The return value is checked.
128+ let ret = unsafe { ioctl_with_ref ( iommufd, IOMMU_DESTROY ( ) , destroy_data) } ;
129+ if ret < 0 {
130+ Err ( IommufdError :: IommuDestroy ( SysError :: last ( ) ) )
131+ } else {
132+ Ok ( ( ) )
133+ }
134+ }
67135 pub ( crate ) fn alloc_iommu_ioas (
68136 iommufd : & IommuFd ,
69137 alloc_data : & mut iommu_ioas_alloc ,
@@ -94,6 +162,7 @@ pub(crate) mod iommufd_syscall {
94162 Ok ( ( ) )
95163 }
96164 }
165+
97166 pub ( crate ) fn unmap_iommu_ioas ( iommufd : & IommuFd , unmap : & mut iommu_ioas_unmap ) -> Result < ( ) > {
98167 // SAFETY:
99168 // 1. The file descriptor provided by 'iommufd' is valid and open.
@@ -107,6 +176,89 @@ pub(crate) mod iommufd_syscall {
107176 Ok ( ( ) )
108177 }
109178 }
179+
180+ pub ( crate ) fn alloc_iommu_hwpt (
181+ iommufd : & IommuFd ,
182+ hwpt_alloc : & mut iommu_hwpt_alloc ,
183+ ) -> Result < ( ) > {
184+ // SAFETY:
185+ // 1. The file descriptor provided by 'iommufd' is valid and open.
186+ // 2. The 'hwpt_alloc' points to initialized memory with expected data structure,
187+ // and remains valid for the duration of syscall.
188+ // 3. The return value is checked.
189+ let ret = unsafe { ioctl_with_mut_ref ( iommufd, IOMMU_HWPT_ALLOC ( ) , hwpt_alloc) } ;
190+ if ret < 0 {
191+ Err ( IommufdError :: IommuHwptAlloc ( SysError :: last ( ) ) )
192+ } else {
193+ Ok ( ( ) )
194+ }
195+ }
196+
197+ pub ( crate ) fn get_hw_info ( iommufd : & IommuFd , hw_info : & mut iommu_hw_info ) -> Result < ( ) > {
198+ // SAFETY:
199+ // 1. The file descriptor provided by 'iommufd' is valid and open.
200+ // 2. The 'hw_info' points to initialized memory with expected data structure,
201+ // and remains valid for the duration of syscall.
202+ // 3. The return value is checked.
203+ let ret = unsafe { ioctl_with_mut_ref ( iommufd, IOMMUFD_GET_HW_INFO ( ) , hw_info) } ;
204+ if ret < 0 {
205+ Err ( IommufdError :: IommuGetHwInfo ( SysError :: last ( ) ) )
206+ } else {
207+ Ok ( ( ) )
208+ }
209+ }
210+
211+ pub ( crate ) fn invalidate_hwpt (
212+ iommufd : & IommuFd ,
213+ hwpt_invalidate : & mut iommu_hwpt_invalidate ,
214+ ) -> Result < ( ) > {
215+ // SAFETY:
216+ // 1. The file descriptor provided by 'iommufd' is valid and open.
217+ // 2. The 'hwpt_invalidate' points to initialized memory with expected data structure,
218+ // and remains valid for the duration of syscall.
219+ // 3. The return value is checked.
220+ let ret =
221+ unsafe { ioctl_with_mut_ref ( iommufd, IOMMUFD_HWPT_INVALIDATE ( ) , hwpt_invalidate) } ;
222+ if ret < 0 {
223+ Err ( IommufdError :: IommuHwptInvalidate ( SysError :: last ( ) ) )
224+ } else {
225+ Ok ( ( ) )
226+ }
227+ }
228+
229+ pub ( crate ) fn alloc_iommu_viommu (
230+ iommufd : & IommuFd ,
231+ viommu_alloc : & mut iommu_viommu_alloc ,
232+ ) -> Result < ( ) > {
233+ // SAFETY:
234+ // 1. The file descriptor provided by 'iommufd' is valid and open.
235+ // 2. The 'viommu_alloc' points to initialized memory with expected data structure,
236+ // and remains valid for the duration of syscall.
237+ // 3. The return value is checked.
238+ let ret = unsafe { ioctl_with_mut_ref ( iommufd, IOMMU_VIOMMU_ALLOC ( ) , viommu_alloc) } ;
239+ if ret < 0 {
240+ Err ( IommufdError :: IommuViommuAlloc ( SysError :: last ( ) ) )
241+ } else {
242+ Ok ( ( ) )
243+ }
244+ }
245+
246+ pub ( crate ) fn alloc_iommu_vdevice (
247+ iommufd : & IommuFd ,
248+ vdevice_alloc : & mut iommu_vdevice_alloc ,
249+ ) -> Result < ( ) > {
250+ // SAFETY:
251+ // 1. The file descriptor provided by 'iommufd' is valid and open.
252+ // 2. The 'vdevice_alloc' points to initialized memory with expected data structure,
253+ // and remains valid for the duration of syscall.
254+ // 3. The return value is checked.
255+ let ret = unsafe { ioctl_with_mut_ref ( iommufd, IOMMU_VDEVICE_ALLOC ( ) , vdevice_alloc) } ;
256+ if ret < 0 {
257+ Err ( IommufdError :: IommuVdeviceAlloc ( SysError :: last ( ) ) )
258+ } else {
259+ Ok ( ( ) )
260+ }
261+ }
110262}
111263
112264#[ cfg( test) ]
@@ -115,8 +267,14 @@ mod tests {
115267
116268 #[ test]
117269 fn test_iommufd_ioctl_code ( ) {
270+ assert_eq ! ( IOMMU_DESTROY ( ) , 15232 ) ;
118271 assert_eq ! ( IOMMU_IOAS_ALLOC ( ) , 15233 ) ;
119272 assert_eq ! ( IOMMU_IOAS_MAP ( ) , 15237 ) ;
120273 assert_eq ! ( IOMMU_IOAS_UNMAP ( ) , 15238 ) ;
274+ assert_eq ! ( IOMMU_HWPT_ALLOC ( ) , 15241 ) ;
275+ assert_eq ! ( IOMMUFD_GET_HW_INFO ( ) , 15242 ) ;
276+ assert_eq ! ( IOMMUFD_HWPT_INVALIDATE ( ) , 15245 ) ;
277+ assert_eq ! ( IOMMU_VIOMMU_ALLOC ( ) , 15248 ) ;
278+ assert_eq ! ( IOMMU_VDEVICE_ALLOC ( ) , 15249 ) ;
121279 }
122280}
0 commit comments