Commit 7cebefe6 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-nouveau-fixes-3.9' of...

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
parents 1caa5900 e4604d8f
...@@ -391,7 +391,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) ...@@ -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) ...@@ -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) ...@@ -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); ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment