Skip to content

Commit 427d844

Browse files
committed
vhost: add vhost-user GET_BACKEND_SPECS handling
This seems like an awful lot of boilerplate (without even any test) to implement a single message. Signed-off-by: Alex Bennée <[email protected]>
1 parent a336395 commit 427d844

File tree

6 files changed

+82
-3
lines changed

6 files changed

+82
-3
lines changed

crates/vhost-user-backend/src/backend.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::io::Result;
2222
use std::ops::Deref;
2323
use std::sync::{Arc, Mutex, RwLock};
2424

25-
use vhost::vhost_user::message::VhostUserProtocolFeatures;
25+
use vhost::vhost_user::message::{VhostUserBackendSpecs, VhostUserProtocolFeatures};
2626
use vhost::vhost_user::Slave;
2727
use vm_memory::bitmap::Bitmap;
2828
use vmm_sys_util::epoll::EventSet;
@@ -54,6 +54,9 @@ where
5454
/// Get available vhost protocol features.
5555
fn protocol_features(&self) -> VhostUserProtocolFeatures;
5656

57+
/// Get the backends specs
58+
fn specs(&self) -> VhostUserBackendSpecs;
59+
5760
/// Enable or disable the virtio EVENT_IDX feature
5861
fn set_event_idx(&self, enabled: bool);
5962

@@ -135,6 +138,9 @@ where
135138
/// Get available vhost protocol features.
136139
fn protocol_features(&self) -> VhostUserProtocolFeatures;
137140

141+
/// Get specs
142+
fn specs(&self) -> VhostUserBackendSpecs;
143+
138144
/// Enable or disable the virtio EVENT_IDX feature
139145
fn set_event_idx(&mut self, enabled: bool);
140146

@@ -220,6 +226,10 @@ where
220226
self.deref().protocol_features()
221227
}
222228

229+
fn specs(&self) -> VhostUserBackendSpecs {
230+
self.deref().specs()
231+
}
232+
223233
fn set_event_idx(&self, enabled: bool) {
224234
self.deref().set_event_idx(enabled)
225235
}
@@ -285,6 +295,10 @@ where
285295
self.lock().unwrap().protocol_features()
286296
}
287297

298+
fn specs(&self) -> VhostUserBackendSpecs {
299+
self.lock().unwrap().specs()
300+
}
301+
288302
fn set_event_idx(&self, enabled: bool) {
289303
self.lock().unwrap().set_event_idx(enabled)
290304
}
@@ -351,6 +365,10 @@ where
351365
self.read().unwrap().protocol_features()
352366
}
353367

368+
fn specs(&self) -> VhostUserBackendSpecs {
369+
self.read().unwrap().specs()
370+
}
371+
354372
fn set_event_idx(&self, enabled: bool) {
355373
self.write().unwrap().set_event_idx(enabled)
356374
}
@@ -436,6 +454,10 @@ pub mod tests {
436454
VhostUserProtocolFeatures::all()
437455
}
438456

457+
fn specs(&self) -> VhostUserBackendSpecs {
458+
VhostUserBackendSpecs::new(2, 32, 4, 8)
459+
}
460+
439461
fn set_event_idx(&mut self, enabled: bool) {
440462
self.event_idx = enabled;
441463
}

crates/vhost-user-backend/src/handler.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,10 @@ where
455455
Ok(())
456456
}
457457

458+
fn specs(&self) -> VhostUserResult<vhost::vhost_user::message::VhostUserBackendSpecs> {
459+
Ok(self.backend.specs())
460+
}
461+
458462
fn get_queue_num(&mut self) -> VhostUserResult<u64> {
459463
Ok(self.num_queues as u64)
460464
}

crates/vhost-user-backend/tests/vhost-user-server.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ use std::sync::{Arc, Barrier, Mutex};
88
use std::thread;
99

1010
use vhost::vhost_user::message::{
11-
VhostUserConfigFlags, VhostUserHeaderFlag, VhostUserInflight, VhostUserProtocolFeatures,
11+
VhostUserBackendSpecs, VhostUserConfigFlags, VhostUserHeaderFlag, VhostUserInflight,
12+
VhostUserProtocolFeatures,
1213
};
1314
use vhost::vhost_user::{Listener, Master, Slave, VhostUserMaster};
1415
use vhost::{VhostBackend, VhostUserMemoryRegionInfo, VringConfigData};
@@ -56,6 +57,10 @@ impl VhostUserBackendMut<VringRwLock, ()> for MockVhostBackend {
5657
VhostUserProtocolFeatures::all()
5758
}
5859

60+
fn specs(&self) -> VhostUserBackendSpecs {
61+
VhostUserBackendSpecs::new(1, 32, 4, 8)
62+
}
63+
5964
fn set_event_idx(&mut self, enabled: bool) {
6065
self.event_idx = enabled;
6166
}

crates/vhost/src/vhost_user/dummy_slave.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,10 @@ impl VhostUserSlaveReqHandlerMut for DummySlaveReqHandler {
204204
Ok(())
205205
}
206206

