Memory management 如何为进程正在使用的内存中的所有页设置写保护?

Memory management 如何为进程正在使用的内存中的所有页设置写保护?,memory-management,linux-kernel,linux-device-driver,ubuntu-14.04,Memory Management,Linux Kernel,Linux Device Driver,Ubuntu 14.04,我想写一个函数,将写保护设置为虚拟内存中的所有页面。那一刻,我真的很喜欢: mm = task->mm; spin_lock(&mm->page_table_lock); for (vma = mm->mmap ; vma ; vma = vma->vm_next) { //loop for all vmas vma->vm_flags, (int) vma->vm_flags & VM_WRITE);

我想写一个函数,将写保护设置为虚拟内存中的所有页面。那一刻,我真的很喜欢:

mm = task->mm;
spin_lock(&mm->page_table_lock);

for (vma = mm->mmap ; vma ; vma = vma->vm_next) {   //loop for all vmas
  vma->vm_flags, (int) vma->vm_flags & VM_WRITE);                                           
  addr = vma->vm_start;
  vma->vm_flags &= ~VM_WRITE;       
  while(addr < vma->vm_end){ //loop for each page
     pgd = pgd_offset(mm, addr);
     if (pgd_none(*pgd)) { addr += PAGE_SIZE; continue; }       
     pud = pud_offset(pgd, addr);
     if (pud_none(*pud)) { addr += PAGE_SIZE; continue; }
     pmd = pmd_offset(pud, addr);
     if (pmd_none(*pmd)) { addr += PAGE_SIZE; continue; }
     pte = pte_offset_map(pmd, addr);
     if (pte_present(*pte)){
        *pte = pte_wrprotect(*pte);         
     } 
spin_unlock(&mm->page_table_lock);  
...........
mm=task->mm;
旋转锁定(&mm->页面锁定);
对于(vma=mm->mmap;vma;vma=vma->vm_next){//所有vma的循环
vma->vm_标志,(int)vma->vm_标志和vm_写入);
addr=vma->vm\u启动;
vma->vm_标志&=~vm_写入;
而(addrvm\u end){//每个页面循环
pgd=pgd_偏移量(mm,addr);
如果(pgd_none(*pgd)){addr+=PAGE_SIZE;continue;}
pud=pud_偏移量(pgd,addr);
如果(pud_none(*pud)){addr+=PAGE_SIZE;continue;}
pmd=pmd_偏移量(pud,addr);
如果(pmd_none(*pmd)){addr+=PAGE_SIZE;continue;}
pte=pte_偏移量_映射(pmd,addr);
如果(私人有限公司出席(*私人有限公司)){
*pte=pte_wrprotect(*pte);
} 
旋转锁定(&mm->页面锁定表锁定);
...........
我在Ubuntu 14.04(内核3.13)上工作。我的程序在内核级工作

但它只是将写保护设置为内存的一部分,并没有将写保护设置为进程正在使用的所有页面


有人可以帮我!

为什么你认为它不是所有的页面,而只是内存的一部分?因为在另一个进程中,我尝试写入这个进程内存的一些页面,其中一些页面出现了SIGSEGV。在一些页面中没有。你如何从进程B写入进程A的虚拟内存空间?@helloworld2008仅更改一个进程的映射(无论如何,在该代码中)。其他进程将有自己的虚拟映射(到相同的底层物理页)。因此,您对一个进程所做的任何VM更改都不会自动转换为另一个进程。@Gil Hamilton和Alan Au:从进程A中,我扫描所有正在运行的进程,并查找包含进程A的pid的进程。如果(t->pid==b\pid),则代码如下所示:
对于每个进程(t)task=t;
从task中,我得到了B进程的VM。