@@ -26,6 +26,9 @@ use super::{
26
26
VringConfigData , VHOST_MAX_MEMORY_REGIONS ,
27
27
} ;
28
28
29
+ #[ cfg( feature = "vhost-user" ) ]
30
+ use super :: vhost_user:: message:: VhostUserVringAddrFlags ;
31
+
29
32
pub mod vhost_binding;
30
33
use self :: vhost_binding:: * ;
31
34
@@ -73,26 +76,63 @@ pub trait VhostKernBackend: AsRawFd {
73
76
}
74
77
75
78
let m = self . mem ( ) . memory ( ) ;
76
- let desc_table_size = 16 * u64:: from ( queue_size) as GuestUsize ;
77
- let avail_ring_size = 6 + 2 * u64:: from ( queue_size) as GuestUsize ;
78
- let used_ring_size = 6 + 8 * u64:: from ( queue_size) as GuestUsize ;
79
- if GuestAddress ( config_data. desc_table_addr )
80
- . checked_add ( desc_table_size)
81
- . is_none_or ( |v| !m. address_in_range ( v) )
82
- {
83
- return false ;
84
- }
85
- if GuestAddress ( config_data. avail_ring_addr )
86
- . checked_add ( avail_ring_size)
87
- . is_none_or ( |v| !m. address_in_range ( v) )
88
- {
89
- return false ;
90
- }
91
- if GuestAddress ( config_data. used_ring_addr )
92
- . checked_add ( used_ring_size)
93
- . is_none_or ( |v| !m. address_in_range ( v) )
94
- {
95
- return false ;
79
+
80
+ // Check if packed ring format is being used
81
+ #[ cfg( feature = "vhost-user" ) ]
82
+ let is_packed = config_data. flags & VhostUserVringAddrFlags :: VHOST_VRING_F_PACKED . bits ( ) != 0 ;
83
+ #[ cfg( not( feature = "vhost-user" ) ) ]
84
+ let is_packed = false ;
85
+
86
+ if is_packed {
87
+ // Packed ring: single descriptor ring layout
88
+ let desc_ring_size = 16 * u64:: from ( queue_size) as GuestUsize ;
89
+ let driver_event_size = 4 ; // 4 bytes for driver event suppression
90
+ let device_event_size = 4 ; // 4 bytes for device event suppression
91
+
92
+ // Validate packed descriptor ring
93
+ if GuestAddress ( config_data. desc_table_addr )
94
+ . checked_add ( desc_ring_size)
95
+ . is_none_or ( |v| !m. address_in_range ( v) )
96
+ {
97
+ return false ;
98
+ }
99
+ // Validate driver event suppression area (available)
100
+ if GuestAddress ( config_data. avail_ring_addr )
101
+ . checked_add ( driver_event_size)
102
+ . is_none_or ( |v| !m. address_in_range ( v) )
103
+ {
104
+ return false ;
105
+ }
106
+ // Validate device event suppression area (used)
107
+ if GuestAddress ( config_data. used_ring_addr )
108
+ . checked_add ( device_event_size)
109
+ . is_none_or ( |v| !m. address_in_range ( v) )
110
+ {
111
+ return false ;
112
+ }
113
+ } else {
114
+ // Split ring validation (existing logic)
115
+ let desc_table_size = 16 * u64:: from ( queue_size) as GuestUsize ;
116
+ let avail_ring_size = 6 + 2 * u64:: from ( queue_size) as GuestUsize ;
117
+ let used_ring_size = 6 + 8 * u64:: from ( queue_size) as GuestUsize ;
118
+ if GuestAddress ( config_data. desc_table_addr )
119
+ . checked_add ( desc_table_size)
120
+ . is_none_or ( |v| !m. address_in_range ( v) )
121
+ {
122
+ return false ;
123
+ }
124
+ if GuestAddress ( config_data. avail_ring_addr )
125
+ . checked_add ( avail_ring_size)
126
+ . is_none_or ( |v| !m. address_in_range ( v) )
127
+ {
128
+ return false ;
129
+ }
130
+ if GuestAddress ( config_data. used_ring_addr )
131
+ . checked_add ( used_ring_size)
132
+ . is_none_or ( |v| !m. address_in_range ( v) )
133
+ {
134
+ return false ;
135
+ }
96
136
}
97
137
98
138
config_data. is_log_addr_valid ( )
0 commit comments