diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c')
| -rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c | 32 |
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; |
