Only respond to DMABUF commands if dmabuf is enabled in config

This commit is contained in:
Bruce Leidl 2023-01-27 16:35:16 -05:00
parent ffa6075c80
commit 9b75e697d6
2 changed files with 29 additions and 17 deletions

View File

@ -1,4 +1,4 @@
use std::os::unix::io::{AsRawFd,RawFd}; use std::os::unix::io::{AsRawFd, RawFd};
use std::sync::{RwLock, Arc}; use std::sync::{RwLock, Arc};
use std::thread; use std::thread;
@ -20,15 +20,16 @@ const DMA_BUF_IOCTL_SYNC: c_ulong = iow!(DMA_BUF_IOCTL_BASE, 0, ::std::mem::size
pub struct VirtioWayland { pub struct VirtioWayland {
feature_bits: u64, feature_bits: u64,
enable_dmabuf: bool,
} }
impl VirtioWayland { impl VirtioWayland {
fn new() -> Self { fn new(enable_dmabuf: bool) -> Self {
VirtioWayland { feature_bits: 0 } VirtioWayland { feature_bits: 0, enable_dmabuf }
} }
pub fn create(vbus: &mut VirtioBus) -> virtio::Result<()> { pub fn create(vbus: &mut VirtioBus, dmabuf: bool) -> virtio::Result<()> {
let dev = Arc::new(RwLock::new(VirtioWayland::new())); let dev = Arc::new(RwLock::new(VirtioWayland::new(dmabuf)));
vbus.new_virtio_device(VIRTIO_ID_WL, dev) vbus.new_virtio_device(VIRTIO_ID_WL, dev)
.set_num_queues(2) .set_num_queues(2)
.set_features(VIRTIO_WL_F_TRANS_FLAGS as u64) .set_features(VIRTIO_WL_F_TRANS_FLAGS as u64)
@ -39,9 +40,9 @@ impl VirtioWayland {
self.feature_bits & VIRTIO_WL_F_TRANS_FLAGS as u64 != 0 self.feature_bits & VIRTIO_WL_F_TRANS_FLAGS as u64 != 0
} }
fn create_device(memory: MemoryManager, in_vq: VirtQueue, out_vq: VirtQueue, transition: bool) -> Result<WaylandDevice> { fn create_device(memory: MemoryManager, in_vq: VirtQueue, out_vq: VirtQueue, transition: bool, enable_dmabuf: bool) -> Result<WaylandDevice> {
let kill_evt = EventFd::new().map_err(Error::EventFdCreate)?; let kill_evt = EventFd::new().map_err(Error::EventFdCreate)?;
let dev = WaylandDevice::new(memory, in_vq, out_vq, kill_evt, transition)?; let dev = WaylandDevice::new(memory, in_vq, out_vq, kill_evt, transition, enable_dmabuf)?;
Ok(dev) Ok(dev)
} }
} }
@ -56,10 +57,11 @@ impl VirtioDeviceOps for VirtioWayland {
thread::spawn({ thread::spawn({
let memory = memory.clone(); let memory = memory.clone();
let transition = self.transition_flags(); let transition = self.transition_flags();
let enable_dmabuf = self.enable_dmabuf;
move || { move || {
let out_vq = queues.pop().unwrap(); let out_vq = queues.pop().unwrap();
let in_vq = queues.pop().unwrap(); let in_vq = queues.pop().unwrap();
let mut dev = match Self::create_device(memory.clone(), in_vq, out_vq,transition) { let mut dev = match Self::create_device(memory.clone(), in_vq, out_vq,transition, enable_dmabuf) {
Err(e) => { Err(e) => {
warn!("Error creating virtio wayland device: {}", e); warn!("Error creating virtio wayland device: {}", e);
return; return;
@ -78,6 +80,7 @@ struct WaylandDevice {
vfd_manager: VfdManager, vfd_manager: VfdManager,
out_vq: VirtQueue, out_vq: VirtQueue,
kill_evt: EventFd, kill_evt: EventFd,
enable_dmabuf: bool,
} }
impl WaylandDevice { impl WaylandDevice {
@ -86,12 +89,13 @@ impl WaylandDevice {
const KILL_TOKEN: u64 = 2; const KILL_TOKEN: u64 = 2;
const VFDS_TOKEN: u64 = 3; const VFDS_TOKEN: u64 = 3;
fn new(mm: MemoryManager, in_vq: VirtQueue, out_vq: VirtQueue, kill_evt: EventFd, use_transition: bool) -> Result<Self> { fn new(mm: MemoryManager, in_vq: VirtQueue, out_vq: VirtQueue, kill_evt: EventFd, use_transition: bool, enable_dmabuf: bool) -> Result<Self> {
let vfd_manager = VfdManager::new(mm, use_transition, in_vq, "/run/user/1000/wayland-0")?; let vfd_manager = VfdManager::new(mm, use_transition, in_vq, "/run/user/1000/wayland-0")?;
Ok(WaylandDevice { Ok(WaylandDevice {
vfd_manager, vfd_manager,
out_vq, out_vq,
kill_evt kill_evt,
enable_dmabuf,
}) })
} }
@ -130,7 +134,7 @@ impl WaylandDevice {
Self::OUT_VQ_TOKEN => { Self::OUT_VQ_TOKEN => {
self.out_vq.ioevent().read().map_err(Error::IoEventError)?; self.out_vq.ioevent().read().map_err(Error::IoEventError)?;
if let Some(chain) = self.out_vq.next_chain() { if let Some(chain) = self.out_vq.next_chain() {
let mut handler = MessageHandler::new(self, chain); let mut handler = MessageHandler::new(self, chain, self.enable_dmabuf);
match handler.run() { match handler.run() {
Ok(()) => { Ok(()) => {
}, },
@ -158,29 +162,37 @@ struct MessageHandler<'a> {
device: &'a mut WaylandDevice, device: &'a mut WaylandDevice,
chain: Chain, chain: Chain,
responded: bool, responded: bool,
enable_dmabuf: bool,
} }
impl <'a> MessageHandler<'a> { impl <'a> MessageHandler<'a> {
fn new(device: &'a mut WaylandDevice, chain: Chain) -> Self { fn new(device: &'a mut WaylandDevice, chain: Chain, enable_dmabuf: bool) -> Self {
MessageHandler { device, chain, responded: false } MessageHandler { device, chain, responded: false, enable_dmabuf }
} }
fn run(&mut self) -> Result<()> { fn run(&mut self) -> Result<()> {
let msg_type = self.chain.r32()?; let msg_type = self.chain.r32()?;
// Flags are always zero // Flags are always zero
let _flags = self.chain.r32()?; let _flags = self.chain.r32()?;
match msg_type { match msg_type {
VIRTIO_WL_CMD_VFD_NEW => self.cmd_new_alloc(), VIRTIO_WL_CMD_VFD_NEW => self.cmd_new_alloc(),
VIRTIO_WL_CMD_VFD_CLOSE => self.cmd_close(), VIRTIO_WL_CMD_VFD_CLOSE => self.cmd_close(),
VIRTIO_WL_CMD_VFD_SEND => self.cmd_send(), VIRTIO_WL_CMD_VFD_SEND => self.cmd_send(),
VIRTIO_WL_CMD_VFD_NEW_DMABUF => self.cmd_new_dmabuf(), VIRTIO_WL_CMD_VFD_NEW_DMABUF if self.enable_dmabuf => self.cmd_new_dmabuf(),
VIRTIO_WL_CMD_VFD_DMABUF_SYNC => self.cmd_dmabuf_sync(), VIRTIO_WL_CMD_VFD_DMABUF_SYNC if self.enable_dmabuf => self.cmd_dmabuf_sync(),
VIRTIO_WL_CMD_VFD_NEW_CTX => self.cmd_new_ctx(), VIRTIO_WL_CMD_VFD_NEW_CTX => self.cmd_new_ctx(),
VIRTIO_WL_CMD_VFD_NEW_PIPE => self.cmd_new_pipe(), VIRTIO_WL_CMD_VFD_NEW_PIPE => self.cmd_new_pipe(),
v => { v => {
self.send_invalid_command()?; self.send_invalid_command()?;
if v == VIRTIO_WL_CMD_VFD_NEW_DMABUF && !self.enable_dmabuf {
// Sommelier probes this command to determine if dmabuf is supported
// so if dmabuf is not enabled don't throw an error.
Ok(())
} else {
Err(Error::UnexpectedCommand(v)) Err(Error::UnexpectedCommand(v))
}
}, },
} }
} }

View File

@ -127,7 +127,7 @@ impl <T: ArchSetup> VmSetup <T> {
devices::VirtioRandom::create(virtio)?; devices::VirtioRandom::create(virtio)?;
if self.config.is_wayland_enabled() { if self.config.is_wayland_enabled() {
devices::VirtioWayland::create(virtio)?; devices::VirtioWayland::create(virtio, self.config.is_dmabuf_enabled())?;
} }
let homedir = self.config.homedir(); let homedir = self.config.homedir();