riscv: fix error on memory op address overflow
Previously, if a memory operation referenced an address that caused the data to wrap around to the beginning of the memory (such as -1 or 0xFFFFFFFFFFFFFFFF), an assert would fail during address translation and gem5 would crash. This patch fixes that by checking for such a case in RISC-V's TLB code and returning a fault from translateData if that would happen. Because RISC-V does support unaligned memory accesses, no checking is performed to make sure that an access doesn't cross a cache line. [Update creation of page table fault to use make_shared.] [Add comment explaining the change and assertion that the memory request isn't zero size.] Change-Id: I7b8ef9a5838f30184dbdbd0c7c1655e1c04a9410 Reviewed-on: https://gem5-review.googlesource.com/2345 Maintainer: Alec Roelke <ar4jc@virginia.edu> Reviewed-by: Brandon Potter <Brandon.Potter@amd.com> Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
This commit is contained in:
@@ -303,6 +303,17 @@ TLB::translateData(RequestPtr req, ThreadContext *tc, bool write)
|
||||
if (FullSystem)
|
||||
panic("translateData not implemented in RISC-V.\n");
|
||||
|
||||
// In the O3 CPU model, sometimes a memory access will be speculatively
|
||||
// executed along a branch that will end up not being taken where the
|
||||
// address is invalid. In that case, return a fault rather than trying
|
||||
// to translate it (which will cause a panic). Since RISC-V allows
|
||||
// unaligned memory accesses, this should only happen if the request's
|
||||
// length is long enough to wrap around from the end of the memory to the
|
||||
// start.
|
||||
assert(req->getSize() > 0);
|
||||
if (req->getVaddr() + req->getSize() - 1 < req->getVaddr())
|
||||
return make_shared<GenericPageTableFault>(req->getVaddr());
|
||||
|
||||
Process * p = tc->getProcessPtr();
|
||||
|
||||
Fault fault = p->pTable->translate(req);
|
||||
|
||||
Reference in New Issue
Block a user