Here, try this patch.
Gabe
Gabriel Michael Black wrote:
> That one I think should be fixed in the decoder. If the mode isn't
> valid, an Uknown(machInst) should be returned rather than the Srs
> instruction. I'll try to get the previous patch cleaned up and
> committed and a patch for this to you this evening. I think it would
> be a worthwhile but time consuming and tedious exercise to make sure
> the bad instruction encodings (like in this case) actually cause
> undefined exceptions rather than blissfully plowing ahead.
>
> Gabe
>
> Quoting Min Kyu Jeong <[email protected]>:
>
>> I tried it, and it solved the particular segfault problem. Thanks!
>>
>> However, a new problem came up further down the execution stream. It
>> is also
>> from a garbage instruction. Invalid register mode is extracted from the
>> garbage binary and used in intRegInMode(). Later during the rename
>> stage,
>> flattenIntIndex() extracts this mode out and found out it's invalid and
>> panics.
>>
>> decoder.cc
>> if (val == 0x4) {
>> *const uint32_t mode =
>> bits(machInst, 4,
>> 0);*
>> switch (bits(machInst, 24, 21)) {
>> case 0x2:
>> return new
>> SRS_STORE_IMM_AN_PY_SN_UN_WN_SZ8(machInst, *mode*,
>> SrsOp::DecrementAfter,
>> false);
>>
>>
>> SRS_STORE_IMM_AY_PY_SN_UN_WY_SZ8::SRS_STORE_IMM_AY_PY_SN_UN_WY_SZ8(ExtMachInst
>>
>> machInst,
>> uint32_t _regMode, int _mode, bool _wb)
>> : SrsOp("srs", machInst, MemWriteOp,
>> (OperatingMode)*_regMode*, (AddrMode)_mode, _wb)
>> {
>>
>> _srcRegIdx[0] = MISCREG_CPSR + Ctrl_Base_DepTag;
>> _srcRegIdx[1] = (condCode == COND_AL || condCode == COND_UC) ?
>> INTREG_ZERO : INTREG_CONDCODES;
>> * **_srcRegIdx[2] = intRegInMode((OperatingMode)regMode, INTREG_SP);*
>>
>>
>>
>> int
>> flattenIntIndex(int reg)
>> {
>> assert(reg >= 0);
>> if (reg < NUM_ARCH_INTREGS) {
>> return intRegMap[reg];
>> } else if (reg < NUM_INTREGS) {
>> return reg;
>> } else {
>> int mode = reg / intRegsPerMode;
>> reg = reg % intRegsPerMode;
>> switch (mode) {
>> case MODE_USER:
>> case MODE_SYSTEM:
>> return INTREG_USR(reg);
>> case MODE_FIQ:
>> return INTREG_FIQ(reg);
>> case MODE_IRQ:
>> return INTREG_IRQ(reg);
>> case MODE_SVC:
>> return INTREG_SVC(reg);
>> case MODE_MON:
>> return INTREG_MON(reg);
>> case MODE_ABORT:
>> return INTREG_ABT(reg);
>> case MODE_UNDEFINED:
>> return INTREG_UND(reg);
>> * default:*
>> * panic("Flattening into an unknown mode.\n");*
>> }
>> }
>>
>>
>>
>> On Mon, Jul 12, 2010 at 10:04 PM, Min Kyu Jeong <[email protected]>
>> wrote:
>>
>>> I will try it tomorrow and let you know.
>>>
>>>
>>> On Mon, Jul 12, 2010 at 6:51 PM, Gabriel Michael Black <
>>> [email protected]> wrote:
>>>
>>>> Did that patch fix it?
>>>>
>>>> Gabe
>>>>
>>>>
>>>> Quoting Gabe Black <[email protected]>:
>>>>
>>>> Here's more or less what's going on as far as the register index. The
>>>>> load microop needs to store into register 1, and it needs to be
>>>>> sure it
>>>>> stores into the version visible from the "user" mode. It does that by
>>>>> applying the intRegInMode function which shifts the register index
>>>>> 1 by
>>>>> MODE_USER * the number of integer registers. Later, the
>>>>> flattenIntIndex
>>>>> function is called to unambiguously figure out what a particular
>>>>> register index goes with given the current values of various ISA
>>>>> state
>>>>> (specifically the CPU mode for ARM) or other conditions flagged by
>>>>> putting the register index in a particular range. You can see in the
>>>>> "else" clause that the mode is re-extracted from the index using an
>>>>> integer division and the offset of 1 is extracted using a mod.
>>>>> This is
>>>>> then translated into the actual register visible from that mode with
>>>>> that index. From this point forward, the CPU can pretend the integer
>>>>> register file is one big flat contiguous space and totally ignore the
>>>>> ISAs register indexing semantics.
>>>>>
>>>>> One additional mechanism is at work when actually storing the
>>>>> register
>>>>> index in the StaticInst object. There are really three different
>>>>> types
>>>>> of register indices, integer, float and misc (which could have
>>>>> also been
>>>>> called "other" or "control"), but these are all stored in the same
>>>>> array
>>>>> with no flag to distinguish them. To be able to tell them apart
>>>>> later,
>>>>> an offset is added to them so that the integer indexes are all
>>>>> from 0 to
>>>>> FP_Base_DepTag - 1, the floating point registers are all from
>>>>> FP_Base_DepTag to Ctrl_Base_DepTag - 1 (inconsistently named for
>>>>> historical reasons), and the misc registers are from Ctrl_Base_DepTag
>>>>> and up. This is a fairly fragile system since if a, say, integer
>>>>> index
>>>>> is large enough, it might spill into the fp or misc range and be
>>>>> misidentified later. I'd like to replace this system with
>>>>> multidimensional indices that track the type explicitly, but I
>>>>> won't get
>>>>> into the specifics here.
>>>>>
>>>>> A flaw in the combination of these two systems is why this particular
>>>>> index isn't being handled correctly. The FP_Base_DepTag is being
>>>>> set to
>>>>> NumIntRegs, but in reality because of the intRegInMode function,
>>>>> integer
>>>>> indices can be a lot larger than that. When this particular index is
>>>>> being processed, 1->577 is even bigger than Ctrl_Base_DepTag, so
>>>>> it gets
>>>>> interpreted as a misc index. These aren't renamed and are passed
>>>>> directly to the ISA object to interpret/use as array indexes. I think
>>>>> the reason this works fine on the simple CPUs is that they always
>>>>> know
>>>>> explicitly what type of register something is, so when they go to
>>>>> undo
>>>>> the DepTag offset, they just pull out the right one automatically. O3
>>>>> isn't able to do that. I have a patch attached that simply multiplies
>>>>> the FP_Base_DepTag value by 32 since 31 is the largest MODE_*
>>>>> constant.
>>>>> In a more final version I'd want to do something that used the real
>>>>> upper limit instead of just knowing multiplying by 32 gives the right
>>>>> answer.
>>>>>
>>>>> I'm not completely convinced this will solve your segfault,
>>>>> though. It
>>>>> looks like that is caused by a bad DynInst pointer ending up in
>>>>> one of
>>>>> the TimeBuffer structures used to pass values between stages. When
>>>>> that
>>>>> goes out of scope and attempts to reference count itself, the junk
>>>>> pointer is dereferenced and causes a segfault. You can tell the
>>>>> pointer
>>>>> is bad because in 64 bit x86, pointers have to be canonical, or in
>>>>> other
>>>>> words be sign extended beyond the largest implemented virtual address
>>>>> bit. Anything starting with an 8 as the MSB is pretty much
>>>>> guaranteed to
>>>>> be bogus. It could still be, however, that writing beyond the end
>>>>> of a
>>>>> register file trampled on that structure and corrupted the pointer.
>>>>> There are asserts in the ISA object's functions that should prevent
>>>>> that, but those would be disabled if you were running with m5.fast
>>>>> (not
>>>>> recommended unless you're 100% certain everything is working).
>>>>>
>>>>> Gabe
>>>>>
>>>>> Min Kyu Jeong wrote:
>>>>>
>>>>>> The following is the excerpt from the disassembly.
>>>>>>
>>>>>> 117c: e321f013 msr CPSR_c, #19 ; 0x13
>>>>>> 1180: e24fd08c sub sp, pc, #140 ; 0x8c
>>>>>> 1184: e321f011 msr CPSR_c, #17 ; 0x11
>>>>>> 1188: e24fd094 sub sp, pc, #148 ; 0x94
>>>>>> 118c: e321f012 msr CPSR_c, #18 ; 0x12
>>>>>> 1190: e24fd09c sub sp, pc, #156 ; 0x9c
>>>>>> 1194: e321f01b msr CPSR_c, #27 ; 0x1b
>>>>>> 1198: e24fd0a4 sub sp, pc, #164 ; 0xa4
>>>>>> 119c: e321f017 msr CPSR_c, #23 ; 0x17
>>>>>> 11a0: e24fd0ac sub sp, pc, #172 ; 0xac
>>>>>> 11a4: e321f01f msr CPSR_c, #31 ; 0x1f
>>>>>> 11a8: e24fd0b4 sub sp, pc, #180 ; 0xb4
>>>>>> 11ac: e321f013 msr CPSR_c, #19 ; 0x13
>>>>>> 11b0: ea000002 b 11c0 <skipLabel_00000002>
>>>>>>
>>>>>> 000011b4 <LabStr_00000002>:
>>>>>> 11b4: 5f444441 69736162 00315f63 ADD_basic_1.
>>>>>>
>>>>>>
>>>>>> After x11b0, branch is predicated fall-through and the string
>>>>>> label is
>>>>>> fetched. The particular bytes that causes the mess is of address
>>>>>> 11b8,
>>>>>> so I think it is the second 4B chunk of the label: x69736162
>>>>>>
>>>>>> The following is the relevant part of trace from the run. There are
>>>>>> some additional prints that I added.
>>>>>>
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b4 (0)
>>>>>> created
>>>>>> [sn:1585]
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Instruction is: svcpl
>>>>>> 17680000: global: MicroLdrUop, regIdx : 577
>>>>>> 17680000: global: MicroLdrUop, regIdx : 581
>>>>>> 17680000: global: MicroLdrUop, regIdx : 582
>>>>>> 17680000: global: MicroLdrUop, regIdx : 584
>>>>>> 17680000: global: MicroLdrUop, regIdx : 589
>>>>>> 17680000: global: MicroLdrUop, regIdx : 590
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (0)
>>>>>> created
>>>>>> [sn:1586]
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Instruction is: addi_uopvs
>>>>>> r34, r3, #0
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (1)
>>>>>> created
>>>>>> [sn:1587]
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Instruction is: subi_uopvs
>>>>>> r3, r3, #24
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Done fetching, reached fetch
>>>>>> bandwidth for this cycle.
>>>>>> 17680000: system.cpu.fetch: [tid:0]: Setting PC to 0x0011b8.
>>>>>> ...
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (2)
>>>>>> created
>>>>>> [sn:1588]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction is: ldr_uopvs
>>>>>> XXX, [r34, #24]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (3)
>>>>>> created
>>>>>> [sn:1589]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction is: ldr_uopvs
>>>>>> XXX, [r34, #20]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (4)
>>>>>> created
>>>>>> [sn:1590]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction is: ldr_uopvs
>>>>>> XXX, [r34, #16]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (5)
>>>>>> created
>>>>>> [sn:1591]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction is: ldr_uopvs
>>>>>> XXX, [r34, #12]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (6)
>>>>>> created
>>>>>> [sn:1592]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction is: ldr_uopvs
>>>>>> XXX, [r34, #8]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction PC 0x11b8 (7)
>>>>>> created
>>>>>> [sn:1593]
>>>>>> 17690000: system.cpu.fetch: [tid:0]: Instruction is: ldr_uopvs
>>>>>> XXX, [r34, #4]
>>>>>> ...
>>>>>> 18440000: system.cpu.rename: [tid:0]: Processing instruction
>>>>>> [sn:1588]
>>>>>> with PC 0x11b8.
>>>>>> 18440000: system.cpu.rename: Adjusting reg index from 105 to 105.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Looking up arch reg 105, got
>>>>>> physical reg 512.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Register 512 is ready.
>>>>>> 18440000: global: [sn:1588] has 1 ready out of 4 sources. RTI 0)
>>>>>> 18440000: system.cpu.rename: Flattening index 35 to 35.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Looking up arch reg 35, got
>>>>>> physical reg 147.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Register 147 is ready.
>>>>>> 18440000: global: [sn:1588] has 2 ready out of 4 sources. RTI 0)
>>>>>> 18440000: system.cpu.rename: Flattening index 34 to 34.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Looking up arch reg 34, got
>>>>>> physical reg 72.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Register 72 is not ready.
>>>>>> 18440000: system.cpu.rename: Adjusting reg index from 577 to 577.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Looking up arch reg 577, got
>>>>>> physical reg 984.
>>>>>> 18440000: system.cpu.rename: [tid:0]: Register 984 is ready.
>>>>>> 18440000: global: [sn:1588] has 3 ready out of 4 sources. RTI 0)
>>>>>> 18440000: system.cpu.rename: Adjusting reg index from 577 to 577.
>>>>>> 18440000: global: Renamed misc reg 472
>>>>>> *18440000: global: Renamed reg 472 to physical reg 984 old
>>>>>> mapping was
>>>>>> 984*
>>>>>> *18440000: system.cpu.rename: [tid:0]: Renaming arch reg 577 to
>>>>>> physical reg 984.*
>>>>>> 18440000: system.cpu.rename: [tid:0]: Adding instruction to history
>>>>>> buffer (size=3), [sn:1588].
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Fri, Jul 9, 2010 at 4:23 PM, Gabriel Michael Black
>>>>>> <[email protected] <mailto:[email protected]>> wrote:
>>>>>>
>>>>>> Thanks for the extra info which should be very helpful. Can you
>>>>>> please tell us what the actual bytes are for the junk
>>>>>> instruction?
>>>>>>
>>>>>>
>>>>>> Gabe
>>>>>>
>>>>>> Quoting Min Kyu Jeong <[email protected]
>>>>>> <mailto:[email protected]
>>>>>> >>:
>>>>>>
>>>>>> I looked into this thing, but still don't fully understand
>>>>>> how
>>>>>> the
>>>>>> out-of-bound reg index causes segfault. Instead, I will just
>>>>>> describe what
>>>>>> is happening hoping someone would catch a clue from it.
>>>>>>
>>>>>> The register index that goes out of bound is the
>>>>>> architectural
>>>>>> register
>>>>>> index, stored in StaticInst class _destRegIdx[0]. The
>>>>>> particular StaticInst
>>>>>> I am getting this from is MicroLdrUop. In the constructor of
>>>>>> the MacroMemOp
>>>>>> (This invalid garbage instruction from mispredicted path is
>>>>>> decoded as
>>>>>> LdmStm), MicroLdrUop instances are generated. The destination
>>>>>> register
>>>>>> indices for uops are generated from the bit vector, and there
>>>>>> is this bit of
>>>>>> code
>>>>>>
>>>>>> if (force_user) {
>>>>>> regIdx = instRegInMode(MODE_USER, regIdx);
>>>>>> }
>>>>>>
>>>>>> that changes regIdx from 1 to 577. This is stored in
>>>>>> _destRegIdx[0] variable
>>>>>> of the MicroLdrUop StaticInst. During renaming, 577 is
>>>>>> renamed
>>>>>> to 984 = 577
>>>>>> - numLogicalRegs + numPhysicalRegs
>>>>>>
>>>>>> This instRegInMode() is what I found suspicous, since the reg
>>>>>> window is
>>>>>> handled by ArmISA::flattenIntIndex() call.
>>>>>>
>>>>>> Anyways, the the simulation segfaults during advance()
>>>>>> function call of the
>>>>>> timebuffer at the end of the NEXT tick. The following is the
>>>>>> call stack.
>>>>>>
>>>>>>
>>>>>> #0 0x000000000040a2fa in RefCounted::decref
>>>>>> (this=0x8d4810708d48c84d) at
>>>>>> build/ARM_FS/base/refcnt.hh:51
>>>>>> #1 0x0000000000761daa in
>>>>>> RefCountingPtr<BaseO3DynInst<O3CPUImpl> >::del
>>>>>> (this=0x9cd200) at build/ARM_FS/base/refcnt.hh:69
>>>>>> #2 0x0000000000761dc1 in ~RefCountingPtr (this=0x9cd200) at
>>>>>> build/ARM_FS/base/refcnt.hh:85
>>>>>> #3 0x000000000077ebf9 in ~commitComm (this=0x9cd1a8) at
>>>>>> build/ARM_FS/cpu/o3/comm.hh:153
>>>>>> #4 0x000000000077ec49 in ~TimeBufStruct (this=0x9ccec8) at
>>>>>> build/ARM_FS/cpu/o3/comm.hh:110
>>>>>> #5 0x00000000007884c4 in TimeBuffer<TimeBufStruct<O3CPUImpl>
>>>>>> >::advance
>>>>>> (this=0x1991038) at build/ARM_FS/base/timebuf.hh:187
>>>>>> #6 0x0000000000798c31 in FullO3CPU<O3CPUImpl>::tick
>>>>>> (this=0x198d310) at
>>>>>> build/ARM_FS/cpu/o3/cpu.cc:523
>>>>>>
>>>>>> I made this segfault goes away by overriding the idx 577
>>>>>> to 0.
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> On Wed, Jun 30, 2010 at 2:17 PM, Gabriel Michael Black <
>>>>>> [email protected] <mailto:[email protected]>> wrote:
>>>>>>
>>>>>> Could you be more specific? There are a lot of register
>>>>>> related indexes and
>>>>>> I'm not sure exactly which ones you're talking about.
>>>>>> Could you walk through
>>>>>> what's happening from the illegal encoding, through the
>>>>>> decoder, through the
>>>>>> CPU and up to the segfault? I don't totally understand
>>>>>> the
>>>>>> mechanics of the
>>>>>> failure at the moment, but my gut reaction is that the
>>>>>> decoder should have
>>>>>> returned an "Unknown(machInst)" when the index was out of
>>>>>> bounds. I'm not
>>>>>> convinced that's what's happening, though.
>>>>>>
>>>>>>
>>>>>> Gabe
>>>>>>
>>>>>> Quoting Min Kyu Jeong <[email protected]
>>>>>> <mailto:[email protected]>>:
>>>>>>
>>>>>> I just found a case somewhat related to this. Not
>>>>>> exactly
>>>>>> an assertion,
>>>>>>
>>>>>> but
>>>>>> a segfault from the mispredicated path
>>>>>> (non)instructions.
>>>>>>
>>>>>> When the operand register index is out of the range,
>>>>>> the call to
>>>>>> timeBuffer.advance() right after the renaming of such
>>>>>> registers causes
>>>>>> segfault . I bypassed this problem by making that
>>>>>> out-of-bound register
>>>>>> index to ZERO registers during the renaming (more
>>>>>> particularly, during
>>>>>> index
>>>>>> flattening). I think raising a fault would be a
>>>>>> better
>>>>>> solution, but
>>>>>> holding
>>>>>> off from actually doing it. Any suggestion would be
>>>>>> appreciated.
>>>>>>
>>>>>> ps. is the [m5-dev] tag in the title added by the
>>>>>> mailing list, or should
>>>>>> I
>>>>>> add it myself?
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Min
>>>>>>
>>>>>> On Mon, Jun 14, 2010 at 3:52 PM, Gabriel Michael
>>>>>> Black <
>>>>>> [email protected] <mailto:[email protected]>>
>>>>>> wrote:
>>>>>>
>>>>>> It's important to distinguish between M5 making
>>>>>> sense, and the code it's
>>>>>>
>>>>>> executing making sense. We shouldn't (and I hope
>>>>>> don't) have any asserts
>>>>>> that check conditions controllable from the
>>>>>> simulated code since those
>>>>>> should generally just cause a fault and may, as
>>>>>> you point out, be
>>>>>> mispeculated. It's fine to check that M5 is
>>>>>> internally consistent,
>>>>>> though.
>>>>>> This is supposed to work in all the CPU models
>>>>>> and
>>>>>> as far as I know
>>>>>> generally does. M5's CPU models should, to the
>>>>>> first order, correctly do
>>>>>> whatever whacky, nonsensical things the
>>>>>> instruction memory tells it to do
>>>>>> without complaining. If you've found a case where
>>>>>> it doesn't (which has
>>>>>> happened before) please let us know so we can
>>>>>> fix it.
>>>>>>
>>>>>> Gabe
>>>>>>
>>>>>>
>>>>>> Quoting Min Kyu Jeong <[email protected]
>>>>>> <mailto:[email protected]>>:
>>>>>>
>>>>>> Is it possible that the speculatively fetched
>>>>>> instructions can cause
>>>>>>
>>>>>> programming assertions to fail? Until a
>>>>>> branch
>>>>>> is resolved, whatever
>>>>>> (even
>>>>>> non-instructions) in the predicted path could
>>>>>> be fetched and decoded.
>>>>>> Can't
>>>>>> assertions on instruction sanity fail for
>>>>>> those?
>>>>>>
>>>>>> I am trying to make O3 CPU model for ARM
>>>>>> working. In many cases the
>>>>>> first
>>>>>> instruction is a branch followed by a
>>>>>> interrupt vector table. I was
>>>>>> wondering if such cases exist for other CPU
>>>>>> models and if it is, handled
>>>>>> how.
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> Min
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> m5-dev mailing list
>>>>>> [email protected] <mailto:[email protected]>
>>>>>> http://m5sim.org/mailman/listinfo/m5-dev
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> m5-dev mailing list
>>>>>> [email protected] <mailto:[email protected]>
>>>>>> http://m5sim.org/mailman/listinfo/m5-dev
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> m5-dev mailing list
>>>>>> [email protected] <mailto:[email protected]>
>>>>>> http://m5sim.org/mailman/listinfo/m5-dev
>>>>>>
>>>>>>
>>>>>> ------------------------------------------------------------------------
>>>>>>
>>>>>>
>>>>>> _______________________________________________
>>>>>> m5-dev mailing list
>>>>>> [email protected]
>>>>>> http://m5sim.org/mailman/listinfo/m5-dev
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>>>> _______________________________________________
>>>> m5-dev mailing list
>>>> [email protected]
>>>> http://m5sim.org/mailman/listinfo/m5-dev
>>>>
>>>
>>>
>>
>
>
> _______________________________________________
> m5-dev mailing list
> [email protected]
> http://m5sim.org/mailman/listinfo/m5-dev
ARM: Make an SRS instruction with a bad mode cause an undefined instruction fault.
diff --git a/src/arch/arm/isa/formats/mem.isa b/src/arch/arm/isa/formats/mem.isa
--- a/src/arch/arm/isa/formats/mem.isa
+++ b/src/arch/arm/isa/formats/mem.isa
@@ -282,6 +282,8 @@
}
} else {
const uint32_t mode = bits(machInst, 4, 0);
+ if (badMode((OperatingMode)mode))
+ return new Unknown(machInst);
if (!add && !wb) {
return new %(srs)s(machInst, mode,
SrsOp::DecrementBefore, wb);
diff --git a/src/arch/arm/isa/formats/uncond.isa b/src/arch/arm/isa/formats/uncond.isa
--- a/src/arch/arm/isa/formats/uncond.isa
+++ b/src/arch/arm/isa/formats/uncond.isa
@@ -166,6 +166,8 @@
const uint32_t val = ((machInst >> 20) & 0x5);
if (val == 0x4) {
const uint32_t mode = bits(machInst, 4, 0);
+ if (badMode((OperatingMode)mode))
+ return new Unknown(machInst);
switch (bits(machInst, 24, 21)) {
case 0x2:
return new %(srs)s(machInst, mode,
_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev