Gabe Black has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/57009 )

Change subject: arch-x86: Move segmentation checks to ld/st microops.
......................................................................

arch-x86: Move segmentation checks to ld/st microops.

These microops were applying the segment base, but not checking limits,
segmentation level access permissions, whether the segment is usable,
etc. Then in the TLB, the original offset and other information had to
be recovered from the post segmentation address, and the request flags.

Instead, we can perform those checks in the microops which already have
all the information they need. This simplifies the plumbing to the TLB,
and avoids having to reverse segmentation which is error prone.

Change-Id: I1fe70ad650bf4f221660e608c49b70e081223e3f
---
M src/arch/amdgpu/common/tlb.cc
M src/arch/x86/SConscript
A src/arch/x86/insts/microldstop.cc
M src/arch/x86/insts/microldstop.hh
M src/arch/x86/isa/microops/ldstop.isa
M src/arch/x86/ldstflags.hh
M src/arch/x86/tlb.cc
M src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
8 files changed, 235 insertions(+), 187 deletions(-)



diff --git a/src/arch/amdgpu/common/tlb.cc b/src/arch/amdgpu/common/tlb.cc
index 698570b..f0f806a 100644
--- a/src/arch/amdgpu/common/tlb.cc
+++ b/src/arch/amdgpu/common/tlb.cc
@@ -438,53 +438,25 @@
         // If protected mode has been enabled...
         if (m5Reg.prot) {
             DPRINTF(GPUTLB, "In protected mode.\n");
-            // If we're not in 64-bit mode, do protection/limit checks
-            if (m5Reg.mode != LongMode) {
-                DPRINTF(GPUTLB, "Not in long mode. Checking segment "
-                        "protection.\n");
+ // If we're not in 64-bit mode and doing a fetch, check CS limits.
+            if (m5Reg.mode != LongMode && mode == BaseMMU::Execute) {
+                DPRINTF(GPUTLB, "Not in long mode. Checking CS limits.\n");

-                // Check for a null segment selector.
- if (!(seg == SEGMENT_REG_TSG || seg == SYS_SEGMENT_REG_IDTR ||
-                    seg == SEGMENT_REG_HS || seg == SEGMENT_REG_LS)
-                    && !tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg))) {
+ const SegAttr attr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
+                // Check for an unusable segment.
+                if (attr.unusable) {
+                    DPRINTF(GPUTLB, "Unusable segment.\n");
                     return std::make_shared<GeneralProtection>(0);
                 }
-
-                bool expandDown = false;
- SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
-
-                if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) {
-                    if (!attr.writable && (mode == BaseMMU::Write ||
-                        storeCheck))
-                        return std::make_shared<GeneralProtection>(0);
-
-                    if (!attr.readable && mode == BaseMMU::Read)
-                        return std::make_shared<GeneralProtection>(0);
-
-                    expandDown = attr.expandDown;
-
-                }
-
-                Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg));
- Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg)); - Addr logSize = (flags >> AddrSizeFlagShift) & AddrSizeFlagMask;
-                int size = 8 << logSize;
-
-                Addr offset = (vaddr - base) & mask(size);
-                Addr endOffset = offset + req->getSize() - 1;
-
-                if (expandDown) {
-                    DPRINTF(GPUTLB, "Checking an expand down segment.\n");
-                    warn_once("Expand down segments are untested.\n");
-
-                    if (offset <= limit || endOffset <= limit)
-                        return std::make_shared<GeneralProtection>(0);
-                } else {
-                    if (offset > limit || endOffset > limit)
-                        return std::make_shared<GeneralProtection>(0);
+ const Addr base = tc->readMiscRegNoEffect(MISCREG_CS_EFF_BASE); + const Addr limit = tc->readMiscRegNoEffect(MISCREG_CS_LIMIT);
+                const Addr offset = vaddr - base;
+                if (offset + req->getSize() - 1 > limit) {
+                    DPRINTF(GPUTLB, "Segment limit check failed, "
+                            "offset = %#x limit = %#x.\n", offset, limit);
+                    return std::make_shared<GeneralProtection>(0);
                 }
             }
