diff options
Diffstat (limited to 'drivers/gpu/host1x/job.c')
-rw-r--r-- | drivers/gpu/host1x/job.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/drivers/gpu/host1x/job.c b/drivers/gpu/host1x/job.c index c4e1050f2252..de5ec333ce1a 100644 --- a/drivers/gpu/host1x/job.c +++ b/drivers/gpu/host1x/job.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/host1x.h> | ||
21 | #include <linux/kref.h> | 22 | #include <linux/kref.h> |
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | #include <linux/scatterlist.h> | 24 | #include <linux/scatterlist.h> |
@@ -27,7 +28,6 @@ | |||
27 | 28 | ||
28 | #include "channel.h" | 29 | #include "channel.h" |
29 | #include "dev.h" | 30 | #include "dev.h" |
30 | #include "host1x_bo.h" | ||
31 | #include "job.h" | 31 | #include "job.h" |
32 | #include "syncpt.h" | 32 | #include "syncpt.h" |
33 | 33 | ||
@@ -264,7 +264,7 @@ static unsigned int do_relocs(struct host1x_job *job, struct host1x_bo *cmdbuf) | |||
264 | } | 264 | } |
265 | 265 | ||
266 | static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf, | 266 | static bool check_reloc(struct host1x_reloc *reloc, struct host1x_bo *cmdbuf, |
267 | unsigned int offset) | 267 | unsigned int offset) |
268 | { | 268 | { |
269 | offset *= sizeof(u32); | 269 | offset *= sizeof(u32); |
270 | 270 | ||
@@ -281,7 +281,7 @@ struct host1x_firewall { | |||
281 | unsigned int num_relocs; | 281 | unsigned int num_relocs; |
282 | struct host1x_reloc *reloc; | 282 | struct host1x_reloc *reloc; |
283 | 283 | ||
284 | struct host1x_bo *cmdbuf_id; | 284 | struct host1x_bo *cmdbuf; |
285 | unsigned int offset; | 285 | unsigned int offset; |
286 | 286 | ||
287 | u32 words; | 287 | u32 words; |
@@ -291,25 +291,37 @@ struct host1x_firewall { | |||
291 | u32 count; | 291 | u32 count; |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static int check_register(struct host1x_firewall *fw, unsigned long offset) | ||
295 | { | ||
296 | if (fw->job->is_addr_reg(fw->dev, fw->class, offset)) { | ||
297 | if (!fw->num_relocs) | ||
298 | return -EINVAL; | ||
299 | |||
300 | if (!check_reloc(fw->reloc, fw->cmdbuf, fw->offset)) | ||
301 | return -EINVAL; | ||
302 | |||
303 | fw->num_relocs--; | ||
304 | fw->reloc++; | ||
305 | } | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
294 | static int check_mask(struct host1x_firewall *fw) | 310 | static int check_mask(struct host1x_firewall *fw) |
295 | { | 311 | { |
296 | u32 mask = fw->mask; | 312 | u32 mask = fw->mask; |
297 | u32 reg = fw->reg; | 313 | u32 reg = fw->reg; |
314 | int ret; | ||
298 | 315 | ||
299 | while (mask) { | 316 | while (mask) { |
300 | if (fw->words == 0) | 317 | if (fw->words == 0) |
301 | return -EINVAL; | 318 | return -EINVAL; |
302 | 319 | ||
303 | if (mask & 1) { | 320 | if (mask & 1) { |
304 | if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) { | 321 | ret = check_register(fw, reg); |
305 | if (!fw->num_relocs) | 322 | if (ret < 0) |
306 | return -EINVAL; | 323 | return ret; |
307 | if (!check_reloc(fw->reloc, fw->cmdbuf_id, | 324 | |
308 | fw->offset)) | ||
309 | return -EINVAL; | ||
310 | fw->reloc++; | ||
311 | fw->num_relocs--; | ||
312 | } | ||
313 | fw->words--; | 325 | fw->words--; |
314 | fw->offset++; | 326 | fw->offset++; |
315 | } | 327 | } |
@@ -324,19 +336,16 @@ static int check_incr(struct host1x_firewall *fw) | |||
324 | { | 336 | { |
325 | u32 count = fw->count; | 337 | u32 count = fw->count; |
326 | u32 reg = fw->reg; | 338 | u32 reg = fw->reg; |
339 | int ret; | ||
327 | 340 | ||
328 | while (count) { | 341 | while (count) { |
329 | if (fw->words == 0) | 342 | if (fw->words == 0) |
330 | return -EINVAL; | 343 | return -EINVAL; |
331 | 344 | ||
332 | if (fw->job->is_addr_reg(fw->dev, fw->class, reg)) { | 345 | ret = check_register(fw, reg); |
333 | if (!fw->num_relocs) | 346 | if (ret < 0) |
334 | return -EINVAL; | 347 | return ret; |
335 | if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset)) | 348 | |
336 | return -EINVAL; | ||
337 | fw->reloc++; | ||
338 | fw->num_relocs--; | ||
339 | } | ||
340 | reg++; | 349 | reg++; |
341 | fw->words--; | 350 | fw->words--; |
342 | fw->offset++; | 351 | fw->offset++; |
@@ -348,21 +357,17 @@ static int check_incr(struct host1x_firewall *fw) | |||
348 | 357 | ||
349 | static int check_nonincr(struct host1x_firewall *fw) | 358 | static int check_nonincr(struct host1x_firewall *fw) |
350 | { | 359 | { |
351 | int is_addr_reg = fw->job->is_addr_reg(fw->dev, fw->class, fw->reg); | ||
352 | u32 count = fw->count; | 360 | u32 count = fw->count; |
361 | int ret; | ||
353 | 362 | ||
354 | while (count) { | 363 | while (count) { |
355 | if (fw->words == 0) | 364 | if (fw->words == 0) |
356 | return -EINVAL; | 365 | return -EINVAL; |
357 | 366 | ||
358 | if (is_addr_reg) { | 367 | ret = check_register(fw, fw->reg); |
359 | if (!fw->num_relocs) | 368 | if (ret < 0) |
360 | return -EINVAL; | 369 | return ret; |
361 | if (!check_reloc(fw->reloc, fw->cmdbuf_id, fw->offset)) | 370 | |
362 | return -EINVAL; | ||
363 | fw->reloc++; | ||
364 | fw->num_relocs--; | ||
365 | } | ||
366 | fw->words--; | 371 | fw->words--; |
367 | fw->offset++; | 372 | fw->offset++; |
368 | count--; | 373 | count--; |
@@ -381,7 +386,7 @@ static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g) | |||
381 | return 0; | 386 | return 0; |
382 | 387 | ||
383 | fw->words = g->words; | 388 | fw->words = g->words; |
384 | fw->cmdbuf_id = g->bo; | 389 | fw->cmdbuf = g->bo; |
385 | fw->offset = 0; | 390 | fw->offset = 0; |
386 | 391 | ||
387 | while (fw->words && !err) { | 392 | while (fw->words && !err) { |
@@ -436,10 +441,6 @@ static int validate(struct host1x_firewall *fw, struct host1x_job_gather *g) | |||
436 | } | 441 | } |
437 | } | 442 | } |
438 | 443 | ||
439 | /* No relocs should remain at this point */ | ||
440 | if (fw->num_relocs) | ||
441 | err = -EINVAL; | ||
442 | |||
443 | out: | 444 | out: |
444 | return err; | 445 | return err; |
445 | } | 446 | } |
@@ -493,6 +494,10 @@ static inline int copy_gathers(struct host1x_job *job, struct device *dev) | |||
493 | offset += g->words * sizeof(u32); | 494 | offset += g->words * sizeof(u32); |
494 | } | 495 | } |
495 | 496 | ||
497 | /* No relocs should remain at this point */ | ||
498 | if (fw.num_relocs) | ||
499 | return -EINVAL; | ||
500 | |||
496 | return 0; | 501 | return 0; |
497 | } | 502 | } |
498 | 503 | ||