# Linux Kernel Module Cheat

### 24.15. gem5 simulate() limit reached

This error happens when the following instruction limits are reached:

    system.cpu[0].max_insts_all_threads
    system.cpu[0].max_insts_any_thread

If the parameter is not set, it defaults to `0`, which is magic and means the huge maximum value of `uint64_t`: 0xFFFFFFFFFFFFFFFF, which in practice would require a very long simulation if at least one CPU were live.

So this usually means all CPUs are in a sleep state, and no events are scheduled in the future, which usually indicates a bug in either gem5 or guest code, leading gem5 to blow up.

Still, fs.py at gem5 08c79a194d1a3430801c04f37d13216cc9ec1da3 does not exit with non-zero status due to this…​ and so we just parse it out just as for m5 fail…​

A trivial and very direct way to see message would be:

    ./run \
      --emulator gem5 \
      --userland userland/arch/x86_64/freestanding/linux/hello.S \
      --trace-insts-stdout \
      -- \
      --param 'system.cpu[0].max_insts_all_threads = 3' \
    ;

which as of lkmc 402059ed22432bb351d42eb10900e5a8e06aa623 runs only the first three instructions and quits!

    info: Entering event queue @ 0.  Starting simulation...
          0: system.cpu A0 T0 : @asm_main_after_prologue    : mov   rdi, 0x1
          0: system.cpu A0 T0 : @asm_main_after_prologue.0  :   MOV_R_I : limm   rax, 0x1 : IntAlu :  D=0x0000000000000001  flags=(IsInteger|IsMicroop|IsLastMicroop|IsFirstMicroop)
       1000: system.cpu A0 T0 : @asm_main_after_prologue+7    : mov rdi, 0x1
       1000: system.cpu A0 T0 : @asm_main_after_prologue+7.0  :   MOV_R_I : limm   rdi, 0x1 : IntAlu :  D=0x0000000000000001  flags=(IsInteger|IsMicroop|IsLastMicroop|IsFirstMicroop)
       2000: system.cpu A0 T0 : @asm_main_after_prologue+14    : lea        rsi, DS:[rip + 0x19]
       2000: system.cpu A0 T0 : @asm_main_after_prologue+14.0  :   LEA_R_P : rdip   t7, %ctrl153,  : IntAlu :  D=0x000000000040008d  flags=(IsInteger|IsMicroop|IsDelayedCommit|IsFirstMicroop)
       2500: system.cpu A0 T0 : @asm_main_after_prologue+14.1  :   LEA_R_P : lea   rsi, DS:[t7 + 0x19] : IntAlu :  D=0x00000000004000a6  flags=(IsInteger|IsMicroop|IsLastMicroop)
    Exiting @ tick 3000 because all threads reached the max instruction count

The exact same can be achieved with the older hardcoded `--maxinsts` mechanism present in `se.py` and `fs.py`:

    ./run \
      --emulator gem5 \
      --userland \userland/arch/x86_64/freestanding/linux/hello.S \
      --trace-insts-stdout \
      -- \
      --maxinsts 3
    ;

Other related fs.py options are:

- `--abs-max-tick`: set the maximum guest simulation time. The same scale as the ExecAll trace is used. E.g., for the above example with 3 instructions, the same trace would be achieved with a value of 3000.

The message also shows on User mode simulation deadlocks, for example in userland/posix/pthread_deadlock.c:

    ./run \
      --emulator gem5 \
      --userland userland/posix/pthread_deadlock.c \
      --cli-args 1 \
    ;

ends in:

    Exiting @ tick 18446744073709551615 because simulate() limit reached

where 18446744073709551615 is 0xFFFFFFFFFFFFFFFF in decimal.

And there is a Baremetal example at baremetal/arch/aarch64/no_bootloader/wfe_loop.S that dies on WFE:

    ./run \
      --arch aarch64 \
      --baremetal baremetal/arch/aarch64/no_bootloader/wfe_loop.S \
      --emulator gem5 \
      --trace-insts-stdout \
    ;

which gives:

    info: Entering event queue @ 0.  Starting simulation...
          0: system.cpu A0 T0 : @lkmc_start    :   wfe                      : IntAlu :  D=0x0000000000000000  flags=(IsSerializeAfter|IsNonSpeculative|IsQuiesce|IsUnverifiable)
       1000: system.cpu A0 T0 : @lkmc_start+4    :   b   <lkmc_start>         : IntAlu :   flags=(IsControl|IsDirectControl|IsUncondControl)
       1500: system.cpu A0 T0 : @lkmc_start    :   wfe                      : IntAlu :  D=0x0000000000000000  flags=(IsSerializeAfter|IsNonSpeculative|IsQuiesce|IsUnverifiable)
    Exiting @ tick 18446744073709551615 because simulate() limit reached

Other examples of the message:

- ARM baremetal multicore with a single CPU stays stopped at an WFE sleep instruction

- this sample bug on se.py multithreading: https://github.com/cirosantilli/linux-kernel-module-cheat/issues/81