x86, mem: Don't try to force physical addresses on the system.
authorGabe Black <gabeblack@google.com>
Mon, 8 Jan 2018 05:32:39 +0000 (21:32 -0800)
committerGabe Black <gabeblack@google.com>
Sat, 20 Jan 2018 08:08:39 +0000 (08:08 +0000)
Use the system object to allocate physical memory instead of manually
placing certain structures and then forcing the system to start other
allocations after them in physical memory.

Change-Id: Ie18c81645c3b648c64a6d7a649a0e50f7028f344
Reviewed-on: https://gem5-review.googlesource.com/7346
Maintainer: Gabe Black <gabeblack@google.com>
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
src/arch/x86/process.cc
src/arch/x86/system.hh
src/mem/multi_level_page_table.hh
src/mem/multi_level_page_table_impl.hh

index 0a94ac4179eadd5860de0765817981d273d5529c..43a5273d7d191ae812746f39d49da13a994cd71a 100644 (file)
@@ -103,8 +103,7 @@ X86Process::X86Process(ProcessParams *params, ObjectFile *objFile,
                               new ArchPageTable(
                                       params->name, params->pid,
                                       params->system, PageBytes,
-                                      PageTableLayout,
-                                      pageTablePhysAddr >> PageShift)) :
+                                      PageTableLayout)) :
                       new EmulationPageTable(params->name, params->pid,
                                              PageBytes),
               objFile),
@@ -214,12 +213,19 @@ X86_64Process::initState()
     if (kvmInSE) {
         PortProxy physProxy = system->physProxy;
 
+        Addr syscallCodePhysAddr = system->allocPhysPages(1);
+        Addr gdtPhysAddr = system->allocPhysPages(1);
+        Addr idtPhysAddr = system->allocPhysPages(1);
+        Addr istPhysAddr = system->allocPhysPages(1);
+        Addr tssPhysAddr = system->allocPhysPages(1);
+        Addr pfHandlerPhysAddr = system->allocPhysPages(1);
+
         /*
          * Set up the gdt.
          */
         uint8_t numGDTEntries = 0;
         uint64_t nullDescriptor = 0;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
                             (uint8_t *)(&nullDescriptor), 8);
         numGDTEntries++;
 
@@ -243,7 +249,7 @@ X86_64Process::initState()
         csLowPLDesc.type.codeOrData = 1;
         csLowPLDesc.dpl = 0;
         uint64_t csLowPLDescVal = csLowPLDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
                             (uint8_t *)(&csLowPLDescVal), 8);
 
         numGDTEntries++;
@@ -257,7 +263,7 @@ X86_64Process::initState()
         dsLowPLDesc.type.codeOrData = 0;
         dsLowPLDesc.dpl = 0;
         uint64_t dsLowPLDescVal = dsLowPLDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
                             (uint8_t *)(&dsLowPLDescVal), 8);
 
         numGDTEntries++;
@@ -271,7 +277,7 @@ X86_64Process::initState()
         dsDesc.type.codeOrData = 0;
         dsDesc.dpl = 3;
         uint64_t dsDescVal = dsDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
                             (uint8_t *)(&dsDescVal), 8);
 
         numGDTEntries++;
@@ -285,7 +291,7 @@ X86_64Process::initState()
         csDesc.type.codeOrData = 1;
         csDesc.dpl = 3;
         uint64_t csDescVal = csDesc;
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
                             (uint8_t *)(&csDescVal), 8);
 
         numGDTEntries++;
@@ -321,7 +327,7 @@ X86_64Process::initState()
             uint64_t high;
         } tssDescVal = {TSSDescLow, TSSDescHigh};
 
