changeset cb3a401c45d7 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=cb3a401c45d7
description:
        arm: Correctly check FP/SIMD access permission in aarch32

        The current implementation of aarch32 FP/SIMD in gem5 assumes that EL1
        and higher are all 32-bit. This breaks interprocessing since an
        aarch64 EL1 uses different enable/disable bits. This change updates
        the permission checks to according to what is prescribed by the ARM
        ARM.

        Change-Id: Icdcef31b00644cfeebec00216b3993aa1de12b88
        Signed-off-by: Andreas Sandberg <[email protected]>
        Reviewed-by: Mitch Hayenga <[email protected]>
        Reviewed-by: Nathanael Premillieu <[email protected]>

diffstat:

 src/arch/arm/insts/static_inst.cc   |  134 +++++++++++++++++++++++++++++++-
 src/arch/arm/insts/static_inst.hh   |   43 +++++++++-
 src/arch/arm/isa/insts/fp.isa       |    2 +-
 src/arch/arm/isa/templates/neon.isa |   27 +----
 src/arch/arm/isa/templates/vfp.isa  |  154 ++++++++++-------------------------
 src/arch/arm/utility.cc             |   85 -------------------
 src/arch/arm/utility.hh             |   14 ---
 7 files changed, 227 insertions(+), 232 deletions(-)

diffs (truncated from 560 to 300 lines):

diff -r 060fc1591151 -r cb3a401c45d7 src/arch/arm/insts/static_inst.cc
--- a/src/arch/arm/insts/static_inst.cc Thu Jun 02 10:50:52 2016 +0100
+++ b/src/arch/arm/insts/static_inst.cc Thu Jun 02 13:38:30 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2014 ARM Limited
+ * Copyright (c) 2010-2014, 2016 ARM Limited
  * Copyright (c) 2013 Advanced Micro Devices, Inc.
  * All rights reserved
  *
@@ -595,4 +595,136 @@
     printMnemonic(ss);
     return ss.str();
 }
+
+
+Fault
+ArmStaticInst::advSIMDFPAccessTrap64(ExceptionLevel el) const
+{
+    switch (el) {
+      case EL1:
+        return std::make_shared<SupervisorTrap>(machInst, 0x1E00000,
+                                                EC_TRAPPED_SIMD_FP);
+      case EL2:
+        return std::make_shared<HypervisorTrap>(machInst, 0x1E00000,
+                                                EC_TRAPPED_SIMD_FP);
+      case EL3:
+        return std::make_shared<SecureMonitorTrap>(machInst, 0x1E00000,
+                                                   EC_TRAPPED_SIMD_FP);
+
+      default:
+        panic("Illegal EL in advSIMDFPAccessTrap64\n");
+    }
 }
