From a42eca84c56f6860e67c0c57f4765a5530cc5f81 Mon Sep 17 00:00:00 2001 From: Christoph Bumiller Date: Tue, 13 Sep 2011 23:02:23 +0200 Subject: [PATCH] nvc0: prevent interruption of m2mf push M2MF will trap if the data stream is interrupted by a QUERY fence and report too much or not enough data. --- src/gallium/drivers/nvc0/nvc0_transfer.c | 38 +++++++++++------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/gallium/drivers/nvc0/nvc0_transfer.c b/src/gallium/drivers/nvc0/nvc0_transfer.c index 69d4a90ed3d..6404c8cc4ae 100644 --- a/src/gallium/drivers/nvc0/nvc0_transfer.c +++ b/src/gallium/drivers/nvc0/nvc0_transfer.c @@ -111,33 +111,31 @@ nvc0_m2mf_push_linear(struct nouveau_context *nv, uint32_t *src = (uint32_t *)data; unsigned count = (size + 3) / 4; - MARK_RING (chan, 8, 2); - - BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2); - OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR); - OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR); - BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2); - OUT_RING (chan, size); - OUT_RING (chan, 1); - BEGIN_RING(chan, RING_MF(EXEC), 1); - OUT_RING (chan, 0x100111); - while (count) { - unsigned nr = AVAIL_RING(chan); + unsigned nr; - if (nr < 9) { - FIRE_RING(chan); - nouveau_bo_validate(chan, dst, NOUVEAU_BO_WR); - continue; - } - nr = MIN2(count, nr - 1); + MARK_RING (chan, 16, 2); + + nr = AVAIL_RING(chan) - 9; + nr = MIN2(count, nr); nr = MIN2(nr, NV04_PFIFO_MAX_PACKET_LEN); - + + BEGIN_RING(chan, RING_MF(OFFSET_OUT_HIGH), 2); + OUT_RELOCh(chan, dst, offset, domain | NOUVEAU_BO_WR); + OUT_RELOCl(chan, dst, offset, domain | NOUVEAU_BO_WR); + BEGIN_RING(chan, RING_MF(LINE_LENGTH_IN), 2); + OUT_RING (chan, nr * 4); + OUT_RING (chan, 1); + BEGIN_RING(chan, RING_MF(EXEC), 1); + OUT_RING (chan, 0x100111); + + /* must not be interrupted (trap on QUERY fence, 0x50 works however) */ BEGIN_RING_NI(chan, RING_MF(DATA), nr); OUT_RINGp (chan, src, nr); - src += nr; count -= nr; + src += nr; + offset += nr * 4; } } -- 2.30.2