-        physProxy.writeBlob(GDTPhysAddr + numGDTEntries * 8,
+        physProxy.writeBlob(gdtPhysAddr + numGDTEntries * 8,
                             (uint8_t *)(&tssDescVal), sizeof(tssDescVal));
 
         numGDTEntries++;
@@ -405,7 +411,7 @@ X86_64Process::initState()
             CR0 cr2 = 0;
             tc->setMiscReg(MISCREG_CR2, cr2);
 
-            CR3 cr3 = pageTablePhysAddr;
+            CR3 cr3 = dynamic_cast<ArchPageTable *>(pTable)->basePtr();
             tc->setMiscReg(MISCREG_CR3, cr3);
 
             CR4 cr4 = 0;
@@ -428,10 +434,6 @@ X86_64Process::initState()
             CR4 cr8 = 0;
             tc->setMiscReg(MISCREG_CR8, cr8);
 
-            const Addr PageMapLevel4 = pageTablePhysAddr;
-            //Point to the page tables.
-            tc->setMiscReg(MISCREG_CR3, PageMapLevel4);
-
             tc->setMiscReg(MISCREG_MXCSR, 0x1f80);
 
             tc->setMiscReg(MISCREG_APIC_BASE, 0xfee00900);
@@ -493,7 +495,7 @@ X86_64Process::initState()
         tss.RSP1_high = tss.IST1_high;
         tss.RSP2_low  = tss.IST1_low;
         tss.RSP2_high = tss.IST1_high;
-        physProxy.writeBlob(TSSPhysAddr, (uint8_t *)(&tss), sizeof(tss));
+        physProxy.writeBlob(tssPhysAddr, (uint8_t *)(&tss), sizeof(tss));
 
         /* Setting IDT gates */
         GateDescriptorLow PFGateLow = 0;
@@ -513,7 +515,7 @@ X86_64Process::initState()
             uint64_t high;
         } PFGate = {PFGateLow, PFGateHigh};
 
-        physProxy.writeBlob(IDTPhysAddr + 0xE0,
+        physProxy.writeBlob(idtPhysAddr + 0xE0,
                             (uint8_t *)(&PFGate), sizeof(PFGate));
 
         /* System call handler */
@@ -539,7 +541,7 @@ X86_64Process::initState()
             0x48, 0xcf
         };
 
-        physProxy.writeBlob(PFHandlerPhysAddr, faultBlob, sizeof(faultBlob));
+        physProxy.writeBlob(pfHandlerPhysAddr, faultBlob, sizeof(faultBlob));
 
         MultiLevelPageTable<PageTableOps> *pt =
             dynamic_cast<MultiLevelPageTable<PageTableOps> *>(pTable);
@@ -547,15 +549,15 @@ X86_64Process::initState()
         /* Syscall handler */
         pt->map(syscallCodeVirtAddr, syscallCodePhysAddr, PageBytes, false);
         /* GDT */
-        pt->map(GDTVirtAddr, GDTPhysAddr, PageBytes, false);
+        pt->map(GDTVirtAddr, gdtPhysAddr, PageBytes, false);
         /* IDT */
-        pt->map(IDTVirtAddr, IDTPhysAddr, PageBytes, false);
+        pt->map(IDTVirtAddr, idtPhysAddr, PageBytes, false);
         /* TSS */
-        pt->map(TSSVirtAddr, TSSPhysAddr, PageBytes, false);
+        pt->map(TSSVirtAddr, tssPhysAddr, PageBytes, false);
         /* IST */
-        pt->map(ISTVirtAddr, ISTPhysAddr, PageBytes, false);
+        pt->map(ISTVirtAddr, istPhysAddr, PageBytes, false);
         /* PF handler */
-        pt->map(PFHandlerVirtAddr, PFHandlerPhysAddr, PageBytes, false);
+        pt->map(PFHandlerVirtAddr, pfHandlerPhysAddr, PageBytes, false);
         /* MMIO region for m5ops */
         pt->map(MMIORegionVirtAddr, MMIORegionPhysAddr, 16*PageBytes, false);
     } else {
index 45bc9651cee2ef8dafd1343462f039b5cb90a891..829a18da43ed767b2953fe59174e7e66bbceca9f 100644 (file)
@@ -64,21 +64,14 @@ namespace X86ISA
 
     /* memory mappings for KVMCpu in SE mode */
     const uint64_t syscallCodeVirtAddr = 0xffff800000000000;
-    const uint64_t syscallCodePhysAddr = 0x60000;
     const uint64_t GDTVirtAddr = 0xffff800000001000;
-    const uint64_t GDTPhysAddr = 0x61000;
     const uint64_t IDTVirtAddr = 0xffff800000002000;
-    const uint64_t IDTPhysAddr = 0x62000;
     const uint64_t TSSVirtAddr = 0xffff800000003000;
     const uint64_t TSSPhysAddr = 0x63000;
     const uint64_t ISTVirtAddr = 0xffff800000004000;
-    const uint64_t ISTPhysAddr = 0x64000;
     const uint64_t PFHandlerVirtAddr = 0xffff800000005000;
-    const uint64_t PFHandlerPhysAddr = 0x65000;
     const uint64_t MMIORegionVirtAddr = 0xffffc90000000000;
     const uint64_t MMIORegionPhysAddr = 0xffff0000;
-
-    const uint64_t pageTablePhysAddr = 0x70000;
 }
 
 class X86System : public System
