<p dir="ltr"><br>
On Mar 31, 2016 12:09 PM, "Samuel Pitoiset" <<a href="mailto:samuel.pitoiset@gmail.com">samuel.pitoiset@gmail.com</a>> wrote:<br>
><br>
> Make sure to avoid out of bounds access in presence of indirect<br>
> array indexing by loading the size from the driver constant buffer.<br>
><br>
> Signed-off-by: Samuel Pitoiset <<a href="mailto:samuel.pitoiset@gmail.com">samuel.pitoiset@gmail.com</a>><br>
> ---<br>
>  .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp      | 55 +++++++++++++++++++++-<br>
>  .../nouveau/codegen/nv50_ir_lowering_nvc0.h        |  3 ++<br>
>  2 files changed, 57 insertions(+), 1 deletion(-)<br>
><br>
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp<br>
> index 850147b..989af20 100644<br>
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp<br>
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp<br>
> @@ -1322,6 +1322,24 @@ NVC0LoweringPass::loadBufLength32(Value *ptr, uint32_t off)<br>
>  }<br>
><br>
>  inline Value *<br>
> +NVC0LoweringPass::loadUboInfo32(Value *ptr, uint32_t off)<br>
> +{<br>
> +   return loadResInfo32(ptr, off, prog->driver->io.uboInfoBase);<br>
> +}<br>
> +<br>
> +inline Value *<br>
> +NVC0LoweringPass::loadUboInfo64(Value *ptr, uint32_t off)<br>
> +{<br>
> +   return loadResInfo64(ptr, off, prog->driver->io.uboInfoBase);</p>
<p dir="ltr">Something somewhere needs to clamp the offset to the max possible const buf... I guess I don't do this for shader buffers either :( put in a comment maybe so we don't forget?</p>
<p dir="ltr">> +}<br>
> +<br>
> +inline Value *<br>
> +NVC0LoweringPass::loadUboLength32(Value *ptr, uint32_t off)<br>
> +{<br>
> +   return loadResLength32(ptr, off, prog->driver->io.uboInfoBase);<br>
> +}<br>
> +<br>
> +inline Value *<br>
>  NVC0LoweringPass::loadMsInfo32(Value *ptr, uint32_t off)<br>
>  {<br>
>     uint8_t b = prog->driver->io.msInfoCBSlot;<br>
> @@ -1711,7 +1729,42 @@ NVC0LoweringPass::handleLDST(Instruction *i)<br>
>           assert(prog->getType() != Program::TYPE_FRAGMENT); // INTERP<br>
>        }<br>
>     } else if (i->src(0).getFile() == FILE_MEMORY_CONST) {<br>
> -      if (i->src(0).isIndirect(1)) {<br>
> +      if (targ->getChipset() >= NVISA_GK104_CHIPSET &&<br>
> +          prog->getType() == Program::TYPE_COMPUTE) {<br>
> +         // The launch descriptor only allows to set up 8 CBs, but OpenGL<br>
> +         // requires at least 12 UBOs. To bypass this limitation, we store the<br>
> +         // addrs into the driver constbuf and we directly load from the global<br>
> +         // memory.<br>
> +         if (i->src(0).isIndirect(1) || i->getSrc(0)->reg.fileIndex > 0) {<br>
> +            int8_t fileIndex = i->getSrc(0)->reg.fileIndex - 1;<br>
> +            Value *ind = i->getIndirect(0, 1);<br>
> +            Value *ptr = loadUboInfo64(ind, fileIndex * 16);<br>
> +            if (i->src(0).isIndirect(1)) {<br>
> +               Value *offset = bld.loadImm(NULL, i->getSrc(0)->reg.data.offset + typeSizeof(i->sType));<br>
> +               Value *length = loadUboLength32(ind, fileIndex * 16);<br>
> +               Value *pred = new_LValue(func, FILE_PREDICATE);<br>
> +               if (i->src(0).isIndirect(0)) {<br>
> +                  bld.mkOp2(OP_ADD, TYPE_U64, ptr, ptr, i->getIndirect(0, 0));<br>
> +                  bld.mkOp2(OP_ADD, TYPE_U32, offset, offset, i->getIndirect(0, 0));<br>
> +               }<br>
> +               i->getSrc(0)->reg.file = FILE_MEMORY_GLOBAL;<br>
> +               i->setIndirect(0, 1, NULL);<br>
> +               i->setIndirect(0, 0, ptr);<br>
> +               bld.mkCmp(OP_SET, CC_GT, TYPE_U32, pred, TYPE_U32, offset, length);<br>
> +               i->setPredicate(CC_NOT_P, pred);<br>
> +               if (i->defExists(0)) {<br>
> +                  bld.mkMov(i->getDef(0), bld.mkImm(0));<br>
> +               }<br>
> +            } else {<br>
> +               if (i->src(0).isIndirect(0)) {<br>
> +                  bld.mkOp2(OP_ADD, TYPE_U64, ptr, ptr, i->getIndirect(0, 0));<br>
> +               }<br>
> +               i->getSrc(0)->reg.file = FILE_MEMORY_GLOBAL;<br>
> +               i->setIndirect(0, 1, NULL);<br>
> +               i->setIndirect(0, 0, ptr);<br>
> +            }<br>
> +         }</p>
<p dir="ltr">This whole block is very confusing. You're checking the same conditions over and over.... Is there a clearer way of writing this logic? With fewer branches?</p>
<p dir="ltr">> +      } else if (i->src(0).isIndirect(1)) {<br>
>           Value *ptr;<br>
>           if (i->src(0).isIndirect(0))<br>
>              ptr = bld.mkOp3v(OP_INSBF, TYPE_U32, bld.getSSA(),<br>
> diff --git a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h<br>
> index be81d29..aa19249 100644<br>
> --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h<br>
> +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h<br>
> @@ -127,6 +127,9 @@ private:<br>
>     Value *loadBufInfo32(Value *ptr, uint32_t off);<br>
>     Value *loadBufInfo64(Value *ptr, uint32_t off);<br>
>     Value *loadBufLength32(Value *ptr, uint32_t off);<br>
> +   Value *loadUboInfo32(Value *ptr, uint32_t off);<br>
> +   Value *loadUboInfo64(Value *ptr, uint32_t off);<br>
> +   Value *loadUboLength32(Value *ptr, uint32_t off);<br>
>     Value *loadMsInfo32(Value *ptr, uint32_t off);<br>
>     Value *loadTexHandle(Value *ptr, unsigned int slot);<br>
><br>
> --<br>
> 2.7.4<br>
><br>
> _______________________________________________<br>
> mesa-dev mailing list<br>
> <a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
> <a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev">https://lists.freedesktop.org/mailman/listinfo/mesa-dev</a><br>
</p>