-
             // If paging is enabled, do the translation.
             if (m5Reg.paging) {
                 DPRINTF(GPUTLB, "Paging enabled.\n");
diff --git a/src/arch/x86/SConscript b/src/arch/x86/SConscript
index 5c80532..c592248 100644
--- a/src/arch/x86/SConscript
+++ b/src/arch/x86/SConscript
@@ -48,6 +48,7 @@
 Source('fs_workload.cc', tags='x86 isa')
 Source('insts/badmicroop.cc', tags='x86 isa')
 Source('insts/microop.cc', tags='x86 isa')
+Source('insts/microldstop.cc', tags='x86 isa')
 Source('insts/microregop.cc', tags='x86 isa')
 Source('insts/static_inst.cc', tags='x86 isa')
 Source('interrupts.cc', tags='x86 isa')
diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc
new file mode 100644
index 0000000..0d603d9
--- /dev/null
+++ b/src/arch/x86/insts/microldstop.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2007-2008 The Hewlett-Packard Development Company
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "arch/x86/insts/microldstop.hh"
+
+#include "arch/x86/faults.hh"
+#include "arch/x86/regs/misc.hh"
+#include "arch/x86/regs/segment.hh"
+#include "base/logging.hh"
+#include "debug/TLB.hh"
+
+namespace gem5
+{
+
+namespace X86ISA
+{
+
+Fault
+MemOp::segmentationCheck(Addr offset, SegmentRegIndex segment,
+        Addr base, Addr size, bool is_load, ThreadContext *tc) const
+{
+ const SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(segment));
+    const bool store_check = memFlags & Request::READ_MODIFY_WRITE;
+
+    // Check for an unusable segment.
+    if (attr.unusable) {
+        DPRINTF(TLB, "Unusable segment.\n");
+        return std::make_shared<GeneralProtection>(0);
+    }
+
+    // Check read/write permissions.
+    bool expand_down = false;
+    if (segment >= SEGMENT_REG_ES && segment <= SEGMENT_REG_HS) {
+        if (!attr.writable && (!is_load || store_check)) {
+            DPRINTF(TLB, "Tried to write to unwritable segment.\n");
+            return std::make_shared<GeneralProtection>(0);
+        }
+        if (!attr.readable && is_load) {
+            DPRINTF(TLB, "Tried to read from unreadble segment.\n");
+            return std::make_shared<GeneralProtection>(0);
+        }
+        // Only these segments can be expand down.
+        expand_down = attr.expandDown;
+    }
+
+    // Check the limit.
+    const Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(segment));
+    if (expand_down) {
+        DPRINTF(TLB, "Checking an expand down segment.\n");
+        warn_once("Expand down segments are untested.\n");
+        if (offset <= limit)
+            return std::make_shared<GeneralProtection>(0);
+    } else {
+        if (offset + size - 1 > limit) {
+            DPRINTF(TLB, "Segment limit check failed, "
+                    "offset = %#x limit = %#x.\n", offset, limit);
+            return std::make_shared<GeneralProtection>(0);
+        }
+    }
+
+    // No problems found!
+    return NoFault;
+}
+
+} // namespace X86ISA
+} // namespace gem5
diff --git a/src/arch/x86/insts/microldstop.hh b/src/arch/x86/insts/microldstop.hh
index e38341b..90b8058 100644
--- a/src/arch/x86/insts/microldstop.hh
+++ b/src/arch/x86/insts/microldstop.hh
@@ -74,6 +74,9 @@
foldABit((addressSize == 1 && !mach_inst.rex.present) ? 1 << 6 : 0)
     {}

+    Fault segmentationCheck(Addr offset, SegmentRegIndex segment,
+            Addr base, Addr size, bool is_load, ThreadContext *tc) const;
+
   public:
     const uint8_t dataSize;
     const uint8_t addressSize;