index 7cbbd8c0ef929697f333e1a5902cf65e89b0a1d0..30f53470696a157c7f795b602904a12593b22f11 100644 (file)
@@ -115,7 +115,7 @@ class MultiLevelPageTable : public EmulationPageTable
     /**
      * Physical address to the last level of the page table
      */
-    Addr basePtr;
+    Addr _basePtr;
 
     /**
      * Vector with sizes of all levels in base 2 logarithmic
@@ -140,12 +140,13 @@ class MultiLevelPageTable : public EmulationPageTable
 public:
     MultiLevelPageTable(const std::string &__name, uint64_t _pid,
                         System *_sys, Addr pageSize,
-                        const std::vector<uint8_t> &layout,
-                        Addr _basePtr);
+                        const std::vector<uint8_t> &layout);
     ~MultiLevelPageTable();
 
     void initState(ThreadContext* tc) override;
 
+    Addr basePtr() { return _basePtr; }
+
     void map(Addr vaddr, Addr paddr, int64_t size,
              uint64_t flags = 0) override;
     void remap(Addr vaddr, int64_t size, Addr new_vaddr) override;
index 3356c9ea230cbf70173f81c1540950901cdcacb7..d756de658f25a7f37bd5a6f21412e8ab904aba08 100644 (file)
@@ -47,9 +47,9 @@ using namespace TheISA;
 template <class ISAOps>
 MultiLevelPageTable<ISAOps>::MultiLevelPageTable(
         const std::string &__name, uint64_t _pid, System *_sys,
-        Addr pageSize, const std::vector<uint8_t> &layout, Addr _basePtr)
+        Addr pageSize, const std::vector<uint8_t> &layout)
     : EmulationPageTable(__name, _pid, pageSize), system(_sys),
-    basePtr(_basePtr), logLevelSize(layout), numLevels(logLevelSize.size())
+      logLevelSize(layout), numLevels(logLevelSize.size())
 {
 }
 
@@ -62,18 +62,16 @@ template <class ISAOps>
 void
 MultiLevelPageTable<ISAOps>::initState(ThreadContext* tc)
 {
-    system->pagePtr = basePtr;
-
     /* setting first level of the page table */
     uint64_t log_req_size = floorLog2(sizeof(PageTableEntry)) +
-                            logLevelSize[numLevels-1];
+                            logLevelSize[numLevels - 1];
     assert(log_req_size >= PageShift);
     uint64_t npages = 1 << (log_req_size - PageShift);
 
-    Addr paddr = system->allocPhysPages(npages);
+    Addr _basePtr = system->allocPhysPages(npages);
 
     PortProxy &p = system->physProxy;
-    p.memsetBlob(paddr, 0, npages << PageShift);
+    p.memsetBlob(_basePtr, 0, npages << PageShift);
 }
 
 
@@ -83,7 +81,7 @@ MultiLevelPageTable<ISAOps>::walk(Addr vaddr, bool allocate, Addr &PTE_addr)
 {
     std::vector<uint64_t> offsets = pTableISAOps.getOffsets(vaddr);
 
-    Addr level_base = basePtr;
+    Addr level_base = _basePtr;
     for (int i = numLevels - 1; i > 0; i--) {
 
         Addr entry_addr = (level_base<<PageShift) +
@@ -221,7 +219,7 @@ MultiLevelPageTable<ISAOps>::serialize(CheckpointOut &cp) const
      * which is serialized separately, we will serialize
      * just the base pointer
      */
-    paramOut(cp, "ptable.pointer", basePtr);
+    paramOut(cp, "ptable.pointer", _basePtr);
 }
 
 template <class ISAOps>
@@ -229,5 +227,5 @@ void
 MultiLevelPageTable<ISAOps>::unserialize(CheckpointIn &cp)
 {
     EmulationPageTable::unserialize(cp);
-    paramIn(cp, "ptable.pointer", basePtr);
+    paramIn(cp, "ptable.pointer", _basePtr);
 }