forked from Minki/linux
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_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;
|
||||
|
Loading…
Reference in New Issue
Block a user