gpu: host1x: firewall: Refactor register check
The same code sequence is used in various places to validate a register access in the command stream. This can be refactored into a separate function. Signed-off-by: Thierry Reding <treding@nvidia.com>
This commit is contained in:
parent
d7fbcf477a
commit
d77563ff56
1 changed files with 31 additions and 26 deletions
|
@ -291,25 +291,37 @@ struct host1x_firewall {
|
||||||
u32 count;
|
u32 count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int check_register(struct host1x_firewall *fw, unsigned long offset)
|
||||||
|
{
|
||||||
|
if (fw->job->is_addr_reg(fw->dev, fw->class, offset)) {
|
||||||
|
if (!fw->num_relocs)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!check_reloc(fw->reloc, fw->cmdbuf, fw->offset))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fw->num_relocs--;
|
||||||
|
fw->reloc++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int check_mask(struct host1x_firewall *fw)
|
static int check_mask(struct host1x_firewall *fw)
|
||||||
{
|
{
|
||||||
u32 mask = fw->mask;
|
u32 mask = fw->mask;
|
||||||
u32 reg = fw->reg;
|
u32 reg = fw->reg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (mask) {
|
while (mask) {
|
||||||
if (fw->words == 0)
|
if (fw->words == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (mask & 1) {
|
if (mask & 1) {
|
||||||
if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
|
ret = check_register(fw, reg);
|
||||||
if (!fw->num_relocs)
|
if (ret < 0)
|
||||||
return -EINVAL;
|
return ret;
|
||||||
if (!check_reloc(fw->reloc, fw->cmdbuf,
|
|
||||||
fw->offset))
|
|
||||||
return -EINVAL;
|
|
||||||
fw->reloc++;
|
|
||||||
fw->num_relocs--;
|
|
||||||
}
|
|
||||||
fw->words--;
|
fw->words--;
|
||||||
fw->offset++;
|
fw->offset++;
|
||||||
}
|
}
|
||||||
|
@ -324,19 +336,16 @@ static int check_incr(struct host1x_firewall *fw)
|
||||||
{
|
{
|
||||||
u32 count = fw->count;
|
u32 count = fw->count;
|
||||||
u32 reg = fw->reg;
|
u32 reg = fw->reg;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
if (fw->words == 0)
|
if (fw->words == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) {
|
ret = check_register(fw, reg);
|
||||||
if (!fw->num_relocs)
|
if (ret < 0)
|
||||||
return -EINVAL;
|
return ret;
|
||||||
if (!check_reloc(fw->reloc, fw->cmdbuf, fw->offset))
|
|
||||||
return -EINVAL;
|
|
||||||
fw->reloc++;
|
|
||||||
fw->num_relocs--;
|
|
||||||
}
|
|
||||||
reg++;
|
reg++;
|
||||||
fw->words--;
|
fw->words--;
|
||||||
fw->offset++;
|
fw->offset++;
|
||||||
|
@ -348,21 +357,17 @@ static int check_incr(struct host1x_firewall *fw)
|
||||||
|
|
||||||
static int check_nonincr(struct host1x_firewall *fw)
|
static int check_nonincr(struct host1x_firewall *fw)
|
||||||
{
|
{
|
||||||
int is_addr_reg = fw->job->is_addr_reg(fw->dev, fw->class, fw->reg);
|
|
||||||
u32 count = fw->count;
|
u32 count = fw->count;
|
||||||
|
int ret;
|
||||||
|
|
||||||
while (count) {
|
while (count) {
|
||||||
if (fw->words == 0)
|
if (fw->words == 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (is_addr_reg) {
|
ret = check_register(fw, fw->reg);
|
||||||
if (!fw->num_relocs)
|
if (ret < 0)
|
||||||
return -EINVAL;
|
return ret;
|
||||||
if (!check_reloc(fw->reloc, fw->cmdbuf, fw->offset))
|
|
||||||
return -EINVAL;
|
|
||||||
fw->reloc++;
|
|
||||||
fw->num_relocs--;
|
|
||||||
}
|
|
||||||
fw->words--;
|
fw->words--;
|
||||||
fw->offset++;
|
fw->offset++;
|
||||||
count--;
|
count--;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue