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

Change subject: arch-x86: Try to make seg fault error codes more accurate.
......................................................................

arch-x86: Try to make seg fault error codes more accurate.

Segmentation faults (the hardware ones, not the OS level ones) have
error codes associated with them, and different actual exception vectors
should be used depending on what you were trying to do when the fault
occurred.

We can't get this 100% right as things are today since there don't seem
to be 100% consistent rules about what fault to return given local info,
but we can use the info we have to be a lot closer.

Note that this won't work when we're using a temporary segment to
operate on the stack, for instance, since we're not actually using the
stack segment. There is currently no solution for this, but there could
be in the future if it matters at some point.

Change-Id: Ia2f5ffd53300abdd141ee32698a2099ad2acdf78
---
M src/arch/x86/insts/microldstop.cc
1 file changed, 55 insertions(+), 5 deletions(-)



diff --git a/src/arch/x86/insts/microldstop.cc b/src/arch/x86/insts/microldstop.cc
index 0d603d9..01f06fd 100644
--- a/src/arch/x86/insts/microldstop.cc
+++ b/src/arch/x86/insts/microldstop.cc
@@ -48,6 +48,33 @@
 namespace X86ISA
 {

+namespace
+{
+Fault
+generateFault(Addr offset, SegmentRegIndex segment,
+        Addr base, Addr size, bool is_load, ThreadContext *tc)
+{
+    if (segment == SEGMENT_REG_SS || segment == SEGMENT_REG_HS)
+        return std::make_shared<StackFault>(0);
+    if (segment == SYS_SEGMENT_REG_TR)
+        return std::make_shared<InvalidTSS>(0);
+    if (segment == SEGMENT_REG_TSG) {
+        // Guess what the selector was.
+        uint16_t selector = offset;
+        return std::make_shared<GeneralProtection>(selector);
+    }
+    if (segment == SEGMENT_REG_TSL) {
+        // Guess what the selector was.
+        uint16_t selector = offset | 0x4;
+        return std::make_shared<GeneralProtection>(selector);
+    }
+
+    // Otherwise just use a #GP.
+    return std::make_shared<GeneralProtection>(0);
+}
+
+} // anonymous namespace
+
 Fault
 MemOp::segmentationCheck(Addr offset, SegmentRegIndex segment,
         Addr base, Addr size, bool is_load, ThreadContext *tc) const
@@ -58,7 +85,7 @@
     // Check for an unusable segment.
     if (attr.unusable) {
         DPRINTF(TLB, "Unusable segment.\n");
-        return std::make_shared<GeneralProtection>(0);
+        return generateFault(offset, segment, base, size, is_load, tc);
     }

     // Check read/write permissions.
@@ -66,11 +93,11 @@
     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);
+            return generateFault(offset, segment, base, size, is_load, tc);
         }
         if (!attr.readable && is_load) {
             DPRINTF(TLB, "Tried to read from unreadble segment.\n");
-            return std::make_shared<GeneralProtection>(0);
+            return generateFault(offset, segment, base, size, is_load, tc);
         }
         // Only these segments can be expand down.
         expand_down = attr.expandDown;
@@ -82,12 +109,12 @@
         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);
+            return generateFault(offset, segment, base, size, is_load, tc);
     } 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);
+            return generateFault(offset, segment, base, size, is_load, tc);
         }
     }


--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/57198
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: Ia2f5ffd53300abdd141ee32698a2099ad2acdf78
Gerrit-Change-Number: 57198
Gerrit-PatchSet: 1
Gerrit-Owner: Gabe Black <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to