3
3
use std:: alloc:: { GlobalAlloc , Layout , System } ;
4
4
use std:: ops:: Index ;
5
5
use std:: { fmt, mem} ;
6
+ use std:: convert:: TryFrom ;
7
+ use std:: mem:: { MaybeUninit , size_of} ;
6
8
/// A rusty mimic of
7
9
/// [`kvm_cpuid`](https://elixir.bootlin.com/linux/v5.10.129/source/arch/x86/include/uapi/asm/kvm.h#L226)
8
10
/// .
@@ -16,10 +18,11 @@ use std::{fmt, mem};
16
18
#[ derive( Debug ) ]
17
19
#[ repr( C ) ]
18
20
pub struct RawCpuid {
19
- /// Number of entries
21
+ /// Number of entries.
20
22
pub nent : u32 ,
21
- padding : u32 ,
22
- // Pointer to entries
23
+ /// Padding.
24
+ pub padding : Padding < { size_of :: < u32 > ( ) } > ,
25
+ /// Pointer to entries.
23
26
pub entries : * mut RawCpuidEntry ,
24
27
}
25
28
impl RawCpuid {
@@ -48,7 +51,7 @@ impl RawCpuid {
48
51
/// On allocation failure.
49
52
pub fn push ( & mut self , entry : RawCpuidEntry ) {
50
53
unsafe {
51
- let layout = Layout :: array :: < RawCpuidEntry > ( self . nent . try_into ( ) . unwrap ( ) ) . unwrap ( ) ;
54
+ let layout = Layout :: array :: < RawCpuidEntry > ( usize :: try_from ( self . nent ) . unwrap ( ) ) . unwrap ( ) ;
52
55
let new_ptr = System . realloc (
53
56
self . entries . cast ( ) ,
54
57
layout,
@@ -57,7 +60,7 @@ impl RawCpuid {
57
60
assert ! ( !new_ptr. is_null( ) , "Allocation failure" ) ;
58
61
self . entries = new_ptr. cast ( ) ;
59
62
self . nent += 1 ;
60
- * self . entries . add ( self . nent . try_into ( ) . unwrap ( ) ) = entry;
63
+ * self . entries . add ( usize :: try_from ( self . nent ) . unwrap ( ) ) = entry;
61
64
}
62
65
}
63
66
}
@@ -106,6 +109,7 @@ impl From<RawCpuid> for kvm_bindings::CpuId {
106
109
kvm_bindings:: CpuId :: from_entries ( kvm_bindings_slice) . unwrap ( )
107
110
}
108
111
}
112
+ /// Structure used to iterate cross CPUID entries.
109
113
pub struct RawCpuidIter < ' a > {
110
114
cpuid : & ' a RawCpuid ,
111
115
count : usize ,
@@ -126,41 +130,42 @@ impl<'a> Iterator for RawCpuidIter<'a> {
126
130
rtn
127
131
}
128
132
}
133
+ /// A structure for owning unused memory for padding.
134
+ #[ derive( Debug , Clone ) ]
135
+ #[ repr( C ) ]
136
+ pub struct Padding < const N : usize > ( MaybeUninit < [ u8 ; N ] > ) ;
137
+ impl < const N : usize > Default for Padding < N > {
138
+ fn default ( ) -> Self {
139
+ Self ( MaybeUninit :: uninit ( ) )
140
+ }
141
+ }
142
+ impl < const N : usize > PartialEq for Padding < N > {
143
+ fn eq ( & self , _other : & Self ) -> bool {
144
+ true
145
+ }
146
+ }
147
+ impl < const N : usize > Eq for Padding < N > { }
148
+
149
+ /// CPUID entry (a mimic of <https://elixir.bootlin.com/linux/v5.10.129/source/arch/x86/include/uapi/asm/kvm.h#L232>).
129
150
#[ derive( Debug , Clone , Eq , PartialEq ) ]
130
151
#[ repr( C ) ]
131
152
pub struct RawCpuidEntry {
153
+ /// CPUID function (leaf).
132
154
pub function : u32 ,
155
+ /// CPUID index (subleaf).
133
156
pub index : u32 ,
157
+ /// TODO
134
158
pub flags : u32 ,
159
+ /// EAX register.
135
160
pub eax : u32 ,
161
+ /// EBX register.
136
162
pub ebx : u32 ,
163
+ /// ECX register.
137
164
pub ecx : u32 ,
165
+ /// EDX register.
138
166
pub edx : u32 ,
139
- padding : [ u32 ; 3 ] ,
140
- }
141
- impl RawCpuidEntry {
142
- #[ must_use]
143
- #[ allow( clippy:: similar_names) ]
144
- pub fn new (
145
- function : u32 ,
146
- index : u32 ,
147
- flags : u32 ,
148
- eax : u32 ,
149
- ebx : u32 ,
150
- ecx : u32 ,
151
- edx : u32 ,
152
- ) -> Self {
153
- Self {
154
- function,
155
- index,
156
- flags,
157
- eax,
158
- ebx,
159
- ecx,
160
- edx,
161
- padding : Default :: default ( ) ,
162
- }
163
- }
167
+ /// CPUID entry padding.
168
+ pub padding : Padding < { size_of :: < [ u32 ; 3 ] > ( ) } > ,
164
169
}
165
170
impl From < RawCpuidEntry > for ( u32 , u32 , u32 , u32 ) {
166
171
fn from ( this : RawCpuidEntry ) -> Self {
0 commit comments