vmm_vhost: make shared memory protection flags cross-platform

The existing flags assume unix libc read = 1, write = 2. On Windows we
have read = 4, write = 2. We can implement the conversion between
base::Protection and VhostUserShmemMapMsgFlags to keep the protocol
itself separate from the platform flags.

BUG=b:221882601
TEST=presubmit & tested downstream

Change-Id: I6fe69df679926b240f7d02dfbbf0704bbca5a5b0
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/3860646
Reviewed-by: David Stevens <stevensd@chromium.org>
Commit-Queue: Idan Raiter <idanr@google.com>
Tested-by: Idan Raiter <idanr@google.com>
This commit is contained in:
Idan Raiter 2022-08-28 21:27:09 -07:00 committed by crosvm LUCI
parent 710b3c9082
commit 5419f1907b
5 changed files with 27 additions and 15 deletions

View file

@ -778,8 +778,7 @@ impl SharedMemoryMapper for VhostShmemMapper {
}
_ => bail!("unsupported source"),
};
let flags = VhostUserShmemMapMsgFlags::from_bits(libc::c_int::from(prot) as u8)
.context(format!("unsupported protection flags {:?}", prot))?;
let flags = VhostUserShmemMapMsgFlags::from(prot);
let msg = VhostUserShmemMapMsg::new(self.shmid, offset, fd_offset, size, flags);
self.frontend
.shmem_map(&msg, &descriptor)

View file

@ -28,7 +28,6 @@ use base::Event;
use base::MappedRegion;
use base::MemoryMappingBuilder;
use base::MemoryMappingBuilderUnix;
use base::Protection;
use base::RawDescriptor;
use base::SafeDescriptor;
use cros_async::EventAsync;
@ -546,7 +545,7 @@ impl BackendChannelInner {
let mapping = MemoryMappingBuilder::new(msg.len as usize)
.from_descriptor(&file)
.offset(msg.fd_offset)
.protection(Protection::from(msg.flags.bits() as libc::c_int))
.protection(msg.flags.into())
.build()
.context("failed to map file")?;

View file

@ -66,7 +66,6 @@ use vmm_vhost::message::VhostUserMemoryRegion;
use vmm_vhost::message::VhostUserMsgHeader;
use vmm_vhost::message::VhostUserMsgValidator;
use vmm_vhost::message::VhostUserShmemMapMsg;
use vmm_vhost::message::VhostUserShmemMapMsgFlags;
use vmm_vhost::message::VhostUserShmemUnmapMsg;
use vmm_vhost::message::VhostUserU64;
use vmm_vhost::Error as VhostError;
@ -984,15 +983,7 @@ impl Worker {
.export(msg.fd_offset, msg.len)
.context("failed to export")?;
let prot = match (
msg.flags.contains(VhostUserShmemMapMsgFlags::MAP_R),
msg.flags.contains(VhostUserShmemMapMsgFlags::MAP_W),
) {
(true, true) => Protection::read_write(),
(true, false) => Protection::read(),
(false, true) => Protection::write(),
(false, false) => bail!("unsupported protection"),
};
let prot = Protection::from(msg.flags);
let regions = regions
.iter()
.map(|r| {

View file

@ -345,7 +345,7 @@ impl VhostUserMasterReqHandlerMut for BackendReqHandlerImpl {
gpu_blob: false,
},
req.shm_offset,
Protection::from(req.flags.bits() as libc::c_int),
Protection::from(req.flags),
) {
Ok(()) => Ok(0),
Err(e) => {

View file

@ -13,6 +13,7 @@ use std::convert::TryInto;
use std::fmt::Debug;
use std::marker::PhantomData;
use base::Protection;
use bitflags::bitflags;
use data_model::DataInit;
@ -863,6 +864,28 @@ bitflags! {
}
}
impl From<Protection> for VhostUserShmemMapMsgFlags {
fn from(prot: Protection) -> Self {
let mut flags = Self::EMPTY;
flags.set(Self::MAP_R, prot.allows(&Protection::read()));
flags.set(Self::MAP_W, prot.allows(&Protection::write()));
flags
}
}
impl From<VhostUserShmemMapMsgFlags> for Protection {
fn from(flags: VhostUserShmemMapMsgFlags) -> Self {
let mut prot = Protection::from(0);
if flags.contains(VhostUserShmemMapMsgFlags::MAP_R) {
prot = prot.set_read();
}
if flags.contains(VhostUserShmemMapMsgFlags::MAP_W) {
prot = prot.set_write();
}
prot
}
}
/// Slave request message to map a file into a shared memory region.
#[repr(C, packed)]
#[derive(Default, Copy, Clone)]