arch-vega: Allow unaligned large host pages
The virtual and physical address for device memory are typically aligned to the page size. On the host (x86), however, the physical address may not be aligned to page size for large page sizes when mixed with 4kB pages. As a result, the physical address calculation must add, rather than bitwise-OR, the virtual page offset to the physical page number. The virtual page offset on the GPU continues to use the variable page bytes for masking and shifting. Change-Id: I6563a1eb43d9b59577d32268b8645a7436304bcb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/63034 Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Matt Sinclair <mattdsinclair@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com> Maintainer: Matt Sinclair <mattdsinclair@gmail.com>
This commit is contained in:
@@ -53,8 +53,7 @@ Walker::startFunctional(Addr base, Addr &addr, unsigned &logBytes,
|
||||
Addr vaddr = addr;
|
||||
Fault fault = startFunctional(base, vaddr, pte, logBytes, mode);
|
||||
isSystem = pte.s;
|
||||
addr = ((pte.ppn << PageShift) & ~mask(logBytes))
|
||||
| (vaddr & mask(logBytes));
|
||||
addr = ((pte.ppn << PageShift) + (vaddr & mask(logBytes)));
|
||||
|
||||
return fault;
|
||||
}
|
||||
@@ -182,8 +181,8 @@ Walker::WalkerState::startWalk()
|
||||
sendPackets();
|
||||
} else {
|
||||
// Set physical page address in entry
|
||||
entry.paddr = bits(entry.pte, 47, entry.logBytes);
|
||||
entry.paddr <<= entry.logBytes;
|
||||
entry.paddr = entry.pte.ppn << PageShift;
|
||||
entry.paddr += entry.vaddr & mask(entry.logBytes);
|
||||
|
||||
// Insert to TLB
|
||||
assert(walker);
|
||||
@@ -277,7 +276,6 @@ Walker::WalkerState::walkStateMachine(PageTableEntry &pte, Addr &nextRead,
|
||||
int fragment = pte.fragment;
|
||||
entry.logBytes = PageShift + std::min(9, fragment);
|
||||
entry.vaddr <<= PageShift;
|
||||
entry.vaddr = entry.vaddr & ~((1 << entry.logBytes) - 1);
|
||||
entry.vaddr = entry.vaddr & ~mask(entry.logBytes);
|
||||
doEndWalk = true;
|
||||
}
|
||||
|
||||
@@ -447,7 +447,7 @@ GpuTLB::walkerResponse(VegaTlbEntry& entry, PacketPtr pkt)
|
||||
VegaISA::PageBytes);
|
||||
|
||||
Addr page_addr = entry.pte.ppn << VegaISA::PageShift;
|
||||
Addr paddr = insertBits(page_addr, entry.logBytes - 1, 0, entry.vaddr);
|
||||
Addr paddr = page_addr + (entry.vaddr & mask(entry.logBytes));
|
||||
pkt->req->setPaddr(paddr);
|
||||
pkt->req->setSystemReq(entry.pte.s);
|
||||
|
||||
@@ -842,7 +842,7 @@ GpuTLB::CpuSidePort::recvFunctional(PacketPtr pkt)
|
||||
// page size. Fragment is still used via logBytes to select lower
|
||||
// bits from vaddr.
|
||||
Addr page_addr = pte.ppn << PageShift;
|
||||
Addr paddr = insertBits(page_addr, logBytes - 1, 0, vaddr);
|
||||
Addr paddr = page_addr + (vaddr & mask(logBytes));
|
||||
Addr alignedPaddr = tlb->pageAlign(paddr);
|
||||
pkt->req->setPaddr(paddr);
|
||||
pkt->req->setSystemReq(pte.s);
|
||||
|
||||
Reference in New Issue
Block a user