207+
fn specs(&self) -> Result<VhostUserBackendSpecs> {
208+
Ok(VhostUserBackendSpecs::new(1, 2, 3, 4))
209+
}
210+
207211
fn get_queue_num(&mut self) -> Result<u64> {
208212
Ok(MAX_QUEUE_NUM as u64)
209213
}

crates/vhost/src/vhost_user/message.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,10 @@ pub enum MasterReq {
146146
/// Query the backend for its device status as defined in the VIRTIO
147147
/// specification.
148148
GET_STATUS = 40,
149+
/// Query the backend for its emulation specification
150+
GET_BACKEND_SPECS = 41,
149151
/// Upper bound of valid commands.
150-
MAX_CMD = 41,
152+
MAX_CMD = 42,
151153
}
152154

153155
impl From<MasterReq> for u32 {
@@ -429,6 +431,8 @@ bitflags! {
429431
const STATUS = 0x0001_0000;
430432
/// Support Xen mmap.
431433
const XEN_MMAP = 0x0002_0000;
434+
/// Support GET_BACKEND_SPECS;
435+
const STANDALONE = 0x0004_0000;
432436
}
433437
}
434438

@@ -667,6 +671,35 @@ impl VhostUserSingleMemoryRegion {
667671
unsafe impl ByteValued for VhostUserSingleMemoryRegion {}
668672
impl VhostUserMsgValidator for VhostUserSingleMemoryRegion {}
669673

674+
/// Supported specs of the backend.
675+
#[repr(C)]
676+
#[derive(Default, Clone, Copy)]
677+
pub struct VhostUserBackendSpecs {
678+
/// VirtIO device ID
679+
device_id: u32,
680+
/// Size of config space
681+
config_size: u32,
682+
/// Minimum number of VQs
683+
min_vqs: u32,
684+
/// Maximum number of VQs
685+
max_vqs: u32,
686+
}
687+
688+
impl VhostUserBackendSpecs {
689+
/// Create a new instance.
690+
pub fn new(device_id: u32, config_size: u32, min_vqs: u32, max_vqs: u32) -> Self {
691+
VhostUserBackendSpecs {
692+
device_id,
693+
config_size,
694+
min_vqs,
695+
max_vqs,
696+
}
697+
}
698+
}
699+
700+
// SAFETY: Safe because all fields of VhostUserBackendSpecs are POD
701+
unsafe impl ByteValued for VhostUserBackendSpecs {}
702+
670703
/// Vring state descriptor.
671704
#[repr(packed)]
672705
#[derive(Copy, Clone, Default)]

crates/vhost/src/vhost_user/slave_req_handler.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ pub trait VhostUserSlaveReqHandler {
6161

6262
fn get_protocol_features(&self) -> Result<VhostUserProtocolFeatures>;
6363
fn set_protocol_features(&self, features: u64) -> Result<()>;
64+
fn specs(&self) -> Result<VhostUserBackendSpecs>;
6465
fn get_queue_num(&self) -> Result<u64>;
6566
fn set_vring_enable(&self, index: u32, enable: bool) -> Result<()>;
6667
fn get_config(&self, offset: u32, size: u32, flags: VhostUserConfigFlags) -> Result<Vec<u8>>;
@@ -103,6 +104,7 @@ pub trait VhostUserSlaveReqHandlerMut {
103104

104105
fn get_protocol_features(&mut self) -> Result<VhostUserProtocolFeatures>;
105106
fn set_protocol_features(&mut self, features: u64) -> Result<()>;
107+
fn specs(&self) -> Result<VhostUserBackendSpecs>;
106108
fn get_queue_num(&mut self) -> Result<u64>;
107109
fn set_vring_enable(&mut self, index: u32, enable: bool) -> Result<()>;
108110
fn get_config(
@@ -192,6 +194,10 @@ impl<T: VhostUserSlaveReqHandlerMut> VhostUserSlaveReqHandler for Mutex<T> {
192194
self.lock().unwrap().set_protocol_features(features)
193195
}
194196

197+
fn specs(&self) -> Result<VhostUserBackendSpecs> {
198+
self.lock().unwrap().specs()
199+
}
200+
195201
fn get_queue_num(&self) -> Result<u64> {
196202
self.lock().unwrap().get_queue_num()
197203
}
@@ -545,6 +551,11 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> {
545551
let msg = VhostUserU64::new(num.into());
546552
self.send_reply_message(&hdr, &msg)?;
547553
}
554+
Ok(MasterReq::GET_BACKEND_SPECS) => {
555+
self.check_proto_feature(VhostUserProtocolFeatures::STANDALONE)?;
556+
let msg = self.backend.specs()?;
557+
self.send_reply_message(&hdr, &msg)?;
558+
}
548559
_ => {
549560
return Err(Error::InvalidMessage);
550561
}

0 commit comments

Comments
 (0)