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)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_device *device = nv_device(drm->device);
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_object *object;
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))
return nouveau_abi16_put(abi16, -EINVAL);
list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
if (chan->chan->handle == (NVDRM_CHAN | info->channel))
list_for_each_entry(temp, &abi16->channels, head) {
if (temp->chan->handle == (NVDRM_CHAN | info->channel)) {
chan = temp;
break;
chan = NULL;
}
}
if (!chan)
......@@ -459,17 +460,18 @@ nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS)
{
struct drm_nouveau_gpuobj_free *fini = data;
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;
int ret;
if (unlikely(!abi16))
return -ENOMEM;
list_for_each_entry_safe(chan, temp, &abi16->channels, head) {
if (chan->chan->handle == (NVDRM_CHAN | fini->channel))
list_for_each_entry(temp, &abi16->channels, head) {
if (temp->chan->handle == (NVDRM_CHAN | fini->channel)) {
chan = temp;
break;
chan = NULL;
}
}
if (!chan)
......
......@@ -71,12 +71,26 @@ module_param_named(modeset, nouveau_modeset, int, 0400);
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
nouveau_drm_vblank_enable(struct drm_device *dev, int head)
{
struct nouveau_drm *drm = nouveau_drm(dev);
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;
}
......@@ -85,16 +99,11 @@ nouveau_drm_vblank_disable(struct drm_device *dev, int head)
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_disp *pdisp = nouveau_disp(drm->device);
nouveau_event_put(pdisp->vblank, head, &drm->vblank);
}
static int
nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head)
{
struct nouveau_drm *drm =
container_of(event, struct nouveau_drm, vblank);
drm_handle_vblank(drm->dev, head);
return NVKM_EVENT_KEEP;
if (drm->vblank[head].func)
nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]);
else
WARN_ON_ONCE(1);
drm->vblank[head].func = NULL;
}
static u64
......@@ -292,7 +301,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
dev->dev_private = drm;
drm->dev = dev;
drm->vblank.func = nouveau_drm_vblank_handler;
INIT_LIST_HEAD(&drm->clients);
spin_lock_init(&drm->tile.lock);
......
......@@ -113,7 +113,7 @@ struct nouveau_drm {
struct nvbios vbios;
struct nouveau_display *display;
struct backlight_device *backlight;
struct nouveau_eventh vblank;
struct nouveau_eventh vblank[4];
/* power management */
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