diff --git a/src/arch/x86/isa/microops/ldstop.isa b/src/arch/x86/isa/microops/ldstop.isa
index 2e15b71..2806f1e 100644
--- a/src/arch/x86/isa/microops/ldstop.isa
+++ b/src/arch/x86/isa/microops/ldstop.isa
@@ -49,20 +49,13 @@
     Fault %(class_name)s::execute(ExecContext *xc,
           Trace::InstRecord *traceData) const
     {
-        Fault fault = NoFault;
-        Addr EA;
-
         %(op_decl)s;
         %(op_rd)s;
-        %(ea_code)s;
- DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
-
+        %(addr_code)s;
         %(code)s;
-        if (fault == NoFault) {
-            %(op_wb)s;
-        }
+        %(op_wb)s;

-        return fault;
+        return NoFault;
     }
 }};

@@ -95,27 +88,23 @@
     %(class_name)s::execute(ExecContext *xc,
             Trace::InstRecord *traceData) const
     {
-        Fault fault = NoFault;
-        Addr EA;
-
         %(op_decl)s;
         %(op_rd)s;
-        %(ea_code)s;
- DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
+        %(addr_code)s;

-        fault = readMemAtomic(xc, traceData, EA, Mem, dataSize, memFlags);
-
-        if (fault == NoFault) {
-            %(code)s;
-        } else if (memFlags & Request::PREFETCH) {
+ Fault fault = readMemAtomic(xc, traceData, linear, Mem, %(data_size)s,
+                memFlags);
+        if (fault) {
             // For prefetches, ignore any faults/exceptions.
-            return NoFault;
-        }
-        if (fault == NoFault) {
-            %(op_wb)s;
+            if (memFlags & Request::PREFETCH)
+                return NoFault;
+            return fault;
         }

-        return fault;
+        %(code)s;
+        %(op_wb)s;
+
+        return NoFault;
     }
 }};

@@ -124,17 +113,11 @@
     %(class_name)s::initiateAcc(ExecContext *xc,
             Trace::InstRecord *traceData) const
     {
-        Fault fault = NoFault;
-        Addr EA;
-
         %(op_decl)s;
         %(op_rd)s;
-        %(ea_code)s;
- DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
+        %(addr_code)s;

- fault = initiateMemRead(xc, traceData, EA, %(memDataSize)s, memFlags);
-
-        return fault;
+ return initiateMemRead(xc, traceData, linear, %(data_size)s, memFlags);
     }
 }};

@@ -143,20 +126,15 @@
     %(class_name)s::completeAcc(PacketPtr pkt, ExecContext *xc,
             Trace::InstRecord *traceData) const
     {
-        Fault fault = NoFault;
-
         %(op_decl)s;
         %(op_rd)s;

         getMem(pkt, Mem, dataSize, traceData);

         %(code)s;
+        %(op_wb)s;

-        if (fault == NoFault) {
-            %(op_wb)s;
-        }
-
-        return fault;
+        return NoFault;
     }
 }};

@@ -167,25 +145,18 @@
     %(class_name)s::execute(ExecContext *xc,
             Trace::InstRecord *traceData) const
     {
-        Fault fault = NoFault;
-
-        Addr EA;
         %(op_decl)s;
         %(op_rd)s;
-        %(ea_code)s;
- DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
-
+        %(addr_code)s;
         %(code)s;

-        if (fault == NoFault) {
-            fault = writeMemAtomic(xc, traceData, Mem, dataSize, EA,
-                    memFlags, NULL);
-            if (fault == NoFault) {
-                %(op_wb)s;
-            }
-        }
+        Fault fault = writeMemAtomic(xc, traceData, Mem, %(data_size)s,
+                linear, memFlags, NULL);
+        if (fault)
+            return fault;

-        return fault;
+        %(op_wb)s;
+        return NoFault;
     }
 }};

@@ -194,21 +165,13 @@
     %(class_name)s::initiateAcc(ExecContext *xc,
             Trace::InstRecord *traceData) const
     {
-        Fault fault = NoFault;
-
-        Addr EA;
         %(op_decl)s;
         %(op_rd)s;
-        %(ea_code)s;
- DPRINTF(X86, "%s : %s: The address is %#x\n", instMnem, mnemonic, EA);
-
+        %(addr_code)s;
         %(code)s;

-        if (fault == NoFault) {
-            fault = writeMemTiming(xc, traceData, Mem, dataSize, EA,
-                    memFlags, NULL);
-        }
-        return fault;
+        return writeMemTiming(xc, traceData, Mem, %(data_size)s, linear,
+                memFlags, NULL);
     }
 }};

