vhost_user: Support sending msg larger than MAX_MSG_SIZE
Introduce another constant MAX_MSG_SIZE that is part of the MsgHeader trait. For now this is only used for sending messages. Consider using the more specific trait constant everywhere. The VHOST_USER_GPU_UPDATE and VHOST_USER_GPU_CURSOR_UPDATE contain image data and are larger than the existing MAX_MSG_SIZE. The existing MAX_MSG_SIZE wasn't really a limitation of the protocol, just an implementation detail limitation in this crate. Signed-off-by: Matej Hrica <mhrica@redhat.com>
This commit is contained in:
parent
9b24090faf
commit
ab0c088bb6
3 changed files with 17 additions and 3 deletions
|
|
@ -226,7 +226,7 @@ impl<H: MsgHeader> Endpoint<H> {
|
|||
body: &T,
|
||||
fds: Option<&[RawFd]>,
|
||||
) -> Result<()> {
|
||||
if mem::size_of::<T>() > MAX_MSG_SIZE {
|
||||
if mem::size_of::<T>() > H::MAX_MSG_SIZE {
|
||||
return Err(Error::OversizedMsg);
|
||||
}
|
||||
let bytes = self.send_iovec_all(&[hdr.as_slice(), body.as_slice()], fds)?;
|
||||
|
|
@ -255,10 +255,10 @@ impl<H: MsgHeader> Endpoint<H> {
|
|||
fds: Option<&[RawFd]>,
|
||||
) -> Result<()> {
|
||||
let len = payload.len();
|
||||
if mem::size_of::<T>() > MAX_MSG_SIZE {
|
||||
if mem::size_of::<T>() > H::MAX_MSG_SIZE {
|
||||
return Err(Error::OversizedMsg);
|
||||
}
|
||||
if len > MAX_MSG_SIZE - mem::size_of::<T>() {
|
||||
if len > H::MAX_MSG_SIZE - mem::size_of::<T>() {
|
||||
return Err(Error::OversizedMsg);
|
||||
}
|
||||
if let Some(fd_arr) = fds {
|
||||
|
|
|
|||
|
|
@ -168,4 +168,5 @@ impl<T: Req> VhostUserMsgValidator for VhostUserGpuMsgHeader<T> {
|
|||
|
||||
impl<R: Req> MsgHeader for VhostUserGpuMsgHeader<R> {
|
||||
type Request = R;
|
||||
const MAX_MSG_SIZE: usize = u32::MAX as usize;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,15 @@ use vm_memory::{GuestAddress, MmapRange, MmapXenFlags};
|
|||
use super::{enum_value, Error, Result};
|
||||
use crate::VringConfigData;
|
||||
|
||||
/*
|
||||
TODO: Consider deprecating this. We don't actually have any preallocated buffers except in tests,
|
||||
so we should be able to support u32::MAX normally.
|
||||
Also this doesn't need to be public api, since Endpoint is private anyway, this doesn't seem
|
||||
useful for consumers of this crate.
|
||||
|
||||
There are GPU specific messages (GpuBackendReq::UPDATE and CURSOR_UPDATE) that are larger than 4K.
|
||||
We can use MsgHeader::MAX_MSG_SIZE, if we want to support larger messages only for GPU headers.
|
||||
*/
|
||||
/// The vhost-user specification uses a field of u32 to store message length.
|
||||
/// On the other hand, preallocated buffers are needed to receive messages from the Unix domain
|
||||
/// socket. To preallocating a 4GB buffer for each vhost-user message is really just an overhead.
|
||||
|
|
@ -58,6 +67,9 @@ pub(super) trait Req:
|
|||
|
||||
pub(super) trait MsgHeader: ByteValued + Copy + Default + VhostUserMsgValidator {
|
||||
type Request: Req;
|
||||
|
||||
/// The maximum size of a msg that can be encapsulated by this MsgHeader
|
||||
const MAX_MSG_SIZE: usize;
|
||||
}
|
||||
|
||||
enum_value! {
|
||||
|
|
@ -228,6 +240,7 @@ pub(super) struct VhostUserMsgHeader<R: Req> {
|
|||
|
||||
impl<R: Req> MsgHeader for VhostUserMsgHeader<R> {
|
||||
type Request = R;
|
||||
const MAX_MSG_SIZE: usize = MAX_MSG_SIZE;
|
||||
}
|
||||
|
||||
impl<R: Req> Debug for VhostUserMsgHeader<R> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue