首页 文章

刷新缓存和TLB不起作用:flush_cache_mm(mm)/ flush_tlb_mm(mm)

提问于
浏览
0

刷新缓存和TLB不起作用 . 以下内核模块接收pid并使用该id刷新进程的tlb / cache条目 .

我修改了Linux内核中的 handle_mm_fault() 函数,并在其中添加了一行打印出pid和导致页面的地址 if(current->pid == target_process) ....请参阅下面注释掉的行 . 但是,当我运行测试时,我看不到该进程导致的任何页面错误 . 我正在使用在x86-64bit处理器上运行的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");

1 回答

  • 0

    刷新缓存和TLB不起作用 .

    实际上它可能会起作用,但TLB刷新的效果不会导致页面错误 . 刷新TLB后,来自目标进程的内存访问将导致TLB未命中和TLB重新填充 . 在大多数常见的x86 / x86_64和更常见的ARM中,Memory management unit将在硬件中重新填充TLB,而没有来自OS的活动代码 . 在重新填充中,MMU将加载页面表并执行它 . 在更具异国情调的SPARC或MIPS中,填写可以通过软件完成,但不能通过pagefault完成 .

    如果要在访问某些内存区域时强制页面错误,您可以(从用户空间)使用 mprotect syscall(check its man,只在标志中设置无读取(PROT_READ)和写入(PROT_WRITE)访问 .

    如果你想从内核空间做同样的事情,你可以检查 mprotectSYSCALL_DEFINE3(mprotect in mm/mprotect.c的实现并做同样的事情......

    unsigned long vm_flags = calc_vm_prot_bits(..flags..); // set flags
     down_write(&current->mm->mmap_sem); // lock mm
     vma = find_vma(current->mm, ..address..); // find needed VMA
     // check for errors...
     vma->vm_flags = newflags;
     vma->vm_page_prot = pgprot_modify(...) // update vm flags, or just call mprotect_fixup
     up_write(&current->mm->mmap_sem); // unlock mm
    

    ^^^代码未经过测试,无效且不应被任何人使用 .

相关问题