@@ -296,10 +259,48 @@
     decoder_output = ""
     exec_output = ""

-    segmentEAExpr = \
-        'bits(scale * Index + Base + disp, addressSize * 8 - 1, 0);'
+    # Calculate the "effective", aka pre-segmentation, address.
+    calc_effective = '''
+    Addr effective = (scale * Index + Base + disp) & mask(addressSize * 8);
+    '''

-    calculateEA = 'EA = SegBase + ' + segmentEAExpr
+    effective_addr_code = calc_effective + r'''
+    DPRINTF(X86, "%s : %s: The effective address is %#x.\n",
+            instMnem, mnemonic, effective);
+    '''
+
+    # Calculate the "linear", aka post-segmentation, address.
+    calc_linear = '''
+    Addr linear = SegBase + effective;
+    if (machInst.mode.mode != X86ISA::LongMode && addressSize != 8)
+        linear &= mask(32);
+    '''
+    calc_check_linear = '''
+    // Perform segmentation checks.
+ if (machInst.mode.mode != X86ISA::LongMode && segment != SEGMENT_REG_MS) { + Fault fault = segmentationCheck(effective, (SegmentRegIndex)segment,
+                SegBase, %(data_size)s, %(is_load)s, xc->tcBase());
+        if (fault)
+            return fault;
+    }
+    ''' + calc_linear
+
+    linear_debug_code = r'''
+    if (SegBase) {
+        DPRINTF(X86, "%s : %s: The linear address is %#x (%#x + %#x).\n",
+                instMnem, mnemonic, linear, SegBase, effective);
+    } else {
+        DPRINTF(X86, "%s : %s: The address is %#x.\n",
+                instMnem, mnemonic, linear);
+    }
+    '''
+
+    def linear_addr_code(is_load, data_size='dataSize'):
+        is_load = 'true' if is_load else 'false'
+        return calc_effective + (calc_check_linear % locals()) + \
+            linear_debug_code
+
+    linear_no_check_code = calc_effective + calc_linear + linear_debug_code

     for cls in microopClasses.loadops:
         if cls.is_float:
@@ -310,13 +311,13 @@
         # Build up the all register version of this micro op
         iops = [InstObjParams(cls.mnemonic, cls.className, base,
                               { "code": cls.code,
-                                "ea_code": calculateEA,
-                                "memDataSize": "dataSize" })]
+                                "addr_code": linear_addr_code(True),
+                                "data_size": "dataSize" })]
         if cls.big:
iops += [InstObjParams(cls.mnemonic, cls.className + "Big", base,
                                    { "code": cls.bigCode,
-                                     "ea_code": calculateEA,
-                                     "memDataSize": "dataSize" })]
+                                     "addr_code": linear_addr_code(True),
+                                     "data_size": "dataSize" })]
         for iop in iops:
             header_output += MicroLdStOpDeclare.subst(iop)
             exec_output += MicroLoadExecute.subst(iop)
@@ -330,9 +331,9 @@
         '''

iop = InstObjParams(cls.mnemonic, cls.className, 'X86ISA::LdStSplitOp',
-                            { "code": code,
-                              "ea_code": calculateEA,
-                              "memDataSize": "2 * dataSize" })
+                { "code": code,
+                  "addr_code": linear_addr_code(True, '2 * dataSize'),
+                  "data_size": "2 * dataSize" })

         header_output += MicroLdStSplitOpDeclare.subst(iop)
         decoder_output += MicroLdStSplitOpConstructor.subst(iop)
@@ -350,9 +351,9 @@

         # Build up the all register version of this micro op
         iop = InstObjParams(cls.mnemonic, cls.className, base,
-                            { "code": cls.code,
-                              "ea_code": calculateEA,
-                              "memDataSize": "dataSize" })
+                { "code": cls.code,
+                  "addr_code": linear_addr_code(False),
+                  "data_size": "dataSize" })
         header_output += MicroLdStOpDeclare.subst(iop)
         exec_output += MicroStoreExecute.subst(iop)
         exec_output += MicroStoreInitiateAcc.subst(iop)
@@ -365,9 +366,9 @@
         '''

