arch-arm: AArch64 reg access HCR_EL2.E2H filter
authorAdrian Herrera <adrian.herrera@arm.com>
Thu, 7 Nov 2019 12:30:08 +0000 (12:30 +0000)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Tue, 4 Feb 2020 13:39:54 +0000 (13:39 +0000)
Some AArch64 system registers report UNDEFINED behaviours if accessed
from EL2 or EL3 in a non-EL2 Host enabled (HCR_EL2.E2H == 0) environment.
Examples of these are seen in the Generic Timer system registers,
namely CNTP_CTL_EL02 or CNTKCTL_EL12.
This patch provides an ISA filter for specifying the above condition.

Change-Id: I240f9afdb000faf5d3c9274ba12bd4cc41fe8604
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/24664
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/arm/isa.hh
src/arch/arm/isa/insts/data64.isa
src/arch/arm/miscregs.cc
src/arch/arm/miscregs.hh

index 7ffa682ef2bfe3f8427348bdaf1dc4010dd477f9..23f05ccafe036cacbc4ba80425946acf3cf01aee 100644 (file)
@@ -250,11 +250,26 @@ namespace ArmISA
                 privNonSecureRead(v);
                 return *this;
             }
+            chain hypE2HRead(bool v = true) const {
+                info[MISCREG_HYP_E2H_RD] = v;
+                return *this;
+            }
+            chain hypE2HWrite(bool v = true) const {
+                info[MISCREG_HYP_E2H_WR] = v;
+                return *this;
+            }
+            chain hypE2H(bool v = true) const {
+                hypE2HRead(v);
+                hypE2HWrite(v);
+                return *this;
+            }
             chain hypRead(bool v = true) const {
+                hypE2HRead(v);
                 info[MISCREG_HYP_RD] = v;
                 return *this;
             }
             chain hypWrite(bool v = true) const {
+                hypE2HWrite(v);
                 info[MISCREG_HYP_WR] = v;
                 return *this;
             }
@@ -263,19 +278,36 @@ namespace ArmISA
                 hypWrite(v);
                 return *this;
             }
+            chain monE2HRead(bool v = true) const {
+                info[MISCREG_MON_E2H_RD] = v;
+                return *this;
+            }
+            chain monE2HWrite(bool v = true) const {
+                info[MISCREG_MON_E2H_WR] = v;
+                return *this;
+            }
+            chain monE2H(bool v = true) const {
+                monE2HRead(v);
+                monE2HWrite(v);
+                return *this;
+            }
             chain monSecureRead(bool v = true) const {
+                monE2HRead(v);
                 info[MISCREG_MON_NS0_RD] = v;
                 return *this;
             }
             chain monSecureWrite(bool v = true) const {
+                monE2HWrite(v);
                 info[MISCREG_MON_NS0_WR] = v;
                 return *this;
             }
             chain monNonSecureRead(bool v = true) const {
+                monE2HRead(v);
                 info[MISCREG_MON_NS1_RD] = v;
                 return *this;
             }
             chain monNonSecureWrite(bool v = true) const {
+                monE2HWrite(v);
                 info[MISCREG_MON_NS1_WR] = v;
                 return *this;
             }
