aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
index 352b30409060..0877ff9a9594 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
@@ -181,7 +181,7 @@ static unsigned amdgpu_vm_num_entries(struct amdgpu_device *adev,
181 181
182 if (level == adev->vm_manager.root_level) 182 if (level == adev->vm_manager.root_level)
183 /* For the root directory */ 183 /* For the root directory */
184 return round_up(adev->vm_manager.max_pfn, 1 << shift) >> shift; 184 return round_up(adev->vm_manager.max_pfn, 1ULL << shift) >> shift;
185 else if (level != AMDGPU_VM_PTB) 185 else if (level != AMDGPU_VM_PTB)
186 /* Everything in between */ 186 /* Everything in between */
187 return 512; 187 return 512;
@@ -1632,13 +1632,6 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1632 continue; 1632 continue;
1633 } 1633 }
1634 1634
1635 /* First check if the entry is already handled */
1636 if (cursor.pfn < frag_start) {
1637 cursor.entry->huge = true;
1638 amdgpu_vm_pt_next(adev, &cursor);
1639 continue;
1640 }
1641
1642 /* If it isn't already handled it can't be a huge page */ 1635 /* If it isn't already handled it can't be a huge page */
1643 if (cursor.entry->huge) { 1636 if (cursor.entry->huge) {
1644 /* Add the entry to the relocated list to update it. */ 1637 /* Add the entry to the relocated list to update it. */
@@ -1663,9 +1656,11 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1663 if (!amdgpu_vm_pt_descendant(adev, &cursor)) 1656 if (!amdgpu_vm_pt_descendant(adev, &cursor))
1664 return -ENOENT; 1657 return -ENOENT;
1665 continue; 1658 continue;
1666 } else if (frag >= parent_shift) { 1659 } else if (frag >= parent_shift &&
1660 cursor.level - 1 != adev->vm_manager.root_level) {
1667 /* If the fragment size is even larger than the parent 1661 /* If the fragment size is even larger than the parent
1668 * shift we should go up one level and check it again. 1662 * shift we should go up one level and check it again
1663 * unless one level up is the root level.
1669 */ 1664 */
1670 if (!amdgpu_vm_pt_ancestor(&cursor)) 1665 if (!amdgpu_vm_pt_ancestor(&cursor))
1671 return -ENOENT; 1666 return -ENOENT;
@@ -1673,10 +1668,10 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1673 } 1668 }
1674 1669
1675 /* Looks good so far, calculate parameters for the update */ 1670 /* Looks good so far, calculate parameters for the update */
1676 incr = AMDGPU_GPU_PAGE_SIZE << shift; 1671 incr = (uint64_t)AMDGPU_GPU_PAGE_SIZE << shift;
1677 mask = amdgpu_vm_entries_mask(adev, cursor.level); 1672 mask = amdgpu_vm_entries_mask(adev, cursor.level);
1678 pe_start = ((cursor.pfn >> shift) & mask) * 8; 1673 pe_start = ((cursor.pfn >> shift) & mask) * 8;
1679 entry_end = (mask + 1) << shift; 1674 entry_end = (uint64_t)(mask + 1) << shift;
1680 entry_end += cursor.pfn & ~(entry_end - 1); 1675 entry_end += cursor.pfn & ~(entry_end - 1);
1681 entry_end = min(entry_end, end); 1676 entry_end = min(entry_end, end);
1682 1677
@@ -1689,7 +1684,7 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1689 flags | AMDGPU_PTE_FRAG(frag)); 1684 flags | AMDGPU_PTE_FRAG(frag));
1690 1685
1691 pe_start += nptes * 8; 1686 pe_start += nptes * 8;
1692 dst += nptes * AMDGPU_GPU_PAGE_SIZE << shift; 1687 dst += (uint64_t)nptes * AMDGPU_GPU_PAGE_SIZE << shift;
1693 1688
1694 frag_start = upd_end; 1689 frag_start = upd_end;
1695 if (frag_start >= frag_end) { 1690 if (frag_start >= frag_end) {
@@ -1701,8 +1696,17 @@ static int amdgpu_vm_update_ptes(struct amdgpu_pte_update_params *params,
1701 } 1696 }
1702 } while (frag_start < entry_end); 1697 } while (frag_start < entry_end);
1703 1698
1704 if (frag >= shift) 1699 if (amdgpu_vm_pt_descendant(adev, &cursor)) {
1700 /* Mark all child entries as huge */
1701 while (cursor.pfn < frag_start) {
1702 cursor.entry->huge = true;
1703 amdgpu_vm_pt_next(adev, &cursor);
1704 }
1705
1706 } else if (frag >= shift) {
1707 /* or just move on to the next on the same level. */
1705 amdgpu_vm_pt_next(adev, &cursor); 1708 amdgpu_vm_pt_next(adev, &cursor);
1709 }
1706 } 1710 }
1707 1711
1708 return 0; 1712 return 0;