iop = InstObjParams(cls.mnemonic, cls.className, 'X86ISA::LdStSplitOp',
-                            { "code": code,
-                              "ea_code": calculateEA,
-                              "memDataSize": "2 * dataSize" })
+                { "code": code,
+                  "addr_code": linear_addr_code(False, '2 * dataSize'),
+                  "data_size": "2 * dataSize" })

         header_output += MicroLdStSplitOpDeclare.subst(iop)
         decoder_output += MicroLdStSplitOpConstructor.subst(iop)
@@ -376,17 +377,17 @@
         exec_output += MicroStoreCompleteAcc.subst(iop)

     iop = InstObjParams("lea", "Lea", 'X86ISA::LdStOp',
- { "code": "Data = merge(Data, data, EA, dataSize);",
-                          "ea_code": "EA = " + segmentEAExpr,
-                          "memDataSize": "dataSize" })
+            { "code": "Data = merge(Data, data, effective, dataSize);",
+              "addr_code": effective_addr_code,
+              "data_size": "dataSize" })
     header_output += MicroLeaDeclare.subst(iop)
     exec_output += MicroLeaExecute.subst(iop)


     iop = InstObjParams("tia", "Tia", 'X86ISA::MemNoDataOp',
-                        { "code": "xc->demapPage(EA, 0);",
-                          "ea_code": calculateEA,
-                          "memDataSize": "dataSize" })
+            { "code": "xc->demapPage(linear, 0);",
+              "addr_code": linear_no_check_code,
+              "data_size": "dataSize" })
     header_output += MicroLeaDeclare.subst(iop)
     exec_output += MicroLeaExecute.subst(iop)
 }};
diff --git a/src/arch/x86/ldstflags.hh b/src/arch/x86/ldstflags.hh
index c18033e..d22778f 100644
--- a/src/arch/x86/ldstflags.hh
+++ b/src/arch/x86/ldstflags.hh
@@ -54,8 +54,6 @@
 constexpr Request::FlagsType SegmentFlagMask = mask(4);
 constexpr auto CPL0FlagShift = 4;
 constexpr auto CPL0FlagBit = 1 << CPL0FlagShift;
-constexpr auto AddrSizeFlagShift = CPL0FlagShift + 1;
-constexpr auto AddrSizeFlagMask = mask(2);

 } // namespace X86ISA
 } // namespace gem5
diff --git a/src/arch/x86/tlb.cc b/src/arch/x86/tlb.cc
index ad2609b..6f5d51d 100644
--- a/src/arch/x86/tlb.cc
+++ b/src/arch/x86/tlb.cc
@@ -328,64 +328,28 @@

     HandyM5Reg m5Reg = tc->readMiscRegNoEffect(MISCREG_M5_REG);