index 75d47925f801ba30c23aadec99b1f325518a2f8b..65ca024e97be1b6cc57ba0a31aa224c74f752890 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2011-2013, 2016-2019 ARM Limited
+// Copyright (c) 2011-2013, 2016-2020 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -313,7 +313,7 @@ let {{
 
     msrMrs64EnabledCheckCode = '''
         // Check for read/write access right
-        if (!can%sAArch64SysReg(flat_idx, Scr64, cpsr, xc->tcBase())) {
+        if (!can%sAArch64SysReg(flat_idx, Hcr64, Scr64, cpsr, xc->tcBase())) {
             if (flat_idx == MISCREG_DAIF ||
                 flat_idx == MISCREG_DC_ZVA_Xt ||
                 flat_idx == MISCREG_DC_CVAC_Xt ||
@@ -537,7 +537,7 @@ let {{
                                     mnemonic);
             }
 
-            if (!canWriteAArch64SysReg(misc_index,
+            if (!canWriteAArch64SysReg(misc_index, Hcr64,
                 Scr64, Cpsr, xc->tcBase())) {
 
                     return std::make_shared<UndefinedInstruction>(
index 787ba2fafa7153c90c5803cacfcae47feeacb4bf..87e130c2b56e12e84ba73027e3f414d92a79123e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013, 2015-2019 ARM Limited
+ * Copyright (c) 2010-2013, 2015-2020 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -1117,7 +1117,8 @@ unflattenMiscReg(int reg)
 }
 
 bool
-canReadAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
+canReadAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
+                     ThreadContext *tc)
 {
     // Check for SP_EL0 access while SPSEL == 0
     if ((reg == MISCREG_SP_EL0) && (tc->readMiscReg(MISCREG_SPSEL) == 0))
@@ -1136,6 +1137,7 @@ canReadAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
     }
 
     bool secure = ArmSystem::haveSecurity(tc) && !scr.ns;
+    bool el2_host = EL2Enabled(tc) && hcr.e2h;
 
     switch (currEL(cpsr)) {
       case EL0:
@@ -1145,9 +1147,11 @@ canReadAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
         return secure ? miscRegInfo[reg][MISCREG_PRI_S_RD] :
             miscRegInfo[reg][MISCREG_PRI_NS_RD];
       case EL2:
-        return miscRegInfo[reg][MISCREG_HYP_RD];
+        return el2_host ? miscRegInfo[reg][MISCREG_HYP_E2H_RD] :
+            miscRegInfo[reg][MISCREG_HYP_RD];
       case EL3:
-        return secure ? miscRegInfo[reg][MISCREG_MON_NS0_RD] :
+        return el2_host ? miscRegInfo[reg][MISCREG_MON_E2H_RD] :
+            secure ? miscRegInfo[reg][MISCREG_MON_NS0_RD] :
             miscRegInfo[reg][MISCREG_MON_NS1_RD];
       default:
         panic("Invalid exception level");
@@ -1155,7 +1159,8 @@ canReadAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
 }
 
 bool
-canWriteAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
+canWriteAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
+                      ThreadContext *tc)
 {
     // Check for SP_EL0 access while SPSEL == 0
     if ((reg == MISCREG_SP_EL0) && (tc->readMiscReg(MISCREG_SPSEL) == 0))
@@ -1180,6 +1185,7 @@ canWriteAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
     }
 
     bool secure = ArmSystem::haveSecurity(tc) && !scr.ns;
+    bool el2_host = EL2Enabled(tc) && hcr.e2h;
 
     switch (el) {
       case EL0:
@@ -1189,9 +1195,11 @@ canWriteAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr, ThreadContext *tc)
         return secure ? miscRegInfo[reg][MISCREG_PRI_S_WR] :
             miscRegInfo[reg][MISCREG_PRI_NS_WR];
       case EL2:
-        return miscRegInfo[reg][MISCREG_HYP_WR];
+        return el2_host ? miscRegInfo[reg][MISCREG_HYP_E2H_WR] :
+            miscRegInfo[reg][MISCREG_HYP_WR];
       case EL3:
-        return secure ? miscRegInfo[reg][MISCREG_MON_NS0_WR] :
+        return el2_host ? miscRegInfo[reg][MISCREG_MON_E2H_WR] :
+            secure ? miscRegInfo[reg][MISCREG_MON_NS0_WR] :
             miscRegInfo[reg][MISCREG_MON_NS1_WR];
       default:
         panic("Invalid exception level");
index 4f522f298b8ce05e563ba965fc669516e63c2577..49df42e51b72d30013bb0703070c59a25b02e34b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2019 ARM Limited
+ * Copyright (c) 2010-2020 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -971,12 +971,18 @@ namespace ArmISA
         // Hypervisor mode
         MISCREG_HYP_RD,
         MISCREG_HYP_WR,
+        // Hypervisor mode, HCR_EL2.E2H == 1
+        MISCREG_HYP_E2H_RD,
+        MISCREG_HYP_E2H_WR,
         // Monitor mode, SCR.NS == 0
         MISCREG_MON_NS0_RD,
         MISCREG_MON_NS0_WR,
         // Monitor mode, SCR.NS == 1
         MISCREG_MON_NS1_RD,
         MISCREG_MON_NS1_WR,
+        // Monitor mode, HCR_EL2.E2H == 1
+        MISCREG_MON_E2H_RD,
+        MISCREG_MON_E2H_WR,
 
         NUM_MISCREG_INFOS
     };
@@ -1927,11 +1933,11 @@ namespace ArmISA
                                              CPSR cpsr);
 
     // Checks read access permissions to AArch64 system registers
-    bool canReadAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr,
+    bool canReadAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
                               ThreadContext *tc);
 
     // Checks write access permissions to AArch64 system registers
-    bool canWriteAArch64SysReg(MiscRegIndex reg, SCR scr, CPSR cpsr,
+    bool canWriteAArch64SysReg(MiscRegIndex reg, HCR hcr, SCR scr, CPSR cpsr,
                                ThreadContext *tc);
 
     // Uses just the scr.ns bit to pre flatten the misc regs. This is useful