diff options
author | Iru Cai <mytbk920423@gmail.com> | 2019-04-03 10:29:37 +0800 |
---|---|---|
committer | Iru Cai <mytbk920423@gmail.com> | 2019-05-31 15:59:17 +0800 |
commit | c0d7cca1d9895f1c3476ce9864584eb4fb2e6ee9 (patch) | |
tree | 3a1cb356c61cc6366d20c46353ed494d8e49ba92 | |
parent | cb5562bb15f32e9040eccb57271d86fddc614230 (diff) | |
download | gem5-c0d7cca1d9895f1c3476ce9864584eb4fb2e6ee9.tar.xz |
check loads using tainted registers, set USL dst as tainted
-rw-r--r-- | src/cpu/base_dyn_inst.hh | 13 | ||||
-rw-r--r-- | src/cpu/o3/cpu.cc | 7 | ||||
-rw-r--r-- | src/cpu/o3/cpu.hh | 1 | ||||
-rw-r--r-- | src/cpu/o3/lsq_unit_impl.hh | 15 | ||||
-rw-r--r-- | src/cpu/o3/regfile.hh | 18 |
5 files changed, 52 insertions, 2 deletions
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh index 6684a4765..3ddf25095 100644 --- a/src/cpu/base_dyn_inst.hh +++ b/src/cpu/base_dyn_inst.hh @@ -480,11 +480,22 @@ class BaseDynInst : public ExecContext, public RefCounted void taintDestRegs(void) { - for (auto dstreg: _destRegIdx) { + for (size_t i = 0; i < numDestRegs(); i++) { + auto dstreg = _destRegIdx[i]; cpu->setTaint(dstreg); } } + bool srcTainted(void) + { + bool result = false; + for (size_t i = 0; i < numSrcRegs(); i++) { + auto src = _srcRegIdx[i]; + result |= cpu->regTainted(src); + } + return result; + } + /** Renames a source logical register to the physical register which * has/will produce that logical register's result. * @todo: add in whether or not the source register is ready. diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 2566cf12a..ad4e6d549 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -1286,6 +1286,13 @@ FullO3CPU<Impl>::setTaint(PhysRegIdPtr phys_reg) } template <class Impl> +bool +FullO3CPU<Impl>::regTainted(PhysRegIdPtr phys_reg) +{ + return regFile.regTainted(phys_reg); +} + +template <class Impl> uint64_t FullO3CPU<Impl>::readIntReg(PhysRegIdPtr phys_reg) { diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 23e6f7434..131655ecd 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -401,6 +401,7 @@ class FullO3CPU : public BaseO3CPU /** taint a register */ void setTaint(PhysRegIdPtr phys_reg); + bool regTainted(PhysRegIdPtr phys_reg); uint64_t readIntReg(PhysRegIdPtr phys_reg); diff --git a/src/cpu/o3/lsq_unit_impl.hh b/src/cpu/o3/lsq_unit_impl.hh index 7462d4c84..14256e382 100644 --- a/src/cpu/o3/lsq_unit_impl.hh +++ b/src/cpu/o3/lsq_unit_impl.hh @@ -1043,6 +1043,7 @@ LSQUnit<Impl>::updateVisibleState() } inst->readyToExpose(true); }else { +#if 0 /* now an untainted USL can be safe */ if (inst->readyToExpose()){ DPRINTF(LSQUnit, "The load can not be validated " "[sn:%lli] PC %s\n", @@ -1050,7 +1051,19 @@ LSQUnit<Impl>::updateVisibleState() assert(0); //--loadsToVLD; } - inst->readyToExpose(false); +#endif + /* set taint for dst registers */ + inst->taintDestRegs(); + /* if the load depends on tainted registers, set + readyToExpose to false, otherwise set it to true + */ + if (inst->srcTainted()) { + DPRINTF(LSQUnit, "load inst [sn:%lli] %s not safe, set readyToExpose to false\n", inst->seqNum, inst->pcState()); + inst->readyToExpose(false); + } else { + DPRINTF(LSQUnit, "load inst [sn:%lli] %s is an unsafe speculated load, but source registers are not tainted.\n", inst->seqNum, inst->pcState()); + inst->readyToExpose(true); + } } inst->fenceDelay(false); } else { diff --git a/src/cpu/o3/regfile.hh b/src/cpu/o3/regfile.hh index 00b4ef045..4d54acc2f 100644 --- a/src/cpu/o3/regfile.hh +++ b/src/cpu/o3/regfile.hh @@ -199,10 +199,28 @@ class PhysRegFile miscTaintMap[idx] = true; break; default: + warn_once("taint for vector registers not supported yet\n"); break; } } + bool regTainted(PhysRegIdPtr phys_reg) { + RegIndex idx = phys_reg->index(); + switch (phys_reg->classValue()) { + case IntRegClass: + return intTaintMap[idx]; + case FloatRegClass: + return floatTaintMap[idx]; + case CCRegClass: + return ccTaintMap[idx]; + case MiscRegClass: + return miscTaintMap[idx]; + default: + warn_once("taint for vector registers not supported yet\n"); + return false; + } + } + /** Reads an integer register. */ uint64_t readIntReg(PhysRegIdPtr phys_reg) const { |