【发布时间】:2014-04-26 12:46:43
【问题描述】:
刷新缓存和 TLB 不起作用。以下内核模块接收 pid 并刷新具有该 id 的进程的 tlb/cache 条目。
我修改了 Linux 内核中的 handle_mm_fault() 函数,并在其中添加了一行打印出 pid 和导致页面 if(current->pid == target_process)....的地址。请参阅下面注释掉的行。但是,当我运行测试时,我没有看到由该进程引起的任何页面错误。我正在使用在 x86-64 位处理器上运行的 linux v3.11.6。
#include <linux/module.h>
#include <linux/mm.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
static int pid = -1;
module_param(pid, int, 0444);
void do_init(void) {
struct task_struct *task;
struct vm_area_struct *next_vma;
struct mm_struct *mm;
if (pid == -1)
return;
task = pid_task(find_vpid(pid), PIDTYPE_PID);
//target_process = pid;
if (!task) {
printk("Could not find the task struct for process id %d\n", pid);
return;
} else {
printk("Found the task <%s>\n", task->comm);
}
mm = task->mm;
if (!mm) {
printk("Could not find the mmap struct for process id %d\n", pid);
return;
}
printk("****Start_brk = %lu\n", mm->start_brk);
down_read(&mm->mmap_sem);
next_vma = find_vma(mm, mm->start_brk);
flush_cache_mm(mm);
flush_tlb_mm(mm);
up_read(&mm->mmap_sem);
}
int init_module(void) {
printk("Inserting the module!!!\n");
do_init();
return 0;
}
void cleanup_module(void) {
printk("Module removed!!!\n");
}
MODULE_LICENSE("GPL");
【问题讨论】:
-
TLB 可以在大多数通用架构(如 x86/x86_64)中由硬件重新填充,而不是通过页面错误。要获得页面错误,您应该更改 VMA 的标志(禁用读写)。
-
我该怎么做?我仍然想从 linux 内核(最好是一个模块)中做到这一点。
-
可以查看
mprotect系统调用(check its man)的实现:SYSCALL_DEFINE3(mprotect in mm/mprotect.c
标签: linux caching memory-management linux-kernel linux-device-driver