diff --git a/devices/src/virtio/gpu/virtio_gpu.rs b/devices/src/virtio/gpu/virtio_gpu.rs index cb95969bb1..ae87e3ea7a 100644 --- a/devices/src/virtio/gpu/virtio_gpu.rs +++ b/devices/src/virtio/gpu/virtio_gpu.rs @@ -859,12 +859,25 @@ impl VirtioGpu { /// Gets rutabaga's capset information associated with `index`. pub fn get_capset_info(&self, index: u32) -> VirtioGpuResult { - let (capset_id, version, size) = self.rutabaga.get_capset_info(index)?; - Ok(OkCapsetInfo { - capset_id, - version, - size, - }) + if let Ok((capset_id, version, size)) = self.rutabaga.get_capset_info(index) { + Ok(OkCapsetInfo { + capset_id, + version, + size, + }) + } else { + // Any capset_id > 63 is invalid according to the virtio-gpu spec, so we can + // intentionally poison the capset without stalling the guest kernel driver. + base::warn!( + "virtio-gpu get_capset_info(index={}) failed. intentionally poisoning response", + index + ); + Ok(OkCapsetInfo { + capset_id: u32::max_value(), + version: 0, + size: 0, + }) + } } /// Gets a capset from rutabaga. diff --git a/rutabaga_gfx/src/rutabaga_core.rs b/rutabaga_gfx/src/rutabaga_core.rs index ab89e7e872..d487449209 100644 --- a/rutabaga_gfx/src/rutabaga_core.rs +++ b/rutabaga_gfx/src/rutabaga_core.rs @@ -1177,23 +1177,26 @@ impl RutabagaBuilder { )); } - if self.default_component == RutabagaComponentType::Rutabaga2D { - let rutabaga_2d = Rutabaga2D::init(fence_handler.clone())?; - rutabaga_components.insert(RutabagaComponentType::Rutabaga2D, rutabaga_2d); - } else { + #[allow(unused_mut)] + let mut fallback_2d = false; + if self.default_component != RutabagaComponentType::Rutabaga2D { #[cfg(feature = "virgl_renderer")] if self.default_component == RutabagaComponentType::VirglRenderer { - let virgl = VirglRenderer::init( + if let Ok(virgl) = VirglRenderer::init( self.virglrenderer_flags, fence_handler.clone(), rutabaga_server_descriptor, - )?; - rutabaga_components.insert(RutabagaComponentType::VirglRenderer, virgl); + ) { + rutabaga_components.insert(RutabagaComponentType::VirglRenderer, virgl); - push_capset(RUTABAGA_CAPSET_VIRGL); - push_capset(RUTABAGA_CAPSET_VIRGL2); - push_capset(RUTABAGA_CAPSET_VENUS); - push_capset(RUTABAGA_CAPSET_DRM); + push_capset(RUTABAGA_CAPSET_VIRGL); + push_capset(RUTABAGA_CAPSET_VIRGL2); + push_capset(RUTABAGA_CAPSET_VENUS); + push_capset(RUTABAGA_CAPSET_DRM); + } else { + log::warn!("error initializing gpu backend=virglrenderer, falling back to 2d."); + fallback_2d = true; + }; } #[cfg(feature = "gfxstream")] @@ -1220,6 +1223,11 @@ impl RutabagaBuilder { push_capset(RUTABAGA_CAPSET_CROSS_DOMAIN); } + if self.default_component == RutabagaComponentType::Rutabaga2D || fallback_2d { + let rutabaga_2d = Rutabaga2D::init(fence_handler.clone())?; + rutabaga_components.insert(RutabagaComponentType::Rutabaga2D, rutabaga_2d); + } + Ok(Rutabaga { resources: Default::default(), contexts: Default::default(),