The K0 and K1 refer to a pair of registers that, according to the MIPS architecture, TLB handlers can use without saving or restoring. These registers thus appear to have unstable values from the POV of the interrupted user or kernel space program.
I know about this module because I once patched it to make it preserve the value of the K0 register. The K0 register then appeared to have a stable value in user space, and I was able to patch glibc to use refer to that register for the thread_self() context value. This saved a trip to the kernel, making pthread_<everthing> faster: mutexes, conditions, you name it. I patched GCC's thread local storage mechanism to also use this.
When looking for the trap handler assembly code, I could not find it in any .S file; then I discovered it's being synthesized at run-time by C code.
https://elixir.bootlin.com/linux/v4.20/source/arch/mips/mm/t...
the code is spread among various C functions. All the uasm_() and UASM_() calls assemble an instruction, e.g.:
The K0 and K1 refer to a pair of registers that, according to the MIPS architecture, TLB handlers can use without saving or restoring. These registers thus appear to have unstable values from the POV of the interrupted user or kernel space program.I know about this module because I once patched it to make it preserve the value of the K0 register. The K0 register then appeared to have a stable value in user space, and I was able to patch glibc to use refer to that register for the thread_self() context value. This saved a trip to the kernel, making pthread_<everthing> faster: mutexes, conditions, you name it. I patched GCC's thread local storage mechanism to also use this.
When looking for the trap handler assembly code, I could not find it in any .S file; then I discovered it's being synthesized at run-time by C code.