drm: fix quiescent locking
A fix for a locking bug which is triggered when a client tries to lock with flag DMA_QUIESCENT (typically the X server), but gets interrupted by a signal. The locking IOCTL should then return an error, but if DMA_QUIESCENT succeeds it returns 0, and the client falsely thinks it has the lock. In addition The client waits for DMA_QUISCENT and possibly DMA_READY without having the lock. From: Thomas Hellstrom Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
parent
33bc227e4e
commit
cf65f1623d
|
@ -104,6 +104,10 @@ int drm_lock(struct inode *inode, struct file *filp,
|
|||
__set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&dev->lock.lock_queue, &entry);
|
||||
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sigemptyset(&dev->sigmask);
|
||||
sigaddset(&dev->sigmask, SIGSTOP);
|
||||
sigaddset(&dev->sigmask, SIGTSTP);
|
||||
|
@ -116,8 +120,12 @@ int drm_lock(struct inode *inode, struct file *filp,
|
|||
if (dev->driver->dma_ready && (lock.flags & _DRM_LOCK_READY))
|
||||
dev->driver->dma_ready(dev);
|
||||
|
||||
if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT))
|
||||
return dev->driver->dma_quiescent(dev);
|
||||
if (dev->driver->dma_quiescent && (lock.flags & _DRM_LOCK_QUIESCENT)) {
|
||||
if (dev->driver->dma_quiescent(dev)) {
|
||||
DRM_DEBUG("%d waiting for DMA quiescent\n", lock.context);
|
||||
return DRM_ERR(EBUSY);
|
||||
}
|
||||
}
|
||||
|
||||
/* dev->driver->kernel_context_switch isn't used by any of the x86
|
||||
* drivers but is used by the Sparc driver.
|
||||
|
@ -128,9 +136,7 @@ int drm_lock(struct inode *inode, struct file *filp,
|
|||
dev->driver->kernel_context_switch(dev, dev->last_context,
|
||||
lock.context);
|
||||
}
|
||||
DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock");
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue