diff -urp a/drivers/gpu/drm/nouveau/nvkm/core/event.c b/drivers/gpu/drm/nouveau/nvkm/core/event.c --- a/drivers/gpu/drm/nouveau/nvkm/core/event.c 2023-04-06 06:12:48.000000000 -0400 +++ b/drivers/gpu/drm/nouveau/nvkm/core/event.c 2023-04-19 13:11:51.510540894 -0400 @@ -28,13 +28,30 @@ nvkm_event_put(struct nvkm_event *event, assert_spin_locked(&event->refs_lock); nvkm_trace(event->subdev, "event: decr %08x on %d\n", types, index); - + + if (index >= event->index_nr) { + nvkm_warn(event->subdev, "event: index out of range (%d >= %d)!\n", index, event->index_nr); + return; + } + while (types) { int type = __ffs(types); types &= ~(1 << type); + if (type >= event->types_nr) { + nvkm_warn(event->subdev, "event: type out of range (%d >= %d)!\n", type, event->types_nr); + continue; + } + if (--event->refs[index * event->types_nr + type] == 0) { - nvkm_trace(event->subdev, "event: blocking %d on %d\n", type, index); - if (event->func->fini) - event->func->fini(event, 1 << type, index); + nvkm_trace(event->subdev, "event: blocking %08x on %d\n", type, index); + if (event->func) { + if (event->func->fini) { + event->func->fini(event, 1 << type, index); + } else { + nvkm_debug(event->subdev, "event: no .fini, nothing to do\n"); + } + } else { + nvkm_warn(event->subdev, "event: missing .func entry!\n"); + } } } } @@ -46,12 +63,29 @@ nvkm_event_get(struct nvkm_event *event, nvkm_trace(event->subdev, "event: incr %08x on %d\n", types, index); + if (index >= event->index_nr) { + nvkm_warn(event->subdev, "event: index out of range (%d >= %d)!\n", index, event->index_nr); + return; + } + while (types) { int type = __ffs(types); types &= ~(1 << type); + if (type >= event->types_nr) { + nvkm_warn(event->subdev, "event: type out of range (%d >= %d)!\n", type, event->types_nr); + continue; + } if (++event->refs[index * event->types_nr + type] == 1) { - nvkm_trace(event->subdev, "event: allowing %d on %d\n", type, index); - if (event->func->init) - event->func->init(event, 1 << type, index); + nvkm_trace(event->subdev, "event: allowing %08x on %d\n", type, index); + if (event->func) { + if (event->func->init) { + event->func->init(event, 1 << type, index); + } else { + nvkm_debug(event->subdev, "event: no .init, nothing to do\n"); + } + } else { + nvkm_warn(event->subdev, "event: missing .func entry!\n"); + } + } } } @@ -146,7 +180,7 @@ void nvkm_event_ntfy_add(struct nvkm_event *event, int id, u32 bits, bool wait, nvkm_event_func func, struct nvkm_event_ntfy *ntfy) { - nvkm_trace(event->subdev, "event: ntfy add %08x on %d wait:%d\n", id, bits, wait); + nvkm_trace(event->subdev, "event: ntfy add %08x on %d wait:%d\n", bits, id, wait); ntfy->event = event; ntfy->id = id; @@ -201,10 +235,14 @@ int __nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev, int types_nr, int index_nr, struct nvkm_event *event) { + event->refs = kzalloc(array3_size(index_nr, types_nr, sizeof(*event->refs)), GFP_KERNEL); if (!event->refs) return -ENOMEM; + nvkm_trace(subdev, "event: init for %d types on %d indices calling %p\n", + types_nr, index_nr, func); + event->func = func; event->subdev = subdev; event->types_nr = types_nr; diff -urp a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c 2023-04-06 06:12:48.000000000 -0400 +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/uconn.c 2023-04-21 09:07:59.864884896 -0400 @@ -86,7 +86,7 @@ nvkm_uconn_uevent(struct nvkm_object *ob if (args->v0.types & NVIF_CONN_EVENT_V0_UNPLUG) bits |= NVKM_I2C_UNPLUG; if (args->v0.types & NVIF_CONN_EVENT_V0_IRQ ) bits |= NVKM_I2C_IRQ; - return nvkm_uevent_add(uevent, &device->i2c->event, outp->dp.aux->id, bits, + return nvkm_uevent_add(uevent, &device->i2c->event, (outp->dp.aux->id)&0xff, bits, nvkm_uconn_uevent_aux); } }