diff options
author | Peikang Zhang <peikang.zhang@amd.com> | 2020-02-07 16:53:28 -0500 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2020-02-25 11:03:54 -0500 |
commit | 0062972b9d9f888d0273c6496769d02e8f509135 (patch) | |
tree | ba1e6accd537dbca70ed54ad1387b12cffd057ee | |
parent | 586ec5dc5c8ea28f46b9e27415dfd0f4de01849e (diff) | |
download | linux-0062972b9d9f888d0273c6496769d02e8f509135.tar.bz2 |
drm/amd/display: System crashes when add_ptb_to_table() gets called
[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.zhang@amd.com>
Reviewed-by: Aric Cyr <Aric.Cyr@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: Harry Wentland <harry.wentland@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/display/modules/vmid/vmid.c | 16 |
1 files 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 f0a153704f6e..00f132f8ad55 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) |