Commit b325765c authored by Mike Rapoport's avatar Mike Rapoport Committed by Andrei Vagin

cr-check: use two features to verify userfaultfd availability

For the older kernels the implementation of userfaultfd would not include
non-cooperative mode. In such case it is still possible to use uffd and
enable lazy-pages, but if the restored process will change its virtual
memory layout during restore, we'll get memory corruption.

After this change 'criu check --feature uffd' will report success if the kernel
supports userfaultfd at all and 'criu check --feature uffd-noncoop' will
report success if the kernel supports non-cooperative userfaultfd.
Suggested-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarMike Rapoport <rppt@linux.vnet.ibm.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent 668ea674
...@@ -1048,11 +1048,6 @@ static int check_compat_cr(void) ...@@ -1048,11 +1048,6 @@ static int check_compat_cr(void)
static int check_uffd(void) static int check_uffd(void)
{ {
unsigned long features = UFFD_FEATURE_EVENT_FORK |
UFFD_FEATURE_EVENT_REMAP |
UFFD_FEATURE_EVENT_UNMAP |
UFFD_FEATURE_EVENT_REMOVE;
if (kerndat_uffd()) if (kerndat_uffd())
return -1; return -1;
...@@ -1061,8 +1056,21 @@ static int check_uffd(void) ...@@ -1061,8 +1056,21 @@ static int check_uffd(void)
return -1; return -1;
} }
return 0;
}
static int check_uffd_noncoop(void)
{
unsigned long features = UFFD_FEATURE_EVENT_FORK |
UFFD_FEATURE_EVENT_REMAP |
UFFD_FEATURE_EVENT_UNMAP |
UFFD_FEATURE_EVENT_REMOVE;
if (check_uffd())
return -1;
if ((kdat.uffd_features & features) != features) { if ((kdat.uffd_features & features) != features) {
pr_err("Userfaultfd missing essential features\n"); pr_err("Non-cooperative UFFD is not supported\n");
return -1; return -1;
} }
...@@ -1181,6 +1189,7 @@ int cr_check(void) ...@@ -1181,6 +1189,7 @@ int cr_check(void)
ret |= check_autofs(); ret |= check_autofs();
ret |= check_compat_cr(); ret |= check_compat_cr();
ret |= check_uffd(); ret |= check_uffd();
ret |= check_uffd_noncoop();
} }
print_on_level(DEFAULT_LOGLEVEL, "%s\n", ret ? CHECK_MAYBE : CHECK_GOOD); print_on_level(DEFAULT_LOGLEVEL, "%s\n", ret ? CHECK_MAYBE : CHECK_GOOD);
...@@ -1222,7 +1231,8 @@ static struct feature_list feature_list[] = { ...@@ -1222,7 +1231,8 @@ static struct feature_list feature_list[] = {
{ "autofs", check_autofs }, { "autofs", check_autofs },
{ "tcp_half_closed", check_tcp_halt_closed }, { "tcp_half_closed", check_tcp_halt_closed },
{ "compat_cr", check_compat_cr }, { "compat_cr", check_compat_cr },
{ "lazy_pages", check_uffd }, { "uffd", check_uffd },
{ "uffd-noncoop", check_uffd_noncoop },
{ NULL, NULL }, { NULL, NULL },
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment