From 9ed39afe62222d52b9a58269889fc5ffc5a1b666 Mon Sep 17 00:00:00 2001 From: Matthew Poremba Date: Sat, 27 Aug 2022 16:50:44 -0700 Subject: [PATCH] dev-amdgpu: Place all user-mode translations in MMHUB The memory management hub ("mmhub") is an aperture that aliases the GPU device memory. MMHUB addresses functionally map to the same device address, with the exception that it is guaranteed not to overlap with host memory. This is useful in gem5 for APIs with Addr type as it prevents sending e.g., DMAs to the wrong place. Change-Id: Ia296809a8dc2c5fbdeba6d70cd53215f9ab36c93 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/63031 Maintainer: Matt Sinclair Reviewed-by: Matt Sinclair Tested-by: kokoro --- src/dev/amdgpu/amdgpu_vm.cc | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/dev/amdgpu/amdgpu_vm.cc b/src/dev/amdgpu/amdgpu_vm.cc index c0c920977e..7a30917b21 100644 --- a/src/dev/amdgpu/amdgpu_vm.cc +++ b/src/dev/amdgpu/amdgpu_vm.cc @@ -331,11 +331,11 @@ AMDGPUVM::UserTranslationGen::translate(Range &range) const DPRINTF(AMDGPUDevice, "User tl base %#lx start %#lx walker %p\n", base, start, walker); - bool dummy; + bool system_bit; unsigned logBytes; Addr paddr = range.vaddr; Fault fault = walker->startFunctional(base, paddr, logBytes, - BaseMMU::Mode::Read, dummy); + BaseMMU::Mode::Read, system_bit); if (fault != NoFault) { fatal("User translation fault"); } @@ -343,9 +343,17 @@ AMDGPUVM::UserTranslationGen::translate(Range &range) const // GPU page size is variable. Use logBytes to determine size. const Addr page_size = 1 << logBytes; Addr next = roundUp(range.vaddr, page_size); - if (next == range.vaddr) + if (next == range.vaddr) { // We don't know the size of the next page, use default. next += AMDGPU_USER_PAGE_SIZE; + } + + // If we are not in system/host memory, change the address to the MMHUB + // aperture. This is mapped to the same backing memory as device memory. + if (!system_bit) { + paddr += vm->getMMHUBBase(); + assert(vm->inMMHUB(paddr)); + } range.size = std::min(range.size, next - range.vaddr); range.paddr = paddr;