From: Peikang Zhang <peikang.zh...@amd.com>

[ Upstream commit 0062972b9d9f888d0273c6496769d02e8f509135 ]

[Why]
Unused VMIDs were not evicted correctly

[How]
1. evict_vmids() logic was fixed;
2. Added boundary check for add_ptb_to_table() and
   clear_entry_from_vmid_table() to avoid crash caused by array out of
   boundary;
3. For mod_vmid_get_for_ptb(), vimd is changed from unsigned to signed
   due to vimd is signed.

Signed-off-by: Peikang Zhang <peikang.zh...@amd.com>
Reviewed-by: Aric Cyr <aric....@amd.com>
Acked-by: Rodrigo Siqueira <rodrigo.sique...@amd.com>
Acked-by: Harry Wentland <harry.wentl...@amd.com>
Signed-off-by: Alex Deucher <alexander.deuc...@amd.com>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/gpu/drm/amd/display/modules/vmid/vmid.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c 
b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
index f0a153704f6e0..00f132f8ad55d 100644
--- a/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
+++ b/drivers/gpu/drm/amd/display/modules/vmid/vmid.c
@@ -40,14 +40,18 @@ struct core_vmid {
 
 static void add_ptb_to_table(struct core_vmid *core_vmid, unsigned int vmid, 
uint64_t ptb)
 {
-       core_vmid->ptb_assigned_to_vmid[vmid] = ptb;
-       core_vmid->num_vmids_available--;
+       if (vmid < MAX_VMID) {
+               core_vmid->ptb_assigned_to_vmid[vmid] = ptb;
+               core_vmid->num_vmids_available--;
+       }
 }
 
 static void clear_entry_from_vmid_table(struct core_vmid *core_vmid, unsigned 
int vmid)
 {
-       core_vmid->ptb_assigned_to_vmid[vmid] = 0;
-       core_vmid->num_vmids_available++;
+       if (vmid < MAX_VMID) {
+               core_vmid->ptb_assigned_to_vmid[vmid] = 0;
+               core_vmid->num_vmids_available++;
+       }
 }
 
 static void evict_vmids(struct core_vmid *core_vmid)
@@ -57,7 +61,7 @@ static void evict_vmids(struct core_vmid *core_vmid)
 
        // At this point any positions with value 0 are unused vmids, evict them
        for (i = 1; i < core_vmid->num_vmid; i++) {
-               if (ord & (1u << i))
+               if (!(ord & (1u << i)))
                        clear_entry_from_vmid_table(core_vmid, i);
        }
 }
@@ -91,7 +95,7 @@ static int get_next_available_vmid(struct core_vmid 
*core_vmid)
 uint8_t mod_vmid_get_for_ptb(struct mod_vmid *mod_vmid, uint64_t ptb)
 {
        struct core_vmid *core_vmid = MOD_VMID_TO_CORE(mod_vmid);
-       unsigned int vmid = 0;
+       int vmid = 0;
 
        // Physical address gets vmid 0
        if (ptb == 0)
-- 
2.20.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to