+
+
+Fault
+ArmStaticInst::checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const
+{
+    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
+
+    if (ArmSystem::haveVirtualization(tc) && el <= EL2) {
+        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL2);
+        if (cptrEnCheck.tfp)
+            return advSIMDFPAccessTrap64(EL2);
+    }
+
+    if (ArmSystem::haveSecurity(tc)) {
+        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
+        if (cptrEnCheck.tfp)
+            return advSIMDFPAccessTrap64(EL3);
+    }
+
+    return NoFault;
+}
+
+Fault
+ArmStaticInst::checkFPAdvSIMDEnabled64(ThreadContext *tc,
+                                       CPSR cpsr, CPACR cpacr) const
+{
+    const ExceptionLevel el = (ExceptionLevel) (uint8_t)cpsr.el;
+    if ((el == EL0 && cpacr.fpen != 0x3) ||
+        (el == EL1 && !(cpacr.fpen & 0x1)))
+        return advSIMDFPAccessTrap64(EL1);
+
+    return checkFPAdvSIMDTrap64(tc, cpsr);
+}
+
+Fault
+ArmStaticInst::checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
+                                         CPSR cpsr, CPACR cpacr,
+                                         NSACR nsacr, FPEXC fpexc,
+                                         bool fpexc_check, bool advsimd) const
+{
+    const bool have_virtualization = ArmSystem::haveVirtualization(tc);
+    const bool have_security = ArmSystem::haveSecurity(tc);
+    const bool is_secure = inSecureState(tc);
+    const ExceptionLevel cur_el = opModeToEL(currOpMode(tc));
+
+    if (cur_el == EL0 && ELIs64(tc, EL1))
+        return checkFPAdvSIMDEnabled64(tc, cpsr, cpacr);
+
+    uint8_t cpacr_cp10 = cpacr.cp10;
+    bool cpacr_asedis = cpacr.asedis;
+
+    if (have_security && !ELIs64(tc, EL3) && !is_secure) {
+        if (nsacr.nsasedis)
+            cpacr_asedis = true;
+        if (nsacr.cp10 == 0)
+            cpacr_cp10 = 0;
+    }
+
+    if (cur_el != EL2) {
+        if (advsimd && cpacr_asedis)
+            return disabledFault();
+
+        if ((cur_el == EL0 && cpacr_cp10 != 0x3) ||
+            (cur_el != EL0 && !(cpacr_cp10 & 0x1)))
+            return disabledFault();
+    }
+
+    if (fpexc_check && !fpexc.en)
+        return disabledFault();
+
+    // -- aarch32/exceptions/traps/AArch32.CheckFPAdvSIMDTrap --
+
+    if (have_virtualization && !is_secure && ELIs64(tc, EL2))
+        return checkFPAdvSIMDTrap64(tc, cpsr);
+
+    if (have_virtualization && !is_secure) {
+        HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
+        bool hcptr_cp10 = hcptr.tcp10;
+        bool hcptr_tase = hcptr.tase;
+
+        if (have_security && !ELIs64(tc, EL3) && !is_secure) {
+            if (nsacr.nsasedis)
+                hcptr_tase = true;
+            if (nsacr.cp10)
+                hcptr_cp10 = true;
+        }
+
+        if ((advsimd && hcptr_tase) || hcptr_cp10) {
+            const uint32_t iss = advsimd ? (1 << 5) : 0xA;
+            if (cur_el == EL2) {
+                return std::make_shared<UndefinedInstruction>(
+                    machInst, iss,
+                    EC_TRAPPED_HCPTR, mnemonic);
+            } else {
+                return std::make_shared<HypervisorTrap>(
+                    machInst, iss,
+                    EC_TRAPPED_HCPTR);
+            }
+
+        }
+    }
+
+    if (have_security && ELIs64(tc, EL3)) {
+        HCPTR cptrEnCheck = tc->readMiscReg(MISCREG_CPTR_EL3);
+        if (cptrEnCheck.tfp)
+            return advSIMDFPAccessTrap64(EL3);
+    }
+
+    return NoFault;
+}
+
+
+}
diff -r 060fc1591151 -r cb3a401c45d7 src/arch/arm/insts/static_inst.hh
--- a/src/arch/arm/insts/static_inst.hh Thu Jun 02 10:50:52 2016 +0100
+++ b/src/arch/arm/insts/static_inst.hh Thu Jun 02 13:38:30 2016 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2013 ARM Limited
+ * Copyright (c) 2010-2013, 2016 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -363,6 +363,47 @@
                                                       mnemonic, true);
     }
 
+    /**
+     * Trap an access to Advanced SIMD or FP registers due to access
+     * control bits.
+     *
+     * See aarch64/exceptions/traps/AArch64.AdvSIMDFPAccessTrap in the
+     * ARM ARM psueodcode library.
+     *
+     * @param el Target EL for the trap
+     */
+    Fault advSIMDFPAccessTrap64(ExceptionLevel el) const;
+
+
+    /**
+     * Check an Advaned SIMD access against CPTR_EL2 and CPTR_EL3.
+     *
+     * See aarch64/exceptions/traps/AArch64.CheckFPAdvSIMDTrap in the
+     * ARM ARM psueodcode library.
+     */
+    Fault checkFPAdvSIMDTrap64(ThreadContext *tc, CPSR cpsr) const;
+
+    /**
+     * Check an Advaned SIMD access against CPACR_EL1, CPTR_EL2, and
+     * CPTR_EL3.
+     *
+     * See aarch64/exceptions/traps/AArch64.CheckFPAdvSIMDEnabled in the
+     * ARM ARM psueodcode library.
+     */
+    Fault checkFPAdvSIMDEnabled64(ThreadContext *tc,
+                                  CPSR cpsr, CPACR cpacr) const;
+
+    /**
+     * Check if a VFP/SIMD access from aarch32 should be allowed.
+     *
+     * See aarch32/exceptions/traps/AArch32.CheckAdvSIMDOrFPEnabled in the
+     * ARM ARM psueodcode library.
+     */
+    Fault checkAdvSIMDOrFPEnabled32(ThreadContext *tc,
+                                    CPSR cpsr, CPACR cpacr,
+                                    NSACR nsacr, FPEXC fpexc,
+                                    bool fpexc_check, bool advsimd) const;
+
   public:
     virtual void
     annotateFault(ArmFault *fault) {}
