changeset 71f8d7c12619 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=71f8d7c12619
description:
        X86: Fix segment limit checks.

diffstat:

3 files changed, 21 insertions(+), 22 deletions(-)
src/arch/x86/insts/microldstop.hh    |    3 +-
src/arch/x86/isa/microops/ldstop.isa |    4 ++-
src/arch/x86/tlb.cc                  |   36 +++++++++++++++-------------------

diffs (92 lines):

diff -r dc4162b805f7 -r 71f8d7c12619 src/arch/x86/insts/microldstop.hh
--- a/src/arch/x86/insts/microldstop.hh Fri Feb 27 09:23:42 2009 -0800
+++ b/src/arch/x86/insts/microldstop.hh Fri Feb 27 09:23:50 2009 -0800
@@ -67,7 +67,8 @@
     static const Request::FlagsType SegmentFlagMask = mask(4);
     static const int FlagShift = 4;
     enum FlagBit {
-        CPL0FlagBit = 1
+        CPL0FlagBit = 1,
+        AddrSizeFlagBit = 2
     };
 
     /**
diff -r dc4162b805f7 -r 71f8d7c12619 src/arch/x86/isa/microops/ldstop.isa
--- a/src/arch/x86/isa/microops/ldstop.isa      Fri Feb 27 09:23:42 2009 -0800
+++ b/src/arch/x86/isa/microops/ldstop.isa      Fri Feb 27 09:23:50 2009 -0800
@@ -375,6 +375,8 @@
                 self.memFlags += " | (CPL0FlagBit << FlagShift)"
             if prefetch:
                 self.memFlags += " | Request::PF_EXCLUSIVE"
+            self.memFlags += " | (machInst.legacy.addr ? " + \
+                             "(AddrSizeFlagBit << FlagShift) : 0)"
 
         def getAllocator(self, *microFlags):
             allocator = '''new %(class_name)s(machInst, macrocodeBlock
@@ -439,7 +441,7 @@
     defineMicroLoadOp('Ldfp', 'FpData.uqw = Mem;')
 
     def defineMicroStoreOp(mnemonic, code, \
-            postCode="", completeCode="", mem_flags=0):
+            postCode="", completeCode="", mem_flags="0"):
         global header_output
         global decoder_output
         global exec_output
diff -r dc4162b805f7 -r 71f8d7c12619 src/arch/x86/tlb.cc
--- a/src/arch/x86/tlb.cc       Fri Feb 27 09:23:42 2009 -0800
+++ b/src/arch/x86/tlb.cc       Fri Feb 27 09:23:50 2009 -0800
@@ -575,38 +575,34 @@
             if (!tc->readMiscRegNoEffect(MISCREG_SEG_SEL(seg)))
                 return new GeneralProtection(0);
             bool expandDown = false;
+            SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
             if (seg >= SEGMENT_REG_ES && seg <= SEGMENT_REG_HS) {
-                SegAttr attr = tc->readMiscRegNoEffect(MISCREG_SEG_ATTR(seg));
                 if (!attr.writable && write)
                     return new GeneralProtection(0);
                 if (!attr.readable && !write && !execute)
                     return new GeneralProtection(0);
                 expandDown = attr.expandDown;
+
             }
             Addr base = tc->readMiscRegNoEffect(MISCREG_SEG_BASE(seg));
             Addr limit = tc->readMiscRegNoEffect(MISCREG_SEG_LIMIT(seg));
+            // This assumes we're not in 64 bit mode. If we were, the default
+            // address size is 64 bits, overridable to 32.
+            int size = 32;
+            bool sizeOverride = (flags & (AddrSizeFlagBit << FlagShift));
+            if (csAttr.defaultSize && sizeOverride ||
+                    !csAttr.defaultSize && !sizeOverride)
+                size = 16;
+            Addr offset = bits(vaddr - base, size-1, 0);
+            Addr endOffset = offset + req->getSize() - 1;
             if (expandDown) {
                 DPRINTF(TLB, "Checking an expand down segment.\n");
-                // We don't have to worry about the access going around the
-                // end of memory because accesses will be broken up into
-                // pieces at boundaries aligned on sizes smaller than an
-                // entire address space. We do have to worry about the limit
-                // being less than the base.
-                if (limit < base) {
-                    if (limit < vaddr + req->getSize() && vaddr < base)
-                        return new GeneralProtection(0);
-                } else {
-                    if (limit < vaddr + req->getSize())
-                        return new GeneralProtection(0);
-                }
+                warn_once("Expand down segments are untested.\n");
+                if (offset <= limit || endOffset <= limit)
+                    return new GeneralProtection(0);
             } else {
-                if (limit < base) {
-                    if (vaddr <= limit || vaddr + req->getSize() >= base)
-                        return new GeneralProtection(0);
-                } else {
-                    if (vaddr <= limit && vaddr + req->getSize() >= base)
-                        return new GeneralProtection(0);
-                }
+                if (offset > limit || endOffset > limit)
+                    return new GeneralProtection(0);
             }
         }
         // If paging is enabled, do the translation.
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to