# Linux Kernel Module Cheat

##### 3.10.1.1. CONFIG_PID_IN_CONTEXTIDR

https://stackoverflow.com/questions/54133479/accessing-logical-software-thread-id-in-gem5 on ARM the kernel can store an indication of PID in the CONTEXTIDR_EL1 register, making that much easier to observe from simulators.

In particular, gem5 prints that number out by default on `ExecAll` messages!

Let’s test it out with Linux kernel build variants + gem5 checkpoint restore and run a different script:

    ./build-linux --arch aarch64 --linux-build-id CONFIG_PID_IN_CONTEXTIDR --config 'CONFIG_PID_IN_CONTEXTIDR=y'
    # Checkpoint run.
    ./run --arch aarch64 --emulator gem5 --linux-build-id CONFIG_PID_IN_CONTEXTIDR --eval './gem5.sh'
    # Trace run.
    ./run \
      --arch aarch64 \
      --emulator gem5 \
      --gem5-readfile 'posix/getpid.out; posix/getpid.out' \
      --gem5-restore 1 \
      --linux-build-id CONFIG_PID_IN_CONTEXTIDR \
      --trace FmtFlag,ExecAll,-ExecSymbol \
    ;

The terminal runs both programs which output their PID to stdout:

    pid=44
    pid=45

By quickly inspecting the `trace.txt` file, we immediately notice that the `system.cpu: A<n>` part of the logs, which used to always be `system.cpu: A0`, now has a few different values! Nice!

We can briefly summarize those values by removing repetitions:

    cut -d' ' -f4 "$(./getvar --arch aarch64 --emulator gem5 trace_txt_file)" | uniq -c

gives:

      97227 A39
     147476 A38
     222052 A40
          1 terminal
    1117724 A40
      27529 A31
      43868 A40
      27487 A31
     138349 A40
      13781 A38
     231246 A40
      25536 A38
      28337 A40
     214799 A38
     963561 A41
      92603 A38
      27511 A31
     224384 A38
     564949 A42
     182360 A38
     729009 A43
       8398 A23
      20200 A10
     636848 A43
     187995 A44
      27529 A31
      70071 A44
      16981 A0
     623806 A44
      16981 A0
     139319 A44
      24487 A0
     174986 A44
      25420 A0
      89611 A44
      16981 A0
     183184 A44
      24728 A0
      89608 A44
      17226 A0
     899075 A44
      24974 A0
     250608 A44
     137700 A43
    1497997 A45
     227485 A43
     138147 A38
     482646 A46

I’m not smart enough to be able to deduce all of those IDs, but we can at least see that:

- A44 and A45 are there as expected from stdout!

- A39 must be the end of the execution of `m5 checkpoint`

- so we guess that A38 is the shell as it comes next

- the weird "terminal" line is `336969745500: system.terminal: attach terminal 0`

- which is the shell PID? I should have printed that as well :-)

- why are there so many other PIDs? This was supposed to be a silent system without daemons!

- A0 is presumably the kernel. However we see process switches without going into A0, so I’m not sure how, it appears to count kernel instructions as part of processes

- A46 has to be the `m5 exit` call

Or if you want to have some real fun, try: baremetal/arch/aarch64/contextidr_el1.c:

    ./run --arch aarch64 --emulator gem5 --baremetal baremetal/arch/aarch64/contextidr_el1.c --trace-insts-stdout

in which we directly set the register ourselves! Output excerpt:

      31500: system.cpu: A0 T0 : @main+12    :   ldr   x0, [sp, #12]      : MemRead :  D=0x0000000000000001 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsLoad)
      32000: system.cpu: A1 T0 : @main+16    :   msr   contextidr_el1, x0 : IntAlu :  D=0x0000000000000001  flags=(IsInteger|IsSerializeAfter|IsNonSpeculative)
      32500: system.cpu: A1 T0 : @main+20    :   ldr   x0, [sp, #12]      : MemRead :  D=0x0000000000000001 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsLoad)
      33000: system.cpu: A1 T0 : @main+24    :   add   w0, w0, #1         : IntAlu :  D=0x0000000000000002  flags=(IsInteger)
      33500: system.cpu: A1 T0 : @main+28    :   str   x0, [sp, #12]      : MemWrite :  D=0x0000000000000002 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsStore)
      34000: system.cpu: A1 T0 : @main+32    :   ldr   x0, [sp, #12]      : MemRead :  D=0x0000000000000002 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsLoad)
      34500: system.cpu: A1 T0 : @main+36    :   subs   w0, #9            : IntAlu :  D=0x0000000000000000  flags=(IsInteger)
      35000: system.cpu: A1 T0 : @main+40    :   b.le   <main+12>         : IntAlu :   flags=(IsControl|IsDirectControl|IsCondControl)
      35500: system.cpu: A1 T0 : @main+12    :   ldr   x0, [sp, #12]      : MemRead :  D=0x0000000000000002 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsLoad)
      36000: system.cpu: A2 T0 : @main+16    :   msr   contextidr_el1, x0 : IntAlu :  D=0x0000000000000002  flags=(IsInteger|IsSerializeAfter|IsNonSpeculative)
      36500: system.cpu: A2 T0 : @main+20    :   ldr   x0, [sp, #12]      : MemRead :  D=0x0000000000000002 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsLoad)
      37000: system.cpu: A2 T0 : @main+24    :   add   w0, w0, #1         : IntAlu :  D=0x0000000000000003  flags=(IsInteger)
      37500: system.cpu: A2 T0 : @main+28    :   str   x0, [sp, #12]      : MemWrite :  D=0x0000000000000003 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsStore)
      38000: system.cpu: A2 T0 : @main+32    :   ldr   x0, [sp, #12]      : MemRead :  D=0x0000000000000003 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsLoad)
      38500: system.cpu: A2 T0 : @main+36    :   subs   w0, #9            : IntAlu :  D=0x0000000000000000  flags=(IsInteger)
      39000: system.cpu: A2 T0 : @main+40    :   b.le   <main+12>         : IntAlu :   flags=(IsControl|IsDirectControl|IsCondControl)
      39500: system.cpu: A2 T0 : @main+12    :   ldr   x0, [sp, #12]      : MemRead :  D=0x0000000000000003 A=0x82fffffc  flags=(IsInteger|IsMemRef|IsLoad)
      40000: system.cpu: A3 T0 : @main+16    :   msr   contextidr_el1, x0 : IntAlu :  D=0x0000000000000003  flags=(IsInteger|IsSerializeAfter|IsNonSpeculative)

ARMv8 architecture reference manual db D13.2.27 "CONTEXTIDR_EL1, Context ID Register (EL1)" documents `CONTEXTIDR_EL1` as:

> Identifies the current Process Identifier.

> The value of the whole of this register is called the Context ID and is used by:

> - The debug logic, for Linked and Unlinked Context ID matching.

> - The trace logic, to identify the current process.

> The significance of this register is for debug and trace use only.

Tested on 145769fc387dc5ee63ec82e55e6b131d9c968538 + 1.