From 22e27e1d618d5e7cfa8673c1cdf5c0c2bd8f802c Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Wed, 21 Oct 2020 04:32:39 -0700 Subject: [PATCH] mem,sim: Get the page size from the page table in SE mode. The page table already knows the size of a page without having to directly use any ISA specific constants. Change-Id: I68b575e194697065620a2097d972076886766f74 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/34172 Tested-by: kokoro Reviewed-by: Bobby R. Bruce Maintainer: Gabe Black --- src/mem/multi_level_page_table.hh | 22 +++++++++++----------- src/mem/page_table.cc | 20 ++++++++++---------- src/mem/page_table.hh | 9 ++++++--- src/sim/mem_state.cc | 2 +- src/sim/process.cc | 13 ++++++------- src/sim/syscall_emul.cc | 7 +++---- src/sim/syscall_emul.hh | 7 ++++--- 7 files changed, 41 insertions(+), 39 deletions(-) diff --git a/src/mem/multi_level_page_table.hh b/src/mem/multi_level_page_table.hh index 68a32b160..3d9ca9b58 100644 --- a/src/mem/multi_level_page_table.hh +++ b/src/mem/multi_level_page_table.hh @@ -192,8 +192,8 @@ class MultiLevelPageTable : public EmulationPageTable public: MultiLevelPageTable(const std::string &__name, uint64_t _pid, - System *_sys, Addr pageSize) : - EmulationPageTable(__name, _pid, pageSize), system(_sys) + System *_sys, Addr _pageSize) : + EmulationPageTable(__name, _pid, _pageSize), system(_sys) {} ~MultiLevelPageTable() {} @@ -204,7 +204,7 @@ public: if (shared) return; - _basePtr = prepTopTable(system, pageSize); + _basePtr = prepTopTable(system, _pageSize); } Addr basePtr() { return _basePtr; } @@ -216,8 +216,8 @@ public: Final entry; - for (int64_t offset = 0; offset < size; offset += pageSize) { - walk(system, pageSize, _basePtr, + for (int64_t offset = 0; offset < size; offset += _pageSize) { + walk(system, _pageSize, _basePtr, vaddr + offset, true, &entry); entry.reset(paddr + offset, true, flags & Uncacheable, @@ -236,16 +236,16 @@ public: Final old_entry, new_entry; - for (int64_t offset = 0; offset < size; offset += pageSize) { + for (int64_t offset = 0; offset < size; offset += _pageSize) { // Unmap the original mapping. - walk(system, pageSize, _basePtr, vaddr + offset, + walk(system, _pageSize, _basePtr, vaddr + offset, false, &old_entry); old_entry.present(false); old_entry.write(system->physProxy); // Map the new one. - walk(system, pageSize, _basePtr, new_vaddr + offset, - true, &new_entry); + walk(system, _pageSize, _basePtr, + new_vaddr + offset, true, &new_entry); new_entry.reset(old_entry.paddr(), true, old_entry.uncacheable(), old_entry.readonly()); new_entry.write(system->physProxy); @@ -259,8 +259,8 @@ public: Final entry; - for (int64_t offset = 0; offset < size; offset += pageSize) { - walk(system, pageSize, _basePtr, + for (int64_t offset = 0; offset < size; offset += _pageSize) { + walk(system, _pageSize, _basePtr, vaddr + offset, false, &entry); fatal_if(!entry.present(), "PageTable::unmap: Address %#x not mapped.", vaddr); diff --git a/src/mem/page_table.cc b/src/mem/page_table.cc index 5318f3558..d088d296b 100644 --- a/src/mem/page_table.cc +++ b/src/mem/page_table.cc @@ -62,9 +62,9 @@ EmulationPageTable::map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags) pTable.emplace(vaddr, Entry(paddr, flags)); } - size -= pageSize; - vaddr += pageSize; - paddr += pageSize; + size -= _pageSize; + vaddr += _pageSize; + paddr += _pageSize; } } @@ -84,9 +84,9 @@ EmulationPageTable::remap(Addr vaddr, int64_t size, Addr new_vaddr) pTable.emplace(new_vaddr, old_it->second); pTable.erase(old_it); - size -= pageSize; - vaddr += pageSize; - new_vaddr += pageSize; + size -= _pageSize; + vaddr += _pageSize; + new_vaddr += _pageSize; } } @@ -108,8 +108,8 @@ EmulationPageTable::unmap(Addr vaddr, int64_t size) auto it = pTable.find(vaddr); assert(it != pTable.end()); pTable.erase(it); - size -= pageSize; - vaddr += pageSize; + size -= _pageSize; + vaddr += _pageSize; } } @@ -119,7 +119,7 @@ EmulationPageTable::isUnmapped(Addr vaddr, int64_t size) // starting address must be page aligned assert(pageOffset(vaddr) == 0); - for (int64_t offset = 0; offset < size; offset += pageSize) + for (int64_t offset = 0; offset < size; offset += _pageSize) if (pTable.find(vaddr + offset) != pTable.end()) return false; @@ -158,7 +158,7 @@ EmulationPageTable::translate(const RequestPtr &req) if (!translate(req->getVaddr(), paddr)) return Fault(new GenericPageTableFault(req->getVaddr())); req->setPaddr(paddr); - if ((paddr & (pageSize - 1)) + req->getSize() > pageSize) { + if ((paddr & (_pageSize - 1)) + req->getSize() > _pageSize) { panic("Request spans page boundaries!\n"); return NoFault; } diff --git a/src/mem/page_table.hh b/src/mem/page_table.hh index 18ee18ac5..65725f349 100644 --- a/src/mem/page_table.hh +++ b/src/mem/page_table.hh @@ -63,7 +63,7 @@ class EmulationPageTable : public Serializable typedef PTable::iterator PTableItr; PTable pTable; - const Addr pageSize; + const Addr _pageSize; const Addr offsetMask; const uint64_t _pid; @@ -73,10 +73,10 @@ class EmulationPageTable : public Serializable EmulationPageTable( const std::string &__name, uint64_t _pid, Addr _pageSize) : - pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), + _pageSize(_pageSize), offsetMask(mask(floorLog2(_pageSize))), _pid(_pid), _name(__name), shared(false) { - assert(isPowerOf2(pageSize)); + assert(isPowerOf2(_pageSize)); } uint64_t pid() const { return _pid; }; @@ -105,6 +105,9 @@ class EmulationPageTable : public Serializable Addr pageAlign(Addr a) { return (a & ~offsetMask); } Addr pageOffset(Addr a) { return (a & offsetMask); } + // Page size can technically vary based on the virtual address, but we'll + // ignore that for now. + Addr pageSize() { return _pageSize; } /** * Maps a virtual memory region to a physical memory region. diff --git a/src/sim/mem_state.cc b/src/sim/mem_state.cc index 7adee590a..6d64f125a 100644 --- a/src/sim/mem_state.cc +++ b/src/sim/mem_state.cc @@ -42,7 +42,7 @@ MemState::MemState(Process *owner, Addr brk_point, Addr stack_base, Addr max_stack_size, Addr next_thread_stack_base, Addr mmap_end) : _ownerProcess(owner), - _pageBytes(owner->system->getPageBytes()), _brkPoint(brk_point), + _pageBytes(owner->pTable->pageSize()), _brkPoint(brk_point), _stackBase(stack_base), _stackSize(max_stack_size), _maxStackSize(max_stack_size), _stackMin(stack_base - max_stack_size), _nextThreadStackBase(next_thread_stack_base), diff --git a/src/sim/process.cc b/src/sim/process.cc index 3968adbd3..315f86b7e 100644 --- a/src/sim/process.cc +++ b/src/sim/process.cc @@ -319,7 +319,7 @@ Process::drain() void Process::allocateMem(Addr vaddr, int64_t size, bool clobber) { - int npages = divCeil(size, (int64_t)system->getPageBytes()); + int npages = divCeil(size, pTable->pageSize()); Addr paddr = system->allocPhysPages(npages); pTable->map(vaddr, paddr, size, clobber ? EmulationPageTable::Clobber : @@ -334,15 +334,14 @@ Process::replicatePage(Addr vaddr, Addr new_paddr, ThreadContext *old_tc, new_paddr = system->allocPhysPages(1); // Read from old physical page. - uint8_t *buf_p = new uint8_t[system->getPageBytes()]; - old_tc->getVirtProxy().readBlob(vaddr, buf_p, system->getPageBytes()); + uint8_t buf_p[pTable->pageSize()]; + old_tc->getVirtProxy().readBlob(vaddr, buf_p, sizeof(buf_p)); // Create new mapping in process address space by clobbering existing // mapping (if any existed) and then write to the new physical page. bool clobber = true; - pTable->map(vaddr, new_paddr, system->getPageBytes(), clobber); - new_tc->getVirtProxy().writeBlob(vaddr, buf_p, system->getPageBytes()); - delete[] buf_p; + pTable->map(vaddr, new_paddr, sizeof(buf_p), clobber); + new_tc->getVirtProxy().writeBlob(vaddr, buf_p, sizeof(buf_p)); } bool @@ -443,7 +442,7 @@ Process::updateBias() // Determine how large the interpreters footprint will be in the process // address space. - Addr interp_mapsize = roundUp(interp->mapSize(), system->getPageBytes()); + Addr interp_mapsize = roundUp(interp->mapSize(), pTable->pageSize()); // We are allocating the memory area; set the bias to the lowest address // in the allocated memory region. diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc index a0b7d2bc1..fd5699ce1 100644 --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -241,7 +241,7 @@ exitGroupFunc(SyscallDesc *desc, ThreadContext *tc, int status) SyscallReturn getpagesizeFunc(SyscallDesc *desc, ThreadContext *tc) { - return (int)tc->getSystemPtr()->getPageBytes(); + return (int)tc->getProcessPtr()->pTable->pageSize(); } @@ -336,11 +336,10 @@ munmapFunc(SyscallDesc *desc, ThreadContext *tc, Addr start, size_t length) // access them again. auto p = tc->getProcessPtr(); - if (start & (tc->getSystemPtr()->getPageBytes() - 1) || !length) { + if (p->pTable->pageOffset(start)) return -EINVAL; - } - length = roundUp(length, tc->getSystemPtr()->getPageBytes()); + length = roundUp(length, p->pTable->pageSize()); p->memState->unmapRegion(start, length); diff --git a/src/sim/syscall_emul.hh b/src/sim/syscall_emul.hh index 9d1f6e272..7d7e2652b 100644 --- a/src/sim/syscall_emul.hh +++ b/src/sim/syscall_emul.hh @@ -1094,7 +1094,7 @@ mremapFunc(SyscallDesc *desc, ThreadContext *tc, GuestABI::VarArgs varargs) { auto p = tc->getProcessPtr(); - Addr page_bytes = tc->getSystemPtr()->getPageBytes(); + Addr page_bytes = p->pTable->pageSize(); uint64_t provided_address = 0; bool use_provided_address = flags & OS::TGT_MREMAP_FIXED; @@ -1626,7 +1626,7 @@ mmapFunc(SyscallDesc *desc, ThreadContext *tc, int tgt_flags, int tgt_fd, typename OS::off_t offset) { auto p = tc->getProcessPtr(); - Addr page_bytes = tc->getSystemPtr()->getPageBytes(); + Addr page_bytes = p->pTable->pageSize(); if (start & (page_bytes - 1) || offset & (page_bytes - 1) || @@ -1809,8 +1809,9 @@ mmap2Func(SyscallDesc *desc, ThreadContext *tc, Addr start, typename OS::size_t length, int prot, int tgt_flags, int tgt_fd, typename OS::off_t offset) { + auto page_size = tc->getProcessPtr()->pTable->pageSize(); return mmapFunc(desc, tc, start, length, prot, tgt_flags, - tgt_fd, offset * tc->getSystemPtr()->getPageBytes()); + tgt_fd, offset * page_size); } /// Target getrlimit() handler. -- 2.30.2