Projects STRLCPY criu Commits c9194500
🤬
  • mem: Don't do unneeded mprotects

    When a vma we restore doesn't have any pages in pagemaps there's
    not need to enforce PROT_WRITE bit on it.
    
    This only applies to non-premmaped vmas.
    
    Signed-off-by: Pavel Emelyanov <[email protected]>
    Signed-off-by: Andrei Vagin <[email protected]>
  • Loading...
  • Pavel Emelyanov committed 7 years ago
    c9194500
    1 parent 91388fce
  • ■ ■ ■ ■ ■
    criu/include/image.h
    skipped 88 lines
    89 89  #define VMA_AREA_VVAR (1 << 12)
    90 90  #define VMA_AREA_AIORING (1 << 13)
    91 91   
     92 +#define VMA_NO_PROT_WRITE (1 << 29)
    92 93  #define VMA_PREMMAPED (1 << 30)
    93 94  #define VMA_UNSUPP (1 << 31)
    94 95   
    skipped 77 lines
  • ■ ■ ■ ■ ■ ■
    criu/mem.c
    skipped 658 lines
    659 659   }
    660 660   }
    661 661   
     662 + /*
     663 + * All mappings here get PROT_WRITE regardless of whether we
     664 + * put any data into it or not, because this area will get
     665 + * mremap()-ed (branch below) so we MIGHT need to have WRITE
     666 + * bits there. Ideally we'd check for the whole COW-chain
     667 + * having any data in.
     668 + */
    662 669   addr = mmap(*tgt_addr, size,
    663 670   vma->e->prot | PROT_WRITE,
    664 671   vma->e->flags | MAP_FIXED | flag,
    skipped 90 lines
    755 762   if (!vma_area_is_private(vma, kdat.task_size))
    756 763   continue;
    757 764   
    758  - if (vma->pvma == NULL && pr->pieok && !vma_force_premap(vma, &vmas->h))
     765 + if (vma->pvma == NULL && pr->pieok && !vma_force_premap(vma, &vmas->h)) {
    759 766   /*
    760 767   * VMA in question is not shared with anyone. We'll
    761 768   * restore it with its contents in restorer.
     769 + * Now let's check whether we need to map it with
     770 + * PROT_WRITE or not.
    762 771   */
     772 + do {
     773 + if (pr->pe->vaddr + pr->pe->nr_pages * PAGE_SIZE <= vma->e->start)
     774 + continue;
     775 + if (pr->pe->vaddr > vma->e->end)
     776 + vma->e->status |= VMA_NO_PROT_WRITE;
     777 + break;
     778 + } while (pr->advance(pr));
     779 + 
    763 780   continue;
     781 + }
    764 782   
    765 783   ret = premap_private_vma(t, vma, at);
     784 + 
    766 785   if (ret < 0)
    767 786   break;
    768 787   }
    skipped 61 lines
    830 849   unsigned long len = min_t(unsigned long,
    831 850   (nr_pages - i) * PAGE_SIZE,
    832 851   vma->e->end - va);
     852 + 
     853 + if (vma->e->status & VMA_NO_PROT_WRITE) {
     854 + pr_debug("VMA 0x%"PRIx64":0x%"PRIx64" RO %#lx:%lu IO\n",
     855 + vma->e->start, vma->e->end, va, nr_pages);
     856 + BUG();
     857 + }
    833 858   
    834 859   if (pagemap_enqueue_iovec(pr, (void *)va, len, vma_io))
    835 860   return -1;
    skipped 277 lines
  • ■ ■ ■ ■ ■ ■
    criu/pie/restorer.c
    skipped 599 lines
    600 600   flags |= MAP_ANONYMOUS;
    601 601   
    602 602   /* A mapping of file with MAP_SHARED is up to date */
    603  - if (vma_entry->fd == -1 || !(vma_entry->flags & MAP_SHARED))
     603 + if ((vma_entry->fd == -1 || !(vma_entry->flags & MAP_SHARED)) &&
     604 + !(vma_entry->status & VMA_NO_PROT_WRITE))
    604 605   prot |= PROT_WRITE;
    605 606   
    606 607   pr_debug("\tmmap(%"PRIx64" -> %"PRIx64", %x %x %d)\n",
    skipped 654 lines
    1261 1262   if (!(vma_entry_is(vma_entry, VMA_AREA_REGULAR)))
    1262 1263   continue;
    1263 1264   
    1264  - if (vma_entry->prot & PROT_WRITE)
     1265 + if ((vma_entry->prot & PROT_WRITE) ||
     1266 + (vma_entry->status & VMA_NO_PROT_WRITE))
    1265 1267   continue;
    1266 1268   
    1267 1269   sys_mprotect(decode_pointer(vma_entry->start),
    skipped 324 lines
Please wait...
Page is in error, reload to recover