On 04/01/2016 07:40 AM, Ilia Mirkin wrote:

On Mar 31, 2016 12:09 PM, "Samuel Pitoiset" <samuel.pitoi...@gmail.com
<mailto:samuel.pitoi...@gmail.com>> wrote:
 >
 > Make sure to avoid out of bounds access in presence of indirect
 > array indexing by loading the size from the driver constant buffer.
 >
 > Signed-off-by: Samuel Pitoiset <samuel.pitoi...@gmail.com
<mailto:samuel.pitoi...@gmail.com>>
 > ---
 >  .../nouveau/codegen/nv50_ir_lowering_nvc0.cpp      | 55
+++++++++++++++++++++-
 >  .../nouveau/codegen/nv50_ir_lowering_nvc0.h        |  3 ++
 >  2 files changed, 57 insertions(+), 1 deletion(-)
 >
 > diff --git
a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
 > index 850147b..989af20 100644
 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
 > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.cpp
 > @@ -1322,6 +1322,24 @@ NVC0LoweringPass::loadBufLength32(Value *ptr,
uint32_t off)
 >  }
 >
 >  inline Value *
 > +NVC0LoweringPass::loadUboInfo32(Value *ptr, uint32_t off)
 > +{
 > +   return loadResInfo32(ptr, off, prog->driver->io.uboInfoBase);
 > +}
 > +
 > +inline Value *
 > +NVC0LoweringPass::loadUboInfo64(Value *ptr, uint32_t off)
 > +{
 > +   return loadResInfo64(ptr, off, prog->driver->io.uboInfoBase);

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?

Right, this can be fixed later but I'll add a comment in the code and a note on my todolist.


 > +}
 > +
 > +inline Value *
 > +NVC0LoweringPass::loadUboLength32(Value *ptr, uint32_t off)
 > +{
 > +   return loadResLength32(ptr, off, prog->driver->io.uboInfoBase);
 > +}
 > +
 > +inline Value *
 >  NVC0LoweringPass::loadMsInfo32(Value *ptr, uint32_t off)
 >  {
 >     uint8_t b = prog->driver->io.msInfoCBSlot;
 > @@ -1711,7 +1729,42 @@ NVC0LoweringPass::handleLDST(Instruction *i)
 >           assert(prog->getType() != Program::TYPE_FRAGMENT); // INTERP
 >        }
 >     } else if (i->src(0).getFile() == FILE_MEMORY_CONST) {
 > -      if (i->src(0).isIndirect(1)) {
 > +      if (targ->getChipset() >= NVISA_GK104_CHIPSET &&
 > +          prog->getType() == Program::TYPE_COMPUTE) {
 > +         // The launch descriptor only allows to set up 8 CBs, but
OpenGL
 > +         // requires at least 12 UBOs. To bypass this limitation, we
store the
 > +         // addrs into the driver constbuf and we directly load from
the global
 > +         // memory.
 > +         if (i->src(0).isIndirect(1) || i->getSrc(0)->reg.fileIndex
 > 0) {
 > +            int8_t fileIndex = i->getSrc(0)->reg.fileIndex - 1;
 > +            Value *ind = i->getIndirect(0, 1);
 > +            Value *ptr = loadUboInfo64(ind, fileIndex * 16);
 > +            if (i->src(0).isIndirect(1)) {
 > +               Value *offset = bld.loadImm(NULL,
i->getSrc(0)->reg.data.offset + typeSizeof(i->sType));
 > +               Value *length = loadUboLength32(ind, fileIndex * 16);
 > +               Value *pred = new_LValue(func, FILE_PREDICATE);
 > +               if (i->src(0).isIndirect(0)) {
 > +                  bld.mkOp2(OP_ADD, TYPE_U64, ptr, ptr,
i->getIndirect(0, 0));
 > +                  bld.mkOp2(OP_ADD, TYPE_U32, offset, offset,
i->getIndirect(0, 0));
 > +               }
 > +               i->getSrc(0)->reg.file = FILE_MEMORY_GLOBAL;
 > +               i->setIndirect(0, 1, NULL);
 > +               i->setIndirect(0, 0, ptr);
 > +               bld.mkCmp(OP_SET, CC_GT, TYPE_U32, pred, TYPE_U32,
offset, length);
 > +               i->setPredicate(CC_NOT_P, pred);
 > +               if (i->defExists(0)) {
 > +                  bld.mkMov(i->getDef(0), bld.mkImm(0));
 > +               }
 > +            } else {
 > +               if (i->src(0).isIndirect(0)) {
 > +                  bld.mkOp2(OP_ADD, TYPE_U64, ptr, ptr,
i->getIndirect(0, 0));
 > +               }
 > +               i->getSrc(0)->reg.file = FILE_MEMORY_GLOBAL;
 > +               i->setIndirect(0, 1, NULL);
 > +               i->setIndirect(0, 0, ptr);
 > +            }
 > +         }

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?

Yeah, this code looks a bit ugly. Will try to improve it.


 > +      } else if (i->src(0).isIndirect(1)) {
 >           Value *ptr;
 >           if (i->src(0).isIndirect(0))
 >              ptr = bld.mkOp3v(OP_INSBF, TYPE_U32, bld.getSSA(),
 > diff --git
a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
 > index be81d29..aa19249 100644
 > --- a/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
 > +++ b/src/gallium/drivers/nouveau/codegen/nv50_ir_lowering_nvc0.h
 > @@ -127,6 +127,9 @@ private:
 >     Value *loadBufInfo32(Value *ptr, uint32_t off);
 >     Value *loadBufInfo64(Value *ptr, uint32_t off);
 >     Value *loadBufLength32(Value *ptr, uint32_t off);
 > +   Value *loadUboInfo32(Value *ptr, uint32_t off);
 > +   Value *loadUboInfo64(Value *ptr, uint32_t off);
 > +   Value *loadUboLength32(Value *ptr, uint32_t off);
 >     Value *loadMsInfo32(Value *ptr, uint32_t off);
 >     Value *loadTexHandle(Value *ptr, unsigned int slot);
 >
 > --
 > 2.7.4
 >
 > _______________________________________________
 > mesa-dev mailing list
 > mesa-dev@lists.freedesktop.org <mailto:mesa-dev@lists.freedesktop.org>
 > https://lists.freedesktop.org/mailman/listinfo/mesa-dev


--
-Samuel
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to