我的目标是将静态结构加载到 L1D 缓存中。之后使用这些结构成员执行一些操作,并在完成操作后运行invd以丢弃所有修改过的缓存行。所以基本上我想在缓存内创建一个安全的环境,这样在缓存内执行操作时,数据就不会泄漏到 RAM 中。
为此,我有一个内核模块。我在结构的成员上放置了一些固定值。然后我禁用抢占,禁用所有其他 CPU(当前 CPU 除外)的缓存,禁用中断,然后使用__builtin_prefetch()将我的静态结构加载到缓存中。之后,我用新值覆盖之前放置的固定值。之后,我执行invd(清除修改后的缓存行),然后为所有其他 CPU 启用缓存,启用中断并启用抢占。我的理由是,当我在原子模式下这样做时,INVD将删除所有更改。从原子模式回来后,我应该看到我之前放置的原始固定值。然而,这并没有发生。退出原子模式后,我可以看到用于覆盖先前放置的固定值的值。这是我的模块代码,
奇怪的是,重新启动PC后,我的输出发生了变化,我只是不明白为什么。现在,我根本没有看到任何变化。我正在发布完整的代码,包括@Peter Cordes 建议的一些修复,
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Author");
MODULE_DESCRIPTION("test INVD");
static struct CACHE_ENV{
unsigned char in[128];
unsigned char out[128];
}cacheEnv __attribute__((aligned(64)));
#define cacheEnvSize (sizeof(cacheEnv)/64)
//#define change "Hello"
unsigned char change[]="hello";
void disCache(void *p){
__asm__ __volatile__ (
"wbinvd\n"
"mov %%cr0, %%rax\n\t"
"or $(1<<30), %%eax\n\t"
"mov %%rax, %%cr0\n\t"
"wbinvd\n"
::
:"%rax"
);
printk(KERN_INFO "cpuid %d --> cache disable\n", …Run Code Online (Sandbox Code Playgroud)