| From 8fab24150cbb73b083b6175a66d12541a7045307 Mon Sep 17 00:00:00 2001 |
| From: Christian Gmeiner <christian.gmeiner@gmail.com> |
| Date: Tue, 19 May 2020 07:30:15 +0200 |
| Subject: [PATCH] drm/etnaviv: fix perfmon domain interation |
| |
| commit 40b697e256ccdb88aaff424b44b4d300eb8460e8 upstream. |
| |
| The GC860 has one GPU device which has a 2d and 3d core. In this case |
| we want to expose perfmon information for both cores. |
| |
| The driver has one array which contains all possible perfmon domains |
| with some meta data - doms_meta. Here we can see that for the GC860 |
| two elements of that array are relevant: |
| |
| doms_3d: is at index 0 in the doms_meta array with 8 perfmon domains |
| doms_2d: is at index 1 in the doms_meta array with 1 perfmon domain |
| |
| The userspace driver wants to get a list of all perfmon domains and |
| their perfmon signals. This is done by iterating over all domains and |
| their signals. If the userspace driver wants to access the domain with |
| id 8 the kernel driver fails and returns invalid data from doms_3d with |
| and invalid offset. |
| |
| This results in: |
| Unable to handle kernel paging request at virtual address 00000000 |
| |
| On such a device it is not possible to use the userspace driver at all. |
| |
| The fix for this off-by-one error is quite simple. |
| |
| Reported-by: Paul Cercueil <paul@crapouillou.net> |
| Tested-by: Paul Cercueil <paul@crapouillou.net> |
| Fixes: ed1dd899baa3 ("drm/etnaviv: rework perfmon query infrastructure") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com> |
| Signed-off-by: Lucas Stach <l.stach@pengutronix.de> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c |
| index 3ce77cbad4ae..b3464d2dc2b4 100644 |
| --- a/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c |
| +++ b/drivers/gpu/drm/etnaviv/etnaviv_perfmon.c |
| @@ -453,7 +453,7 @@ static const struct etnaviv_pm_domain *pm_domain(const struct etnaviv_gpu *gpu, |
| if (!(gpu->identity.features & meta->feature)) |
| continue; |
| |
| - if (meta->nr_domains < (index - offset)) { |
| + if (index - offset >= meta->nr_domains) { |
| offset += meta->nr_domains; |
| continue; |
| } |
| -- |
| 2.7.4 |
| |