- const Addr logAddrSize = (flags >> AddrSizeFlagShift) & AddrSizeFlagMask;
-    const int addrSize = 8 << logAddrSize;
-    const Addr addrMask = mask(addrSize);
-
     // If protected mode has been enabled...
     if (m5Reg.prot) {
         DPRINTF(TLB, "In protected mode.\n");
-        // If we're not in 64-bit mode, do protection/limit checks
-        if (m5Reg.mode != LongMode) {
- DPRINTF(TLB, "Not in long mode. Checking segment protection.\n");
+        // If we're not in 64-bit mode and doing a fetch, check CS limits.
+        if (m5Reg.mode != LongMode && mode == BaseMMU::Execute) {
+            DPRINTF(TLB, "Not in long mode. Checking CS limits.\n");

- // CPUs won't know to use CS when building fetch requests, so we
-            // need to override the value of "seg" here if this is a fetch.
-            if (mode == BaseMMU::Execute)
-                seg = SEGMENT_REG_CS;
-
-            SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
+            const SegAttr attr = tc->readMiscRegNoEffect(MISCREG_CS_ATTR);
             // Check for an unusable segment.
             if (attr.unusable) {
                 DPRINTF(TLB, "Unusable segment.\n");
                 return std::make_shared<GeneralProtection>(0);
             }
-            bool expandDown = false;
-            if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) {
- if (!attr.writable && (mode == BaseMMU::Write || storeCheck)) { - DPRINTF(TLB, "Tried to write to unwritable segment.\n");
-                    return std::make_shared<GeneralProtection>(0);
-                }
-                if (!attr.readable && mode == BaseMMU::Read) {
- DPRINTF(TLB, "Tried to read from unreadble segment.\n");
-                    return std::make_shared<GeneralProtection>(0);
-                }
-                expandDown = attr.expandDown;
-
-            }
-            Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg));
-            Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg));
-            Addr offset;
-            if (mode == BaseMMU::Execute)
-                offset = vaddr - base;
-            else
-                offset = (vaddr - base) & addrMask;
-            Addr endOffset = offset + req->getSize() - 1;
-            if (expandDown) {
-                DPRINTF(TLB, "Checking an expand down segment.\n");
-                warn_once("Expand down segments are untested.\n");
-                if (offset <= limit || endOffset <= limit)
-                    return std::make_shared<GeneralProtection>(0);
-            } else {
-                if (offset > limit || endOffset > limit) {
-                    DPRINTF(TLB, "Segment limit check failed, "
-                            "offset = %#x limit = %#x.\n", offset, limit);
-                    return std::make_shared<GeneralProtection>(0);
-                }
+            const Addr base = tc->readMiscRegNoEffect(MISCREG_CS_EFF_BASE);
+            const Addr limit = tc->readMiscRegNoEffect(MISCREG_CS_LIMIT);
+            const Addr offset = vaddr - base;
+            if (offset + req->getSize() - 1 > limit) {
+                DPRINTF(TLB, "Segment limit check failed, "
+                        "offset = %#x limit = %#x.\n", offset, limit);
+                return std::make_shared<GeneralProtection>(0);
             }
         }
-        if (m5Reg.submode != SixtyFourBitMode && addrSize != 64)
-            vaddr &= mask(32);
         // If paging is enabled, do the translation.
         if (m5Reg.paging) {
             DPRINTF(TLB, "Paging enabled.\n");
diff --git a/src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py b/src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
index 69c42f0..5d46c71 100644
--- a/src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
+++ b/src/arch/x86/ucasmlib/arch/x86/microops/ldstop.py
@@ -62,9 +62,6 @@
             self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
         if uncacheable:
             self.instFlags += " | Request::UNCACHEABLE"
-        self.memFlags += \
-            " | ((log2i(%s) & AddrSizeFlagMask) << AddrSizeFlagShift)" % \
-            addressSize

     def getAllocator(self, microFlags):
         allocator = '''new %(class_name)s(machInst, macrocodeBlock,
@@ -103,9 +100,6 @@
             self.instFlags += " | (1ULL << StaticInst::IsNonSpeculative)"
         if uncacheable:
             self.instFlags += " | Request::UNCACHEABLE"
-        self.memFlags += \
-            " | ((log2i(%s) & AddrSizeFlagMask) << AddrSizeFlagShift)" % \
-            addressSize

     def getAllocator(self, microFlags):
         allocString = '''
@@ -168,9 +162,7 @@
         self.dataSize = dataSize
         self.addressSize = addressSize
         self.instFlags = ""
-        self.memFlags = baseFlags + \
-            " | ((log2i(%s) & AddrSizeFlagMask) << AddrSizeFlagShift)" % \
-            addressSize
+        self.memFlags = baseFlags

     def getAllocator(self, microFlags):
         allocator = '''new %(class_name)s(machInst, macrocodeBlock,

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/57009
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I1fe70ad650bf4f221660e608c49b70e081223e3f
Gerrit-Change-Number: 57009
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <gabe.bl...@gmail.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to