Disable L1 and L2 CPU caches on Linux

This is inspired by me wanting to check if my code is affected (helped) heavily by CPU cache. A little bit research landed me on the following post. https://www.linuxquestions.org/questions/linux-kernel-70/disabling-cpu-caches-936077/

According to the author, disableCache.c looks like this

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int disableCache_init(void)
{
        printk(KERN_ALERT "Disabling L1 and L2 caches.\n");
        __asm__(".intel_syntax noprefix\n\t"
                "mov    eax,cr0\n\t"
                "or     eax,(1 << 30)\n\t"
                "mov    cr0,eax\n\t"
                "wbinvd\n\t"
                ".att_syntax noprefix\n\t"
        : : : "eax" );
        return 0;
}
static void disableCache_exit(void)
{
        printk(KERN_ALERT "Enabling L1 and L2 caches.\n");
        __asm__(".intel_syntax noprefix\n\t"
                "mov    eax,cr0\n\t"
                "and     eax,~(1 << 30)\n\t"
                "mov    cr0,eax\n\t"
                "wbinvd\n\t"
                ".att_syntax noprefix\n\t"
        : : : "eax" );
}
module_init(disableCache_init);
module_exit(disableCache_exit);

Makefile looks like this

EXTRA_CFLAGS = -m32
obj-m += disableCache.o

all:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

Very unfortunately this code cannot be compiled on my 64 bit system. To make this compatible to my system, “EXTRA_CFLAGS = -m32” needs to be removed from the Makefile.
Also, assembly instructions need be to altered a little bit. Luckily, the cache disabling control bit on cr0 still sits on the 30th bit. The code is gonna be like this after change.

#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int disableCache_init(void)
{
        printk(KERN_ALERT "Disabling L1 and L2 caches.\n");
        __asm__(".intel_syntax noprefix\n\t"
                "mov    rax,cr0\n\t"
                "or     rax,(1 << 30)\n\t"
                "mov    cr0,rax\n\t"
                "wbinvd\n\t"
                ".att_syntax noprefix\n\t"
        : : : "eax" );
        return 0;
}
static void disableCache_exit(void)
{
        printk(KERN_ALERT "Enabling L1 and L2 caches.\n");
        __asm__(".intel_syntax noprefix\n\t"
                "mov    rax,cr0\n\t"
                "and     rax,~(1 << 30)\n\t"
                "mov    cr0,rax\n\t"
                "wbinvd\n\t"
                ".att_syntax noprefix\n\t"
        : : : "eax" );
}
module_init(disableCache_init);
module_exit(disableCache_exit);

After a successful “make all” to compile, and “sudo insmod ./disableCache.ko”, the module is happily loaded into the kernel. Almost instantly you feel UNBELIEVABLE glitches on your computer which now feels like a 1980’s machine. Even the mouse cursor cannot sustain continuous move on the screen. This tells you everything is successful!

P.S. Almost forgot to mention how the cache affected my code’s performance. Sadly, not apparent. Even sadder, a few minutes later the computer became completely not operatable and I hit the restart button…

Leave a Reply

Your email address will not be published. Required fields are marked *