Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gpu: host1x: Check waits in the firewall

Check waits in the firewall in a way it is done for relocations.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
Reviewed-by: Erik Faye-Lund <kusmabite@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>

authored by

Dmitry Osipenko and committed by
Thierry Reding
a47ac10e a2b78b0d

+34 -2
+34 -2
drivers/gpu/host1x/job.c
··· 31 31 #include "job.h" 32 32 #include "syncpt.h" 33 33 34 + #define HOST1X_WAIT_SYNCPT_OFFSET 0x8 35 + 34 36 struct host1x_job *host1x_job_alloc(struct host1x_channel *ch, 35 37 u32 num_cmdbufs, u32 num_relocs, 36 38 u32 num_waitchks) ··· 339 337 return true; 340 338 } 341 339 340 + static bool check_wait(struct host1x_waitchk *wait, struct host1x_bo *cmdbuf, 341 + unsigned int offset) 342 + { 343 + offset *= sizeof(u32); 344 + 345 + if (wait->bo != cmdbuf || wait->offset != offset) 346 + return false; 347 + 348 + return true; 349 + } 350 + 342 351 struct host1x_firewall { 343 352 struct host1x_job *job; 344 353 struct device *dev; 345 354 346 355 unsigned int num_relocs; 347 356 struct host1x_reloc *reloc; 357 + 358 + unsigned int num_waitchks; 359 + struct host1x_waitchk *waitchk; 348 360 349 361 struct host1x_bo *cmdbuf; 350 362 unsigned int offset; ··· 384 368 385 369 fw->num_relocs--; 386 370 fw->reloc++; 371 + } 372 + 373 + if (offset == HOST1X_WAIT_SYNCPT_OFFSET) { 374 + if (fw->class != HOST1X_CLASS_HOST1X) 375 + return -EINVAL; 376 + 377 + if (!fw->num_waitchks) 378 + return -EINVAL; 379 + 380 + if (!check_wait(fw->waitchk, fw->cmdbuf, fw->offset)) 381 + return -EINVAL; 382 + 383 + fw->num_waitchks--; 384 + fw->waitchk++; 387 385 } 388 386 389 387 return 0; ··· 564 534 fw.dev = dev; 565 535 fw.reloc = job->relocarray; 566 536 fw.num_relocs = job->num_relocs; 537 + fw.waitchk = job->waitchk; 538 + fw.num_waitchks = job->num_waitchk; 567 539 fw.class = job->class; 568 540 569 541 for (i = 0; i < job->num_gathers; i++) { ··· 604 572 offset += g->words * sizeof(u32); 605 573 } 606 574 607 - /* No relocs should remain at this point */ 608 - if (fw.num_relocs) 575 + /* No relocs and waitchks should remain at this point */ 576 + if (fw.num_relocs || fw.num_waitchks) 609 577 return -EINVAL; 610 578 611 579 return 0;