diff --git a/coredump/criu_coredump/coredump.py b/coredump/criu_coredump/coredump.py index ae7a9eb87..c9d20bf67 100644 --- a/coredump/criu_coredump/coredump.py +++ b/coredump/criu_coredump/coredump.py @@ -56,6 +56,7 @@ status = { "VMA_AREA_AIORING": 1 << 13, "VMA_AREA_MEMFD": 1 << 14, "VMA_AREA_UPROBES": 1 << 17, + "VMA_AREA_NOT_ACCOUNTABLE": 1 << 18, "VMA_AREA_UNSUPP": 1 << 31 } diff --git a/criu/include/image.h b/criu/include/image.h index 30e32323d..d5c384c80 100644 --- a/criu/include/image.h +++ b/criu/include/image.h @@ -101,6 +101,7 @@ #define VMA_AREA_SHSTK (1 << 15) #define VMA_AREA_GUARD (1 << 16) #define VMA_AREA_UPROBES (1 << 17) +#define VMA_AREA_NOT_ACCOUNTABLE (1 << 18) #define VMA_EXT_PLUGIN (1 << 27) #define VMA_CLOSE (1 << 28) diff --git a/criu/mem.c b/criu/mem.c index 9e8740c07..2eb2580d4 100644 --- a/criu/mem.c +++ b/criu/mem.c @@ -951,15 +951,25 @@ static int premap_private_vma(struct pstree_item *t, struct vma_area *vma, void } /* - * All mappings here get PROT_WRITE regardless of whether we - * put any data into it or not, because this area will get - * mremap()-ed (branch below) so we MIGHT need to have WRITE - * bits there. Ideally we'd check for the whole COW-chain - * having any data in. + * For VMAs that have PROT_NONE and are not accountable + * (did not have the "ac" flag in /proc/pid/smaps), we + * can safely mmap them with PROT_NONE because we know + * we will never need to write any bits to them. */ - addr = mmap(*tgt_addr, size, vma->e->prot | PROT_WRITE, vma->e->flags | MAP_FIXED | flag, vma->e->fd, - vma->e->pgoff); - + if (vma->e->prot == PROT_NONE && vma_area_is(vma, VMA_AREA_NOT_ACCOUNTABLE)) { + addr = mmap(*tgt_addr, size, PROT_NONE, vma->e->flags | MAP_FIXED | flag, vma->e->fd, + vma->e->pgoff); + } else { + /* + * All mappings here get PROT_WRITE regardless of whether we + * put any data into it or not, because this area will get + * mremap()-ed (branch below) so we MIGHT need to have WRITE + * bits there. Ideally we'd check for the whole COW-chain + * having any data in. + */ + addr = mmap(*tgt_addr, size, vma->e->prot | PROT_WRITE, vma->e->flags | MAP_FIXED | flag, vma->e->fd, + vma->e->pgoff); + } if (addr == MAP_FAILED) { pr_perror("Unable to map ANON_VMA"); return -1; diff --git a/criu/proc_parse.c b/criu/proc_parse.c index 9605ff209..85ccbd0d9 100644 --- a/criu/proc_parse.c +++ b/criu/proc_parse.c @@ -123,10 +123,11 @@ bool handle_vma_plugin(int *fd, struct stat *stat) } static void __parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf, - int *shstk) + int *shstk, bool *no_ac) { char *tok; + *no_ac = true; if (!buf[0]) return; @@ -174,6 +175,9 @@ static void __parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf, if (_vmflag_match(tok, "ss")) *shstk = 1; + if (_vmflag_match(tok, "ac")) + *no_ac = false; + /* * Anything else is just ignored. */ @@ -185,21 +189,26 @@ static void __parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf, void parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf) { int shstk = 0; + bool no_ac = false; - __parse_vmflags(buf, flags, madv, io_pf, &shstk); + __parse_vmflags(buf, flags, madv, io_pf, &shstk, &no_ac); } static void parse_vma_vmflags(char *buf, struct vma_area *vma_area) { int io_pf = 0; int shstk = 0; + bool no_ac = false; __parse_vmflags(buf, &vma_area->e->flags, &vma_area->e->madv, &io_pf, - &shstk); + &shstk, &no_ac); if (shstk) vma_area->e->status |= VMA_AREA_SHSTK; + if (no_ac) + vma_area->e->status |= VMA_AREA_NOT_ACCOUNTABLE; + /* * vmsplice doesn't work for VM_IO and VM_PFNMAP mappings, the * only exception is VVAR area that mapped by the kernel as diff --git a/lib/pycriu/images/pb2dict.py b/lib/pycriu/images/pb2dict.py index 56f0e5d25..6c687aace 100644 --- a/lib/pycriu/images/pb2dict.py +++ b/lib/pycriu/images/pb2dict.py @@ -113,6 +113,7 @@ mmap_status_map = [ ('VMA_AREA_MEMFD', 1 << 14), ('VMA_AREA_SHSTK', 1 << 15), ('VMA_AREA_UPROBES', 1 << 17), + ('VMA_AREA_NOT_ACCOUNTABLE', 1 << 18), ('VMA_UNSUPP', 1 << 31), ]