From 3384caf0fe7fb4c33b5393840f1f447965b7d9ac Mon Sep 17 00:00:00 2001 From: Nikos Nikoleris Date: Wed, 1 Mar 2017 20:55:15 +0000 Subject: arm: Don't panic when checking coprocessor read/write permissions Instructions that use the coprocessor interface check the current program status to determine whether the current context has the priviledges to read from/write to the coprocessor. Some modes allow the execution of coprocessor instructions, some others do not allow it, while some other modes are unexpected (e.g., executing an AArch32 instruction while being in an AArch64 mode). Previously we would unconditionally trigger a panic if we were in an unexpected mode. This change removes the panic and replaces it with an Undefined Instruction fault that triggers if and when a coprocessor instruction commits in an unexpected mode. This allows speculative coprocessor instructions from unexpected modes to execute but prevents them from gettting committed. Change-Id: If2776d5bae2471cdbaf76d0e1ae655f501bfbf01 Reviewed-by: Andreas Sandberg Reviewed-by: Rekai Gonzalez Alberquilla Reviewed-on: https://gem5-review.googlesource.com/2281 Maintainer: Andreas Sandberg Reviewed-by: Weiping Liao --- src/arch/arm/isa/insts/misc.isa | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'src/arch/arm/isa/insts') diff --git a/src/arch/arm/isa/insts/misc.isa b/src/arch/arm/isa/insts/misc.isa index 77c22e6ca..6d6e56b8f 100644 --- a/src/arch/arm/isa/insts/misc.isa +++ b/src/arch/arm/isa/insts/misc.isa @@ -1,6 +1,6 @@ // -*- mode:c++ -*- -// Copyright (c) 2010-2013 ARM Limited +// Copyright (c) 2010-2013,2017 ARM Limited // All rights reserved // // The license below extends only to copyright in the software and shall @@ -814,7 +814,9 @@ let {{ mrc14code = ''' MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(op1); - if (!canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase())) { + bool can_read, undefined; + std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); + if (!can_read || undefined) { return std::make_shared(machInst, false, mnemonic); } @@ -836,7 +838,9 @@ let {{ mcr14code = ''' MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(dest); - if (!canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase())) { + bool can_write, undefined; + std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); + if (undefined || !can_write) { return std::make_shared(machInst, false, mnemonic); } @@ -861,12 +865,13 @@ let {{ xc->tcBase()->flattenMiscIndex(preFlatOp1); bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, Hcptr, imm); - bool canRead = canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); - + bool can_read, undefined; + std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canRead && !(hypTrap && !inUserMode(Cpsr) && !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared(machInst, false, mnemonic); } @@ -891,12 +896,14 @@ let {{ xc->tcBase()->flattenMiscIndex(preFlatDest); bool hypTrap = mcrMrc15TrapToHyp(miscReg, Hcr, Cpsr, Scr, Hdcr, Hstr, Hcptr, imm); - bool canWrite = canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); + bool can_write, undefined; + std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canWrite & !(hypTrap & !inUserMode(Cpsr) & !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared(machInst, false, mnemonic); } @@ -920,12 +927,13 @@ let {{ MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(preFlatOp1); bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); - bool canRead = canReadCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); - + bool can_read, undefined; + std::tie(can_read, undefined) = canReadCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canRead && !(hypTrap && !inUserMode(Cpsr) && !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_read && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared(machInst, false, mnemonic); } @@ -949,12 +957,14 @@ let {{ MiscRegIndex miscReg = (MiscRegIndex) xc->tcBase()->flattenMiscIndex(preFlatDest); bool hypTrap = mcrrMrrc15TrapToHyp(miscReg, Cpsr, Scr, Hstr, Hcr, imm); - bool canWrite = canWriteCoprocReg(miscReg, Scr, Cpsr, xc->tcBase()); + bool can_write, undefined; + std::tie(can_write, undefined) = canWriteCoprocReg(miscReg, Scr, Cpsr); // if we're in non secure PL1 mode then we can trap regargless of whether // the register is accessable, in other modes we trap if only if the register // IS accessable. - if (!canWrite & !(hypTrap & !inUserMode(Cpsr) & !inSecureState(Scr, Cpsr))) { + if (undefined || (!can_write && !(hypTrap && !inUserMode(Cpsr) && + !inSecureState(Scr, Cpsr)))) { return std::make_shared(machInst, false, mnemonic); } -- cgit v1.2.3