Merge branch 'drm-nouveau-fixes-3.9' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
Oops fixers. * 'drm-nouveau-fixes-3.9' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: drm/nouveau: fix NULL ptr dereference from nv50_disp_intr() drm/nouveau: fix handling empty channel list in ioctl's
This commit is contained in:
commit
7cebefe6cc
@ -391,7 +391,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
|
|||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_device *device = nv_device(drm->device);
|
struct nouveau_device *device = nv_device(drm->device);
|
||||||
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
||||||
struct nouveau_abi16_chan *chan, *temp;
|
struct nouveau_abi16_chan *chan = NULL, *temp;
|
||||||
struct nouveau_abi16_ntfy *ntfy;
|
struct nouveau_abi16_ntfy *ntfy;
|
||||||
struct nouveau_object *object;
|
struct nouveau_object *object;
|
||||||
struct nv_dma_class args = {};
|
struct nv_dma_class args = {};
|
||||||
@ -404,10 +404,11 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
|
|||||||
if (unlikely(nv_device(abi16->device)->card_type >= NV_C0))
|
if (unlikely(nv_device(abi16->device)->card_type >= NV_C0))
|
||||||
return nouveau_abi16_put(abi16, -EINVAL);
|
return nouveau_abi16_put(abi16, -EINVAL);
|
||||||
|
|
||||||
list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
|
list_for_each_entry(temp, &abi16->channels, head) {
|
||||||
if (chan->chan->handle == (NVDRM_CHAN | info->channel))
|
if (temp->chan->handle == (NVDRM_CHAN | info->channel)) {
|
||||||
|
chan = temp;
|
||||||
break;
|
break;
|
||||||
chan = NULL;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
@ -459,17 +460,18 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
|
|||||||
{
|
{
|
||||||
struct drm_nouveau_gpuobj_free *fini = data;
|
struct drm_nouveau_gpuobj_free *fini = data;
|
||||||
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev);
|
||||||
struct nouveau_abi16_chan *chan, *temp;
|
struct nouveau_abi16_chan *chan = NULL, *temp;
|
||||||
struct nouveau_abi16_ntfy *ntfy;
|
struct nouveau_abi16_ntfy *ntfy;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (unlikely(!abi16))
|
if (unlikely(!abi16))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
|
list_for_each_entry(temp, &abi16->channels, head) {
|
||||||
if (chan->chan->handle == (NVDRM_CHAN | fini->channel))
|
if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) {
|
||||||
|
chan = temp;
|
||||||
break;
|
break;
|
||||||
chan = NULL;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!chan)
|
if (!chan)
|
||||||
|
@ -71,12 +71,26 @@ module_param_named(modeset, nouveau_modeset, int, 0400);
|
|||||||
|
|
||||||
static struct drm_driver driver;
|
static struct drm_driver driver;
|
||||||
|
|
||||||
|
static int
|
||||||
|
nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
|
||||||
|
{
|
||||||
|
struct nouveau_drm *drm =
|
||||||
|
container_of(event, struct nouveau_drm, vblank[head]);
|
||||||
|
drm_handle_vblank(drm->dev, head);
|
||||||
|
return NVKM_EVENT_KEEP;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
nouveau_drm_vblank_enable(struct drm_device *dev, int head)
|
nouveau_drm_vblank_enable(struct drm_device *dev, int head)
|
||||||
{
|
{
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_disp *pdisp = nouveau_disp(drm->device);
|
struct nouveau_disp *pdisp = nouveau_disp(drm->device);
|
||||||
nouveau_event_get(pdisp->vblank, head, &drm->vblank);
|
|
||||||
|
if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank)))
|
||||||
|
return -EIO;
|
||||||
|
WARN_ON_ONCE(drm->vblank[head].func);
|
||||||
|
drm->vblank[head].func = nouveau_drm_vblank_handler;
|
||||||
|
nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,16 +99,11 @@ nouveau_drm_vblank_disable(struct drm_device *dev, int head)
|
|||||||
{
|
{
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
struct nouveau_disp *pdisp = nouveau_disp(drm->device);
|
struct nouveau_disp *pdisp = nouveau_disp(drm->device);
|
||||||
nouveau_event_put(pdisp->vblank, head, &drm->vblank);
|
if (drm->vblank[head].func)
|
||||||
}
|
nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]);
|
||||||
|
else
|
||||||
static int
|
WARN_ON_ONCE(1);
|
||||||
nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
|
drm->vblank[head].func = NULL;
|
||||||
{
|
|
||||||
struct nouveau_drm *drm =
|
|
||||||
container_of(event, struct nouveau_drm, vblank);
|
|
||||||
drm_handle_vblank(drm->dev, head);
|
|
||||||
return NVKM_EVENT_KEEP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64
|
static u64
|
||||||
@ -292,7 +301,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
|
|||||||
|
|
||||||
dev->dev_private = drm;
|
dev->dev_private = drm;
|
||||||
drm->dev = dev;
|
drm->dev = dev;
|
||||||
drm->vblank.func = nouveau_drm_vblank_handler;
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&drm->clients);
|
INIT_LIST_HEAD(&drm->clients);
|
||||||
spin_lock_init(&drm->tile.lock);
|
spin_lock_init(&drm->tile.lock);
|
||||||
|
@ -113,7 +113,7 @@ struct nouveau_drm {
|
|||||||
struct nvbios vbios;
|
struct nvbios vbios;
|
||||||
struct nouveau_display *display;
|
struct nouveau_display *display;
|
||||||
struct backlight_device *backlight;
|
struct backlight_device *backlight;
|
||||||
struct nouveau_eventh vblank;
|
struct nouveau_eventh vblank[4];
|
||||||
|
|
||||||
/* power management */
|
/* power management */
|
||||||
struct nouveau_pm *pm;
|
struct nouveau_pm *pm;
|
||||||
|
Loading…
Reference in New Issue
Block a user