fix: deadlock in virgl_resource_create_blob, remove Box::leak
BUG 1: virgl_resource_create_blob held device lock while calling self.gem_create() which internally tries to lock device again. Rust std::sync::Mutex is not reentrant — guaranteed deadlock. Fix: release device lock before calling gem_create, using a scoped block for the has_resource_blob feature check. BUG 2: Box::leak in atomic_commit error paths converted dynamically-formatted strings to &'static str at the cost of a memory leak per error. Replaced with static &str literals.
This commit is contained in:
@@ -902,12 +902,14 @@ impl GpuDriver for VirtioDriver {
|
||||
fn virgl_resource_create_blob(
|
||||
&self, blob_mem: u32, blob_flags: u32, blob_id: u64, size: u64,
|
||||
) -> Result<(GemHandle, u32)> {
|
||||
let mut device = self
|
||||
.device
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("VirtIO device state poisoned".into()))?;
|
||||
if !device.has_resource_blob {
|
||||
return Err(DriverError::Unsupported("virgl blob resource create"));
|
||||
{
|
||||
let device = self
|
||||
.device
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("VirtIO device state poisoned".into()))?;
|
||||
if !device.has_resource_blob {
|
||||
return Err(DriverError::Unsupported("virgl blob resource create"));
|
||||
}
|
||||
}
|
||||
let gem_handle = self.gem_create(size, 0, 0)?;
|
||||
let resource = self
|
||||
@@ -916,6 +918,10 @@ impl GpuDriver for VirtioDriver {
|
||||
.map_err(|_| DriverError::Initialization("VirtIO resource state poisoned".into()))?
|
||||
.find_by_handle(gem_handle)
|
||||
.ok_or(DriverError::NotFound(format!("resource for GEM handle {}", gem_handle)))?;
|
||||
let mut device = self
|
||||
.device
|
||||
.lock()
|
||||
.map_err(|_| DriverError::Initialization("VirtIO device state poisoned".into()))?;
|
||||
device.resource_create_blob(resource.resource_id, blob_mem, blob_flags, blob_id, size)?;
|
||||
Ok((gem_handle, resource.resource_id))
|
||||
}
|
||||
@@ -1016,14 +1022,14 @@ impl GpuDriver for VirtioDriver {
|
||||
return Err(DriverError::NotFound(format!("CRTC {}", crtc_id)));
|
||||
}
|
||||
AtomicCheckResult::InvalidMode { crtc_id, reason } => {
|
||||
return Err(DriverError::InvalidArgument(Box::leak(
|
||||
format!("CRTC {} invalid mode: {}", crtc_id, reason).into_boxed_str(),
|
||||
)));
|
||||
return Err(DriverError::InvalidArgument(
|
||||
"atomic mode validation failed",
|
||||
));
|
||||
}
|
||||
AtomicCheckResult::ClockTooHigh { crtc_id, .. } => {
|
||||
return Err(DriverError::InvalidArgument(Box::leak(
|
||||
format!("CRTC {} pixel clock exceeds hardware limit", crtc_id).into_boxed_str(),
|
||||
)));
|
||||
return Err(DriverError::InvalidArgument(
|
||||
"atomic pixel clock exceeds hardware limit",
|
||||
));
|
||||
}
|
||||
AtomicCheckResult::ConnectorDisconnected { connector_id } => {
|
||||
return Err(DriverError::Initialization(format!(
|
||||
|
||||
Reference in New Issue
Block a user