Commit 0062972b authored by Peikang Zhang's avatar Peikang Zhang Committed by Alex Deucher

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: default avatarPeikang Zhang <peikang.zhang@amd.com>
Reviewed-by: default avatarAric Cyr <Aric.Cyr@amd.com>
Acked-by: default avatarRodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Acked-by: default avatarHarry Wentland <harry.wentland@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 586ec5dc
...@@ -40,14 +40,18 @@ struct core_vmid { ...@@ -40,14 +40,18 @@ struct core_vmid {
static void add_ptb_to_table(struct core_vmid *core_vmid, unsigned int vmid, uint64_t ptb) 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; if (vmid < MAX_VMID) {
core_vmid->num_vmids_available--; 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) static void clear_entry_from_vmid_table(struct core_vmid *core_vmid, unsigned int vmid)
{ {
core_vmid->ptb_assigned_to_vmid[vmid] = 0; if (vmid < MAX_VMID) {
core_vmid->num_vmids_available++; core_vmid->ptb_assigned_to_vmid[vmid] = 0;
core_vmid->num_vmids_available++;
}
} }
static void evict_vmids(struct core_vmid *core_vmid) static void evict_vmids(struct core_vmid *core_vmid)
...@@ -57,7 +61,7 @@ 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 // At this point any positions with value 0 are unused vmids, evict them
for (i = 1; i < core_vmid->num_vmid; i++) { 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); clear_entry_from_vmid_table(core_vmid, i);
} }
} }
...@@ -91,7 +95,7 @@ static int get_next_available_vmid(struct core_vmid *core_vmid) ...@@ -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) 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); struct core_vmid *core_vmid = MOD_VMID_TO_CORE(mod_vmid);
unsigned int vmid = 0; int vmid = 0;
// Physical address gets vmid 0 // Physical address gets vmid 0
if (ptb == 0) if (ptb == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment