mem,sim: Get the page size from the page table in SE mode.
authorGabe Black <gabe.black@gmail.com>
Wed, 21 Oct 2020 11:32:39 +0000 (04:32 -0700)
committerGabe Black <gabe.black@gmail.com>
Fri, 6 Nov 2020 08:16:40 +0000 (08:16 +0000)
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 <noreply+kokoro@google.com>
Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu>
Maintainer: Gabe Black <gabe.black@gmail.com>

src/mem/multi_level_page_table.hh
src/mem/page_table.cc
src/mem/page_table.hh
src/sim/mem_state.cc
src/sim/process.cc
src/sim/syscall_emul.cc
src/sim/syscall_emul.hh

index 68a32b16015aa1917bb419c93dfa41fea0eb2f66..3d9ca9b586dfca9963ddc9c4843098facc10e858 100644 (file)
@@ -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<EntryTypes...>(system, pageSize);
+        _basePtr = prepTopTable<EntryTypes...>(system, _pageSize);
     }
 
     Addr basePtr() { return _basePtr; }
@@ -216,8 +216,8 @@ public:
 
         Final entry;
 
-        for (int64_t offset = 0; offset < size; offset += pageSize) {
-            walk<EntryTypes...>(system, pageSize, _basePtr,
+        for (int64_t offset = 0; offset < size; offset += _pageSize) {
+            walk<EntryTypes...>(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<EntryTypes...>(system, pageSize, _basePtr, vaddr + offset,
+            walk<EntryTypes...>(system, _pageSize, _basePtr, vaddr + offset,
                                 false, &old_entry);
             old_entry.present(false);
             old_entry.write(system->physProxy);
 
             // Map the new one.
-            walk<EntryTypes...>(system, pageSize, _basePtr, new_vaddr + offset,
-                                true, &new_entry);
+            walk<EntryTypes...>(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<EntryTypes...>(system, pageSize, _basePtr,
+        for (int64_t offset = 0; offset < size; offset += _pageSize) {
+            walk<EntryTypes...>(system, _pageSize, _basePtr,
                                 vaddr + offset, false, &entry);
             fatal_if(!entry.present(),
                      "PageTable::unmap: Address %#x not mapped.", vaddr);
index 5318f355884670a4dbb4c9b18bb814e797292524..d088d296b51e6a226b8ba066f9248a8b7e9a025d 100644 (file)
@@ -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;
     }
index 18ee18ac5d38461052ddb7f4341900b1aecd0c82..65725f349028ed6fbe565c094876ed7cf2c979d6 100644 (file)
@@ -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.
index 7adee590a3cfec2a31572dbea2a07e14ac90af1d..6d64f125ace387f78b41740072cb21bb166dd31a 100644 (file)
@@ -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),
index 3968adbd39a7e80050cb5f2d85a09d55ee2431a8..315f86b7e25c8f926df1ee7544e4991888f8c644 100644 (file)
@@ -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.
index a0b7d2bc1125075122455c3624d558c37ecd3c50..fd5699ce152d0735711ff49341ba485b6bcd55ba 100644 (file)
@@ -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);
 
index 9d1f6e27251ccd7fea1ed60ca713a22e962998ca..7d7e2652beed4fbe7bc7041ac17805b3325dff49 100644 (file)
@@ -1094,7 +1094,7 @@ mremapFunc(SyscallDesc *desc, ThreadContext *tc,
         GuestABI::VarArgs<uint64_t> 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<OS>(desc, tc, start, length, prot, tgt_flags,
-                        tgt_fd, offset * tc->getSystemPtr()->getPageBytes());
+                        tgt_fd, offset * page_size);
 }
 
 /// Target getrlimit() handler.