Skip to content

Commit 2e1b330

Browse files
alexandruagbonzini
authored andcommitted
relax trait bounds for AvailIter & DescriptorChain
We are using a `: GuestAddressSpace` trait bound for `AvailIter` and `DescriptorChain`, but the objects are actually only interested in the fact that `M` can dereference to a `GuestMemory` implementation. Signed-off-by: Alexandru Agache <aagch@amazon.com>
1 parent 79f0c10 commit 2e1b330

File tree

2 files changed

+46
-24
lines changed

2 files changed

+46
-24
lines changed

crates/devices/virtio-blk/src/request.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
//! approach.
2525
2626
use std::fmt::{self, Display};
27+
use std::ops::Deref;
2728
use std::result;
2829

2930
use crate::defs::{
@@ -32,9 +33,7 @@ use crate::defs::{
3233
};
3334

3435
use virtio_queue::{Descriptor, DescriptorChain};
35-
use vm_memory::{
36-
ByteValued, Bytes, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryError,
37-
};
36+
use vm_memory::{ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryError};
3837

3938
/// Block request parsing errors.
4039
#[derive(Debug)]
@@ -159,7 +158,10 @@ impl Request {
159158
}
160159

161160
// Checks that a descriptor meets the minimal requirements for a valid status descriptor.
162-
fn check_status_desc<M: GuestMemory>(mem: &M, desc: Descriptor) -> Result<()> {
161+
fn check_status_desc<M>(mem: &M, desc: Descriptor) -> Result<()>
162+
where
163+
M: GuestMemory + ?Sized,
164+
{
163165
// The status MUST always be writable.
164166
if !desc.is_write_only() {
165167
return Err(Error::UnexpectedReadOnlyDescriptor);
@@ -202,7 +204,11 @@ impl Request {
202204
/// # Arguments
203205
/// * `desc_chain` - A mutable reference to the descriptor chain that should point to the
204206
/// buffers of a virtio block request.
205-
pub fn parse<M: GuestAddressSpace>(desc_chain: &mut DescriptorChain<M>) -> Result<Request> {
207+
pub fn parse<M>(desc_chain: &mut DescriptorChain<M>) -> Result<Request>
208+
where
209+
M: Deref,
210+
M::Target: GuestMemory,
211+
{
206212
let chain_head = desc_chain.next().ok_or(Error::DescriptorChainTooShort)?;
207213
// The head contains the request type which MUST be readable.
208214
if chain_head.is_write_only() {
@@ -235,7 +241,7 @@ impl Request {
235241
}
236242
let status_desc = desc;
237243

238-
Request::check_status_desc::<<M>::M>(desc_chain.memory(), status_desc)?;
244+
Request::check_status_desc(desc_chain.memory(), status_desc)?;
239245

240246
request.status_addr = status_desc.addr();
241247
Ok(request)

crates/virtio-queue/src/lib.rs

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ unsafe impl ByteValued for Descriptor {}
146146

147147
/// A virtio descriptor chain.
148148
#[derive(Clone, Debug)]
149-
pub struct DescriptorChain<M: GuestAddressSpace> {
150-
mem: M::T,
149+
pub struct DescriptorChain<M> {
150+
mem: M,
151151
desc_table: GuestAddress,
152152
queue_size: u16,
153153
head_index: u16,
@@ -156,9 +156,13 @@ pub struct DescriptorChain<M: GuestAddressSpace> {
156156
is_indirect: bool,
157157
}
158158

159-
impl<M: GuestAddressSpace> DescriptorChain<M> {
159+
impl<M> DescriptorChain<M>
160+
where
161+
M: Deref,
162+
M::Target: GuestMemory,
163+
{
160164
fn with_ttl(
161-
mem: M::T,
165+
mem: M,
162166
desc_table: GuestAddress,
163167
queue_size: u16,
164168
ttl: u16,
@@ -176,7 +180,7 @@ impl<M: GuestAddressSpace> DescriptorChain<M> {
176180
}
177181

178182
/// Create a new `DescriptorChain` instance.
179-
fn new(mem: M::T, desc_table: GuestAddress, queue_size: u16, head_index: u16) -> Self {
183+
fn new(mem: M, desc_table: GuestAddress, queue_size: u16, head_index: u16) -> Self {
180184
Self::with_ttl(mem, desc_table, queue_size, queue_size, head_index)
181185
}
182186

@@ -187,8 +191,8 @@ impl<M: GuestAddressSpace> DescriptorChain<M> {
187191

188192
/// Return a `GuestMemory` object that can be used to access the buffers
189193
/// pointed to by the descriptor chain.
190-
pub fn memory(&self) -> &M::M {
191-
&*self.mem
194+
pub fn memory(&self) -> &M::Target {
195+
self.mem.deref()
192196
}
193197

194198
/// Returns an iterator that only yields the readable descriptors in the chain.
@@ -237,7 +241,11 @@ impl<M: GuestAddressSpace> DescriptorChain<M> {
237241
}
238242
}
239243

240-
impl<M: GuestAddressSpace> Iterator for DescriptorChain<M> {
244+
impl<M> Iterator for DescriptorChain<M>
245+
where
246+
M: Deref,
247+
M::Target: GuestMemory,
248+
{
241249
type Item = Descriptor;
242250

243251
/// Returns the next descriptor in this descriptor chain, if there is one.
@@ -282,12 +290,16 @@ impl<M: GuestAddressSpace> Iterator for DescriptorChain<M> {
282290

283291
/// An iterator for readable or writable descriptors.
284292
#[derive(Clone)]
285-
pub struct DescriptorChainRwIter<M: GuestAddressSpace> {
293+
pub struct DescriptorChainRwIter<M> {
286294
chain: DescriptorChain<M>,
287295
writable: bool,
288296
}
289297

290-
impl<M: GuestAddressSpace> Iterator for DescriptorChainRwIter<M> {
298+
impl<M> Iterator for DescriptorChainRwIter<M>
299+
where
300+
M: Deref,
301+
M::Target: GuestMemory,
302+
{
291303
type Item = Descriptor;
292304

293305
/// Returns the next descriptor in this descriptor chain, if there is one.
@@ -311,9 +323,9 @@ impl<M: GuestAddressSpace> Iterator for DescriptorChainRwIter<M> {
311323

312324
// We can't derive Debug, because rustc doesn't generate the M::T: Debug
313325
// constraint
314-
impl<M: Debug + GuestAddressSpace> Debug for DescriptorChainRwIter<M>
326+
impl<M> Debug for DescriptorChainRwIter<M>
315327
where
316-
M::T: Debug,
328+
M: Debug,
317329
{
318330
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
319331
f.debug_struct("DescriptorChainRwIter")
@@ -325,16 +337,16 @@ where
325337

326338
/// Consuming iterator over all available descriptor chain heads in the queue.
327339
#[derive(Debug)]
328-
pub struct AvailIter<'b, M: GuestAddressSpace> {
329-
mem: M::T,
340+
pub struct AvailIter<'b, M> {
341+
mem: M,
330342
desc_table: GuestAddress,
331343
avail_ring: GuestAddress,
332344
last_index: Wrapping<u16>,
333345
queue_size: u16,
334346
next_avail: &'b mut Wrapping<u16>,
335347
}
336348

337-
impl<'b, M: GuestAddressSpace> AvailIter<'b, M> {
349+
impl<'b, M> AvailIter<'b, M> {
338350
/// Goes back one position in the available descriptor chain offered by the driver.
339351
///
340352
/// Rust does not support bidirectional iterators. This is the only way to revert the effect
@@ -347,7 +359,11 @@ impl<'b, M: GuestAddressSpace> AvailIter<'b, M> {
347359
}
348360
}
349361

350-
impl<'b, M: GuestAddressSpace> Iterator for AvailIter<'b, M> {
362+
impl<'b, M> Iterator for AvailIter<'b, M>
363+
where
364+
M: Clone + Deref,
365+
M::Target: GuestMemory,
366+
{
351367
type Item = DescriptorChain<M>;
352368

353369
fn next(&mut self) -> Option<Self::Item> {
@@ -561,7 +577,7 @@ pub struct QueueState<M: GuestAddressSpace> {
561577

562578
impl<M: GuestAddressSpace> QueueState<M> {
563579
/// Get a consuming iterator over all available descriptor chain heads offered by the driver.
564-
pub fn iter(&mut self, mem: M::T) -> Result<AvailIter<'_, M>, Error> {
580+
pub fn iter(&mut self, mem: M::T) -> Result<AvailIter<'_, M::T>, Error> {
565581
self.avail_idx(&mem, Ordering::Acquire)
566582
.map(move |idx| AvailIter {
567583
mem,
@@ -1103,7 +1119,7 @@ impl<M: GuestAddressSpace, S: QueueStateT<M>> Queue<M, S> {
11031119

11041120
impl<M: GuestAddressSpace> Queue<M, QueueState<M>> {
11051121
/// A consuming iterator over all available descriptor chain heads offered by the driver.
1106-
pub fn iter(&mut self) -> Result<AvailIter<'_, M>, Error> {
1122+
pub fn iter(&mut self) -> Result<AvailIter<'_, M::T>, Error> {
11071123
self.state.iter(self.mem.memory())
11081124
}
11091125
}

0 commit comments

Comments
 (0)