summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorArto Merilainen <amerilainen@nvidia.com>2013-05-29 14:26:03 +0400
committerThierry Reding <thierry.reding@gmail.com>2013-06-22 14:43:52 +0400
commit5060d8ec7cfc29dd399b4fe952ba96e7a88aa778 (patch)
tree8a8234fd8eb8798c72b5f3493237a9a2ec435b15 /drivers
parent64c173d3a2bb367c901f1f0a66c1d4e338d8cb2c (diff)
downloadlinux-5060d8ec7cfc29dd399b4fe952ba96e7a88aa778.tar.xz
gpu: host1x: Check reloc table before usage
The firewall assumed that the user space always delivers a relocation table when it is accessing address registers. If userspace did not deliver a relocation table and tried to access the address registers, the code performed bad memory accesses. This patch modifies the firewall to check correctly that the firewall table is available before accessing it. In addition, check_reloc() is converted to use boolean return value (true when the reloc is valid, false when invalid). Signed-off-by: Arto Merilainen <amerilainen@nvidia.com> Acked-By: Terje Bergstrom <tbergstrom@nvidia.com> Signed-off-by: Thierry Reding <thierry.reding@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/host1x/job.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c
index 2974ac8d70a7..83804fdf9c99 100644
--- a/drivers/gpu/host1x/job.c
+++ b/drivers/gpu/host1x/job.c
@@ -268,15 +268,15 @@ static unsigned int do_relocs(struct host1x_job *job, struct host1x_bo *cmdbuf)
return 0;
}
-static int check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf,
+static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf,
unsigned int offset)
{
offset *= sizeof(u32);
if (reloc->cmdbuf != cmdbuf || reloc->cmdbuf_offset != offset)
- return -EINVAL;
+ return false;
- return 0;
+ return true;
}
struct host1x_firewall {
@@ -307,10 +307,10 @@ static int check_mask(struct host1x_firewall *fw)
if (mask & 1) {
if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
- bool bad_reloc = check_reloc(fw->reloc,
- fw->cmdbuf_id,
- fw->offset);
- if (!fw->num_relocs || bad_reloc)
+ if (!fw->num_relocs)
+ return -EINVAL;
+ if (!check_reloc(fw->reloc, fw->cmdbuf_id,
+ fw->offset))
return -EINVAL;
fw->reloc++;
fw->num_relocs--;
@@ -335,9 +335,9 @@ static int check_incr(struct host1x_firewall *fw)
return -EINVAL;
if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
- bool bad_reloc = check_reloc(fw->reloc, fw->cmdbuf_id,
- fw->offset);
- if (!fw->num_relocs || bad_reloc)
+ if (!fw->num_relocs)
+ return -EINVAL;
+ if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset))
return -EINVAL;
fw->reloc++;
fw->num_relocs--;
@@ -361,9 +361,9 @@ static int check_nonincr(struct host1x_firewall *fw)
return -EINVAL;
if (is_addr_reg) {
- bool bad_reloc = check_reloc(fw->reloc, fw->cmdbuf_id,
- fw->offset);
- if (!fw->num_relocs || bad_reloc)
+ if (!fw->num_relocs)
+ return -EINVAL;
+ if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset))
return -EINVAL;
fw->reloc++;
fw->num_relocs--;