@@ -12,7 +12,7 @@ use std::os::unix::io::{FromRawFd, IntoRawFd};
12
12
use std:: result:: Result ;
13
13
use std:: sync:: { Arc , Mutex , MutexGuard , RwLock , RwLockReadGuard , RwLockWriteGuard } ;
14
14
15
- use virtio_queue:: { Error as VirtQueError , Queue } ;
15
+ use virtio_queue:: { Error as VirtQueError , Queue , QueueT } ;
16
16
use vm_memory:: { GuestAddress , GuestAddressSpace , GuestMemoryAtomic , GuestMemoryMmap } ;
17
17
use vmm_sys_util:: eventfd:: EventFd ;
18
18
@@ -32,7 +32,9 @@ pub trait VringT<M: GuestAddressSpace>:
32
32
for < ' a > VringStateGuard < ' a , M > + for < ' a > VringStateMutGuard < ' a , M >
33
33
{
34
34
/// Create a new instance of Vring.
35
- fn new ( mem : M , max_queue_size : u16 ) -> Self ;
35
+ fn new ( mem : M , max_queue_size : u16 ) -> Result < Self , VirtQueError >
36
+ where
37
+ Self : Sized ;
36
38
37
39
/// Get an immutable reference to the kick event fd.
38
40
fn get_ref ( & self ) -> <Self as VringStateGuard < M > >:: G ;
@@ -59,7 +61,12 @@ pub trait VringT<M: GuestAddressSpace>:
59
61
fn set_enabled ( & self , enabled : bool ) ;
60
62
61
63
/// Set queue addresses for descriptor table, available ring and used ring.
62
- fn set_queue_info ( & self , desc_table : u64 , avail_ring : u64 , used_ring : u64 ) ;
64
+ fn set_queue_info (
65
+ & self ,
66
+ desc_table : u64 ,
67
+ avail_ring : u64 ,
68
+ used_ring : u64 ,
69
+ ) -> Result < ( ) , VirtQueError > ;
63
70
64
71
/// Get queue next avail head.
65
72
fn queue_next_avail ( & self ) -> u16 ;
@@ -94,38 +101,41 @@ pub trait VringT<M: GuestAddressSpace>:
94
101
/// This struct maintains all information of a virito queue, and could be used as an `VringT`
95
102
/// object for single-threaded context.
96
103
pub struct VringState < M : GuestAddressSpace = GuestMemoryAtomic < GuestMemoryMmap > > {
97
- queue : Queue < M > ,
104
+ queue : Queue ,
98
105
kick : Option < EventFd > ,
99
106
call : Option < EventFd > ,
100
107
err : Option < EventFd > ,
101
108
enabled : bool ,
109
+ mem : M ,
102
110
}
103
111
104
112
impl < M : GuestAddressSpace > VringState < M > {
105
113
/// Create a new instance of Vring.
106
- fn new ( mem : M , max_queue_size : u16 ) -> Self {
107
- VringState {
108
- queue : Queue :: new ( mem , max_queue_size) ,
114
+ fn new ( mem : M , max_queue_size : u16 ) -> Result < Self , VirtQueError > {
115
+ Ok ( VringState {
116
+ queue : Queue :: new ( max_queue_size) ? ,
109
117
kick : None ,
110
118
call : None ,
111
119
err : None ,
112
120
enabled : false ,
113
- }
121
+ mem,
122
+ } )
114
123
}
115
124
116
125
/// Get an immutable reference to the underlying raw `Queue` object.
117
- pub fn get_queue ( & self ) -> & Queue < M > {
126
+ pub fn get_queue ( & self ) -> & Queue {
118
127
& self . queue
119
128
}
120
129
121
130
/// Get a mutable reference to the underlying raw `Queue` object.
122
- pub fn get_queue_mut ( & mut self ) -> & mut Queue < M > {
131
+ pub fn get_queue_mut ( & mut self ) -> & mut Queue {
123
132
& mut self . queue
124
133
}
125
134
126
135
/// Add an used descriptor into the used queue.
127
136
pub fn add_used ( & mut self , desc_index : u16 , len : u32 ) -> Result < ( ) , VirtQueError > {
128
- self . queue . add_used ( desc_index, len)
137
+ self . queue
138
+ . add_used ( self . mem . memory ( ) . deref ( ) , desc_index, len)
129
139
}
130
140
131
141
/// Notify the vhost-user master that used descriptors have been put into the used queue.
@@ -139,17 +149,17 @@ impl<M: GuestAddressSpace> VringState<M> {
139
149
140
150
/// Enable event notification for queue.
141
151
pub fn enable_notification ( & mut self ) -> Result < bool , VirtQueError > {
142
- self . queue . enable_notification ( )
152
+ self . queue . enable_notification ( self . mem . memory ( ) . deref ( ) )
143
153
}
144
154
145
155
/// Disable event notification for queue.
146
156
pub fn disable_notification ( & mut self ) -> Result < ( ) , VirtQueError > {
147
- self . queue . disable_notification ( )
157
+ self . queue . disable_notification ( self . mem . memory ( ) . deref ( ) )
148
158
}
149
159
150
160
/// Check whether a notification to the guest is needed.
151
161
pub fn needs_notification ( & mut self ) -> Result < bool , VirtQueError > {
152
- self . queue . needs_notification ( )
162
+ self . queue . needs_notification ( self . mem . memory ( ) . deref ( ) )
153
163
}
154
164
155
165
/// Set vring enabled state.
@@ -158,10 +168,18 @@ impl<M: GuestAddressSpace> VringState<M> {
158
168
}
159
169
160
170
/// Set queue addresses for descriptor table, available ring and used ring.
161
- pub fn set_queue_info ( & mut self , desc_table : u64 , avail_ring : u64 , used_ring : u64 ) {
162
- self . queue . state . desc_table = GuestAddress ( desc_table) ;
163
- self . queue . state . avail_ring = GuestAddress ( avail_ring) ;
164
- self . queue . state . used_ring = GuestAddress ( used_ring) ;
171
+ pub fn set_queue_info (
172
+ & mut self ,
173
+ desc_table : u64 ,
174
+ avail_ring : u64 ,
175
+ used_ring : u64 ,
176
+ ) -> Result < ( ) , VirtQueError > {
177
+ self . queue
178
+ . try_set_desc_table_address ( GuestAddress ( desc_table) ) ?;
179
+ self . queue
180
+ . try_set_avail_ring_address ( GuestAddress ( avail_ring) ) ?;
181
+ self . queue
182
+ . try_set_used_ring_address ( GuestAddress ( used_ring) )
165
183
}
166
184
167
185
/// Get queue next avail head.
@@ -252,10 +270,10 @@ impl<'a, M: 'a + GuestAddressSpace> VringStateMutGuard<'a, M> for VringMutex<M>
252
270
}
253
271
254
272
impl < M : ' static + GuestAddressSpace > VringT < M > for VringMutex < M > {
255
- fn new ( mem : M , max_queue_size : u16 ) -> Self {
256
- VringMutex {
257
- state : Arc :: new ( Mutex :: new ( VringState :: new ( mem, max_queue_size) ) ) ,
258
- }
273
+ fn new ( mem : M , max_queue_size : u16 ) -> Result < Self , VirtQueError > {
274
+ Ok ( VringMutex {
275
+ state : Arc :: new ( Mutex :: new ( VringState :: new ( mem, max_queue_size) ? ) ) ,
276
+ } )
259
277
}
260
278
261
279
fn get_ref ( & self ) -> <Self as VringStateGuard < M > >:: G {
@@ -290,7 +308,12 @@ impl<M: 'static + GuestAddressSpace> VringT<M> for VringMutex<M> {
290
308
self . lock ( ) . set_enabled ( enabled)
291
309
}
292
310
293
- fn set_queue_info ( & self , desc_table : u64 , avail_ring : u64 , used_ring : u64 ) {
311
+ fn set_queue_info (
312
+ & self ,
313
+ desc_table : u64 ,
314
+ avail_ring : u64 ,
315
+ used_ring : u64 ,
316
+ ) -> Result < ( ) , VirtQueError > {
294
317
self . lock ( )
295
318
. set_queue_info ( desc_table, avail_ring, used_ring)
296
319
}
@@ -354,10 +377,10 @@ impl<'a, M: 'a + GuestAddressSpace> VringStateMutGuard<'a, M> for VringRwLock<M>
354
377
}
355
378
356
379
impl < M : ' static + GuestAddressSpace > VringT < M > for VringRwLock < M > {
357
- fn new ( mem : M , max_queue_size : u16 ) -> Self {
358
- VringRwLock {
359
- state : Arc :: new ( RwLock :: new ( VringState :: new ( mem, max_queue_size) ) ) ,
360
- }
380
+ fn new ( mem : M , max_queue_size : u16 ) -> Result < Self , VirtQueError > {
381
+ Ok ( VringRwLock {
382
+ state : Arc :: new ( RwLock :: new ( VringState :: new ( mem, max_queue_size) ? ) ) ,
383
+ } )
361
384
}
362
385
363
386
fn get_ref ( & self ) -> <Self as VringStateGuard < M > >:: G {
@@ -392,7 +415,12 @@ impl<M: 'static + GuestAddressSpace> VringT<M> for VringRwLock<M> {
392
415
self . write_lock ( ) . set_enabled ( enabled)
393
416
}
394
417
395
- fn set_queue_info ( & self , desc_table : u64 , avail_ring : u64 , used_ring : u64 ) {
418
+ fn set_queue_info (
419
+ & self ,
420
+ desc_table : u64 ,
421
+ avail_ring : u64 ,
422
+ used_ring : u64 ,
423
+ ) -> Result < ( ) , VirtQueError > {
396
424
self . write_lock ( )
397
425
. set_queue_info ( desc_table, avail_ring, used_ring)
398
426
}
@@ -447,39 +475,30 @@ mod tests {
447
475
GuestMemoryMmap :: < AtomicBitmap > :: from_ranges ( & [ ( GuestAddress ( 0x100000 ) , 0x10000 ) ] )
448
476
. unwrap ( ) ,
449
477
) ;
450
- let vring = VringMutex :: new ( mem, 0x1000 ) ;
478
+ let vring = VringMutex :: new ( mem, 0x1000 ) . unwrap ( ) ;
451
479
452
480
assert ! ( vring. get_ref( ) . get_kick( ) . is_none( ) ) ;
453
481
assert ! ( !vring. get_mut( ) . enabled) ;
454
482
assert ! ( !vring. lock( ) . queue. ready( ) ) ;
455
- assert ! ( !vring. lock( ) . queue. state . event_idx_enabled) ;
483
+ assert ! ( !vring. lock( ) . queue. event_idx_enabled( ) ) ;
456
484
457
485
vring. set_enabled ( true ) ;
458
486
assert ! ( vring. get_ref( ) . enabled) ;
459
487
460
- vring. set_queue_info ( 0x100100 , 0x100200 , 0x100300 ) ;
461
- assert_eq ! (
462
- vring. lock( ) . get_queue( ) . state. desc_table,
463
- GuestAddress ( 0x100100 )
464
- ) ;
465
- assert_eq ! (
466
- vring. lock( ) . get_queue( ) . state. avail_ring,
467
- GuestAddress ( 0x100200 )
468
- ) ;
469
- assert_eq ! (
470
- vring. lock( ) . get_queue( ) . state. used_ring,
471
- GuestAddress ( 0x100300 )
472
- ) ;
488
+ vring. set_queue_info ( 0x100100 , 0x100200 , 0x100300 ) . unwrap ( ) ;
489
+ assert_eq ! ( vring. lock( ) . get_queue( ) . desc_table( ) , 0x100100 ) ;
490
+ assert_eq ! ( vring. lock( ) . get_queue( ) . avail_ring( ) , 0x100200 ) ;
491
+ assert_eq ! ( vring. lock( ) . get_queue( ) . used_ring( ) , 0x100300 ) ;
473
492
474
493
assert_eq ! ( vring. queue_next_avail( ) , 0 ) ;
475
494
vring. set_queue_next_avail ( 0x20 ) ;
476
495
assert_eq ! ( vring. queue_next_avail( ) , 0x20 ) ;
477
496
478
497
vring. set_queue_size ( 0x200 ) ;
479
- assert_eq ! ( vring. lock( ) . queue. state . size, 0x200 ) ;
498
+ assert_eq ! ( vring. lock( ) . queue. size( ) , 0x200 ) ;
480
499
481
500
vring. set_queue_event_idx ( true ) ;
482
- assert ! ( vring. lock( ) . queue. state . event_idx_enabled) ;
501
+ assert ! ( vring. lock( ) . queue. event_idx_enabled( ) ) ;
483
502
484
503
vring. set_queue_ready ( true ) ;
485
504
assert ! ( vring. lock( ) . queue. ready( ) ) ;
@@ -490,7 +509,7 @@ mod tests {
490
509
let mem = GuestMemoryAtomic :: new (
491
510
GuestMemoryMmap :: < ( ) > :: from_ranges ( & [ ( GuestAddress ( 0x100000 ) , 0x10000 ) ] ) . unwrap ( ) ,
492
511
) ;
493
- let vring = VringMutex :: new ( mem, 0x1000 ) ;
512
+ let vring = VringMutex :: new ( mem, 0x1000 ) . unwrap ( ) ;
494
513
495
514
vring. set_enabled ( true ) ;
496
515
assert ! ( vring. get_ref( ) . enabled) ;
0 commit comments