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

Change subject: arch-x86: Add some missing checks to STI and CLI.
......................................................................

arch-x86: Add some missing checks to STI and CLI.

Also make sure those instructions won't truncate the flags register.

Change-Id: Id55a4454480cd20ca462c08b93043254a9962dfe
---
M src/arch/x86/isa/decoder/one_byte_opcodes.isa
M src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py
2 files changed, 123 insertions(+), 21 deletions(-)



diff --git a/src/arch/x86/isa/decoder/one_byte_opcodes.isa b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
index 40beeb7..6dc9311 100644
--- a/src/arch/x86/isa/decoder/one_byte_opcodes.isa
+++ b/src/arch/x86/isa/decoder/one_byte_opcodes.isa
@@ -611,10 +611,12 @@
             0x1: STC();
             0x2: decode MODE_SUBMODE {
                 0x3: CLI_VIRT();
+                0x4: CLI_REAL();
                 default: CLI();
             }
             0x3: decode MODE_SUBMODE {
                 0x3: STI_VIRT();
+                0x4: STI_REAL();
                 default: STI();
             }
             0x4: CLD();
diff --git a/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py b/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py
index 63b37bb..2f2b2ce 100644
--- a/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py
+++ b/src/arch/x86/isa/insts/general_purpose/flags/set_and_clear.py
@@ -35,41 +35,89 @@

 microcode = '''
 def macroop CLD {
-    ruflags t1
+    ruflags t1, dataSize=8
     limm t2, "~((uint64_t)DFBit)", dataSize=8
-    and t1, t1, t2
-    wruflags t1, t0
+    and t1, t1, t2, dataSize=8
+    wruflags t1, t0, dataSize=8
 };

 def macroop STD {
-    ruflags t1
+    ruflags t1, dataSize=8
     limm t2, "DFBit", dataSize=8
-    or t1, t1, t2
-    wruflags t1, t0
+    or t1, t1, t2, dataSize=8
+    wruflags t1, t0, dataSize=8
 };

 def macroop CLC {
-    ruflags t1
-    andi t2, t1, "CFBit"
-    wruflags t1, t2
+    ruflags t1, dataSize=8
+    limm t2, "~((uint64_t)CFBit)", dataSize=8
+    and t1, t1, t2, dataSize=8
+    wruflags t1, t0, dataSize=8
 };

 def macroop STC {
-    ruflags t1
-    ori t1, t1, "CFBit"
-    wruflags t1, t0
+    ruflags t1, dataSize=8
+    ori t1, t1, "CFBit", dataSize=8
+    wruflags t1, t0, dataSize=8
 };

 def macroop CMC {
-    ruflags t1
-    wruflagsi t1, "CFBit"
+    ruflags t1, dataSize=8
+    wruflagsi t1, "CFBit", dataSize=8
 };

 def macroop STI {
-    rflags t1
+    rflags t1, dataSize=8
+
+    # Extract the IOPL.
+    srli t2, t1, 12, dataSize=8
+    andi t2, t1, 0x3, dataSize=8
+
+    # Find the CPL.
+    rdm5reg t3, dataSize=8
+    srli t3, t3, 4, dataSize=8
+    andi t3, t3, 0x3, dataSize=8
+
+    # if !(CPL > IOPL), jump down to setting IF.
+    sub t0, t2, t3, flags=(ECF,), dataSize=8
+    br label("setIf"), flags=(nCECF,)
+
+    # if (CR4.PVI == 1 && CPL == 3) {
+    # } else GP
+
+    # Check CR4.PVI
+    rdcr t4, cr4, dataSize=8
+    andi t0, t4, 0x1, flags=(CEZF,)
+    fault "std::make_shared<GeneralProtection>(0)", flags=(CEZF,)
+
+    # Check CPL.
+    andi t4, t3, 0x3, dataSize=8
+    xori t4, t4, 0x3, dataSize=8, flags=(CEZF,)
+    fault "std::make_shared<GeneralProtection>(0)", flags=(nCEZF,)
+
+    #     if (RFLAGS.VIP == 1)
+    #         EXCEPTION[#GP(0)]
+
+    # Check RFLAGS.VIP == 1
+    rflag t0, "VIPBit"
+    fault "std::make_shared<GeneralProtection>(0)", flags=(nCEZF,)
+
+    limm t2, "VIFBit", dataSize=8
+    br label("setBitInT2")
+
+setIf:
     limm t2, "IFBit", dataSize=8
-    or t1, t1, t2
-    wrflags t1, t0
+
+setBitInT2:
+    or t1, t1, t2, dataSize=8
+    wrflags t1, t0, dataSize=8
+};
+
+def macroop STI_REAL {
+    rflags t1, dataSize=8
+    limm t2, "IFBit", dataSize=8
+    or t1, t1, t2, dataSize=8
+    wrflags t1, t0, dataSize=8
 };

 def macroop STI_VIRT {
@@ -77,10 +125,51 @@
 };

 def macroop CLI {
-    rflags t1
-    limm t2, "~IFBit", dataSize=8
-    and t1, t1, t2
-    wrflags t1, t0
+    rflags t1, dataSize=8
+
+    # Extract the IOPL.
+    srli t2, t1, 12, dataSize=8
+    andi t2, t1, 0x3, dataSize=8
+
+    # Find the CPL.
+    rdm5reg t3, dataSize=8
+    srli t3, t3, 4, dataSize=8
+    andi t3, t3, 0x3, dataSize=8
+
+    # if !(CPL > IOPL), jump down to clearing IF.
+    sub t0, t2, t3, flags=(ECF,), dataSize=8
+    br label("maskIf"), flags=(nCECF,)
+
+    # if (CR4.PVI == 1 && CPL == 3) {
+    # } else GP
+
+    # Check CR4.PVI
+    rdcr t4, cr4, dataSize=8
+    andi t0, t4, 0x1, flags=(CEZF,)
+    fault "std::make_shared<GeneralProtection>(0)", flags=(CEZF,)
+
+    # Check CPL.
+    andi t4, t3, 0x3, dataSize=8
+    xori t4, t4, 0x3, dataSize=8, flags=(CEZF,)
+    fault "std::make_shared<GeneralProtection>(0)", flags=(nCEZF,)
+
+    # RFLAGS.VIF = 0
+    limm t2, "~((uint64_t)VIFBit)", dataSize=8
+    br label("maskWithT2")
+
+maskIf:
+    limm t2, "~((uint64_t)IFBit)", dataSize=8
+
+maskWithT2:
+    and t1, t1, t2, dataSize=8
+    wrflags t1, t0, dataSize=8
+};
+
+def macroop CLI_REAL {
+    rflags t1, dataSize=8
+    limm t2, "~((uint64_t)IFBit)", dataSize=8
+    and t1, t1, t2, dataSize=8
+    wrflags t1, t0, dataSize=8
 };

 def macroop CLI_VIRT {

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/55892
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: Id55a4454480cd20ca462c08b93043254a9962dfe
Gerrit-Change-Number: 55892
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