Skip to content

Commit 78942ae

Browse files
committed
Merge branch 'etnaviv/next' of https://git.pengutronix.de/git/lst/linux into drm-next
- make etnaviv work on IOMMU enabled systems - fix mapping of command buffers on systems with more than 4GB RAM - close a DoS vector - fix spurious GPU resets Signed-off-by: Dave Airlie <[email protected]> From: Lucas Stach <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 236f0f4 + cdd1569 commit 78942ae

File tree

5 files changed

+42
-12
lines changed

5 files changed

+42
-12
lines changed

drivers/gpu/drm/etnaviv/etnaviv_drv.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ static int compare_str(struct device *dev, void *data)
589589
static int etnaviv_pdev_probe(struct platform_device *pdev)
590590
{
591591
struct device *dev = &pdev->dev;
592+
struct device_node *first_node = NULL;
592593
struct component_match *match = NULL;
593594

594595
if (!dev->platform_data) {
@@ -598,6 +599,9 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
598599
if (!of_device_is_available(core_node))
599600
continue;
600601

602+
if (!first_node)
603+
first_node = core_node;
604+
601605
drm_of_component_match_add(&pdev->dev, &match,
602606
compare_of, core_node);
603607
}
@@ -609,6 +613,32 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
609613
component_match_add(dev, &match, compare_str, names[i]);
610614
}
611615

616+
/*
617+
* PTA and MTLB can have 40 bit base addresses, but
618+
* unfortunately, an entry in the MTLB can only point to a
619+
* 32 bit base address of a STLB. Moreover, to initialize the
620+
* MMU we need a command buffer with a 32 bit address because
621+
* without an MMU there is only an indentity mapping between
622+
* the internal 32 bit addresses and the bus addresses.
623+
*
624+
* To make things easy, we set the dma_coherent_mask to 32
625+
* bit to make sure we are allocating the command buffers and
626+
* TLBs in the lower 4 GiB address space.
627+
*/
628+
if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)) ||
629+
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
630+
dev_dbg(&pdev->dev, "No suitable DMA available\n");
631+
return -ENODEV;
632+
}
633+
634+
/*
635+
* Apply the same DMA configuration to the virtual etnaviv
636+
* device as the GPU we found. This assumes that all Vivante
637+
* GPUs in the system share the same DMA constraints.
638+
*/
639+
if (first_node)
640+
of_dma_configure(&pdev->dev, first_node, true);
641+
612642
return component_master_add_with_match(dev, &etnaviv_master_ops, match);
613643
}
614644

@@ -653,21 +683,12 @@ static int __init etnaviv_init(void)
653683
if (!of_device_is_available(np))
654684
continue;
655685

656-
pdev = platform_device_alloc("etnaviv", -1);
686+
pdev = platform_device_alloc("etnaviv", PLATFORM_DEVID_NONE);
657687
if (!pdev) {
658688
ret = -ENOMEM;
659689
of_node_put(np);
660690
goto unregister_platform_driver;
661691
}
662-
pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
663-
pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
664-
665-
/*
666-
* Apply the same DMA configuration to the virtual etnaviv
667-
* device as the GPU we found. This assumes that all Vivante
668-
* GPUs in the system share the same DMA constraints.
669-
*/
670-
of_dma_configure(&pdev->dev, np, true);
671692

672693
ret = platform_device_add(pdev);
673694
if (ret) {

drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,12 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data,
469469
return -EINVAL;
470470
}
471471

472+
if (args->stream_size > SZ_64K || args->nr_relocs > SZ_64K ||
473+
args->nr_bos > SZ_64K || args->nr_pmrs > 128) {
474+
DRM_ERROR("submit arguments out of size limits\n");
475+
return -EINVAL;
476+
}
477+
472478
/*
473479
* Copy the command submission and bo array to kernel space in
474480
* one go, and do this outside of any locks.

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1658,7 +1658,7 @@ etnaviv_gpu_cooling_set_cur_state(struct thermal_cooling_device *cdev,
16581658
return 0;
16591659
}
16601660

1661-
static struct thermal_cooling_device_ops cooling_ops = {
1661+
static const struct thermal_cooling_device_ops cooling_ops = {
16621662
.get_max_state = etnaviv_gpu_cooling_get_max_state,
16631663
.get_cur_state = etnaviv_gpu_cooling_get_cur_state,
16641664
.set_cur_state = etnaviv_gpu_cooling_set_cur_state,

drivers/gpu/drm/etnaviv/etnaviv_gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ struct etnaviv_gpu {
130130

131131
/* hang detection */
132132
u32 hangcheck_dma_addr;
133+
u32 hangcheck_fence;
133134

134135
void __iomem *mmio;
135136
int irq;

drivers/gpu/drm/etnaviv/etnaviv_sched.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,10 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
107107
*/
108108
dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS);
109109
change = dma_addr - gpu->hangcheck_dma_addr;
110-
if (change < 0 || change > 16) {
110+
if (gpu->completed_fence != gpu->hangcheck_fence ||
111+
change < 0 || change > 16) {
111112
gpu->hangcheck_dma_addr = dma_addr;
113+
gpu->hangcheck_fence = gpu->completed_fence;
112114
goto out_no_timeout;
113115
}
114116

0 commit comments

Comments
 (0)