diff -r 060fc1591151 -r cb3a401c45d7 src/arch/arm/isa/insts/fp.isa
--- a/src/arch/arm/isa/insts/fp.isa     Thu Jun 02 10:50:52 2016 +0100
+++ b/src/arch/arm/isa/insts/fp.isa     Thu Jun 02 13:38:30 2016 +0100
@@ -260,7 +260,7 @@
     decoder_output += FpRegRegOpConstructor.subst(vmrsFpscrIop);
     exec_output += PredOpExecute.subst(vmrsFpscrIop);
 
-    vmrsApsrFpscrCode = vmrsApsrEnabledCheckCode + '''
+    vmrsApsrFpscrCode = vfpEnabledCheckCode + '''
         FPSCR fpscr = FpCondCodes;
         CondCodesNZ = (fpscr.n << 1) | fpscr.z;
         CondCodesC = fpscr.c;
diff -r 060fc1591151 -r cb3a401c45d7 src/arch/arm/isa/templates/neon.isa
--- a/src/arch/arm/isa/templates/neon.isa       Thu Jun 02 10:50:52 2016 +0100
+++ b/src/arch/arm/isa/templates/neon.isa       Thu Jun 02 13:38:30 2016 +0100
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2010-2012 ARM Limited
+// Copyright (c) 2010-2012, 2016 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -40,26 +40,11 @@
 let {{
     simdEnabledCheckCode = '''
     {
-        uint32_t issEnCheck;
-        bool trapEnCheck;
-        uint32_t seq;
-        if (!vfpNeonEnabled(seq, Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck,
-                            trapEnCheck, xc->tcBase(), Fpexc, true))
-            {return disabledFault();}
-        if (trapEnCheck) {
-            CPSR cpsrEnCheck = Cpsr;
-            if (cpsrEnCheck.mode == MODE_HYP) {
-                return std::make_shared<UndefinedInstruction>(
-                                                machInst, issEnCheck,
-                                                EC_TRAPPED_HCPTR);
-            } else {
-                if (!inSecureState(Scr, Cpsr)) {
-                    return std::make_shared<HypervisorTrap>(
-                                              machInst, issEnCheck,
-                                              EC_TRAPPED_HCPTR);
-                }
-            }
-        }
+        Fault fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
+                                                Cpsr, Cpacr, Nsacr, Fpexc,
+                                                true, true);
+        if (fault != NoFault)
+            return fault;
     }
     '''
 }};
diff -r 060fc1591151 -r cb3a401c45d7 src/arch/arm/isa/templates/vfp.isa
--- a/src/arch/arm/isa/templates/vfp.isa        Thu Jun 02 10:50:52 2016 +0100
+++ b/src/arch/arm/isa/templates/vfp.isa        Thu Jun 02 13:38:30 2016 +0100
@@ -1,6 +1,6 @@
 // -*- mode:c++ -*-
 
-// Copyright (c) 2010-2013 ARM Limited
+// Copyright (c) 2010-2013, 2016 ARM Limited
 // All rights reserved
 //
 // The license below extends only to copyright in the software and shall
@@ -39,125 +39,61 @@
 
 let {{
     vfpEnabledCheckCode = '''
-        uint32_t issEnCheck;
-        bool trapEnCheck;
-        uint32_t seq;
-        if (!vfpNeonEnabled(seq,Hcptr, Nsacr, Cpacr, Cpsr, issEnCheck,
-                            trapEnCheck, xc->tcBase(), Fpexc))
-            {return disabledFault();}
-        if (trapEnCheck) {
-            CPSR cpsrEnCheck = Cpsr;
-            if (cpsrEnCheck.mode == MODE_HYP) {
-                return std::make_shared<UndefinedInstruction>(
-                                                machInst, issEnCheck,
-                                                EC_TRAPPED_HCPTR, mnemonic);
-            } else {
-                if (!inSecureState(Scr, Cpsr)) {
-                    return std::make_shared<HypervisorTrap>(
-                                              machInst, issEnCheck,
-                                              EC_TRAPPED_HCPTR);
-                }
-            }
-        }
+    {
+        Fault fault = checkAdvSIMDOrFPEnabled32(xc->tcBase(),
+                                                Cpsr, Cpacr, Nsacr, Fpexc,
+                                                true, false);
+        if (fault != NoFault)
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to