Commit afac0e43 authored by Terje Bergstrom's avatar Terje Bergstrom Committed by Thierry Reding

gpu: host1x: Don't reset firewall between gathers

The firewall was reinitialised for each gather. Because the filter
was reinitialised, it did not track the class over gather boundaries.
This allowed the user application to set host1x class to one class
in one gather and use that class in another gather without firewall
having knowledge about that.
Signed-off-by: default avatarTerje Bergstrom <tbergstrom@nvidia.com>
Signed-off-by: default avatarArto Merilainen <amerilainen@nvidia.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 5060d8ec
...@@ -376,69 +376,60 @@ static int check_nonincr(struct host1x_firewall *fw) ...@@ -376,69 +376,60 @@ static int check_nonincr(struct host1x_firewall *fw)
return 0; return 0;
} }
static int validate(struct host1x_job *job, struct device *dev, static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g)
struct host1x_job_gather *g)
{ {
u32 *cmdbuf_base; u32 *cmdbuf_base;
int err = 0; int err = 0;
struct host1x_firewall fw;
fw.job = job; if (!fw->job->is_addr_reg)
fw.dev = dev;
fw.reloc = job->relocarray;
fw.num_relocs = job->num_relocs;
fw.cmdbuf_id = g->bo;
fw.offset = 0;
fw.class = 0;
if (!job->is_addr_reg)
return 0; return 0;
cmdbuf_base = host1x_bo_mmap(g->bo); cmdbuf_base = host1x_bo_mmap(g->bo);
if (!cmdbuf_base) if (!cmdbuf_base)
return -ENOMEM; return -ENOMEM;
fw->words = g->words;
fw->cmdbuf_id = g->bo;
fw->offset = 0;
fw.words = g->words; while (fw->words && !err) {
while (fw.words && !err) { u32 word = cmdbuf_base[fw->offset];
u32 word = cmdbuf_base[fw.offset];
u32 opcode = (word & 0xf0000000) >> 28; u32 opcode = (word & 0xf0000000) >> 28;
fw.mask = 0; fw->mask = 0;
fw.reg = 0; fw->reg = 0;
fw.count = 0; fw->count = 0;
fw.words--; fw->words--;
fw.offset++; fw->offset++;
switch (opcode) { switch (opcode) {
case 0: case 0:
fw.class = word >> 6 & 0x3ff; fw->class = word >> 6 & 0x3ff;
fw.mask = word & 0x3f; fw->mask = word & 0x3f;
fw.reg = word >> 16 & 0xfff; fw->reg = word >> 16 & 0xfff;
err = check_mask(&fw); err = check_mask(fw);
if (err) if (err)
goto out; goto out;
break; break;
case 1: case 1:
fw.reg = word >> 16 & 0xfff; fw->reg = word >> 16 & 0xfff;
fw.count = word & 0xffff; fw->count = word & 0xffff;
err = check_incr(&fw); err = check_incr(fw);
if (err) if (err)
goto out; goto out;
break; break;
case 2: case 2:
fw.reg = word >> 16 & 0xfff; fw->reg = word >> 16 & 0xfff;
fw.count = word & 0xffff; fw->count = word & 0xffff;
err = check_nonincr(&fw); err = check_nonincr(fw);
if (err) if (err)
goto out; goto out;
break; break;
case 3: case 3:
fw.mask = word & 0xffff; fw->mask = word & 0xffff;
fw.reg = word >> 16 & 0xfff; fw->reg = word >> 16 & 0xfff;
err = check_mask(&fw); err = check_mask(fw);
if (err) if (err)
goto out; goto out;
break; break;
...@@ -453,12 +444,10 @@ static int validate(struct host1x_job *job, struct device *dev, ...@@ -453,12 +444,10 @@ static int validate(struct host1x_job *job, struct device *dev,
} }
/* No relocs should remain at this point */ /* No relocs should remain at this point */
if (fw.num_relocs) if (fw->num_relocs)
err = -EINVAL; err = -EINVAL;
out: out:
host1x_bo_munmap(g->bo, cmdbuf_base);
return err; return err;
} }
...@@ -508,8 +497,15 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev) ...@@ -508,8 +497,15 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
int err; int err;
unsigned int i, j; unsigned int i, j;
struct host1x *host = dev_get_drvdata(dev->parent); struct host1x *host = dev_get_drvdata(dev->parent);
struct host1x_firewall fw;
DECLARE_BITMAP(waitchk_mask, host1x_syncpt_nb_pts(host)); DECLARE_BITMAP(waitchk_mask, host1x_syncpt_nb_pts(host));
fw.job = job;
fw.dev = dev;
fw.reloc = job->relocarray;
fw.num_relocs = job->num_relocs;
fw.class = 0;
bitmap_zero(waitchk_mask, host1x_syncpt_nb_pts(host)); bitmap_zero(waitchk_mask, host1x_syncpt_nb_pts(host));
for (i = 0; i < job->num_waitchk; i++) { for (i = 0; i < job->num_waitchk; i++) {
u32 syncpt_id = job->waitchk[i].syncpt_id; u32 syncpt_id = job->waitchk[i].syncpt_id;
...@@ -543,7 +539,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev) ...@@ -543,7 +539,7 @@ int host1x_job_pin(struct host1x_job *job, struct device *dev)
err = 0; err = 0;
if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL)) if (IS_ENABLED(CONFIG_TEGRA_HOST1X_FIREWALL))
err = validate(job, dev, g); err = validate(&fw, g);
if (err) if (err)
dev_err(dev, "Job invalid (err=%d)\n", err); dev_err(dev, "Job invalid (err=%d)\n", err);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment