Commit 9354582f authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Andrei Vagin

kdat: Relax uffd checks (v2)

v2: When uffd is present, the reported features may still be 0,
    so we need one more bool for uffd syscall itself.
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 459b833a
...@@ -1053,9 +1053,14 @@ static int check_uffd(void) ...@@ -1053,9 +1053,14 @@ static int check_uffd(void)
UFFD_FEATURE_EVENT_UNMAP | UFFD_FEATURE_EVENT_UNMAP |
UFFD_FEATURE_EVENT_REMOVE; UFFD_FEATURE_EVENT_REMOVE;
if (kerndat_uffd(true)) if (kerndat_uffd())
return -1; return -1;
if (!kdat.has_uffd) {
pr_err("UFFD is not supported\n");
return -1;
}
if ((kdat.uffd_features & features) != features) { if ((kdat.uffd_features & features) != features) {
pr_err("Userfaultfd missing essential features\n"); pr_err("Userfaultfd missing essential features\n");
return -1; return -1;
......
...@@ -900,7 +900,7 @@ static int handle_feature_check(int sk, CriuReq * msg) ...@@ -900,7 +900,7 @@ static int handle_feature_check(int sk, CriuReq * msg)
if ((msg->features->has_lazy_pages == 1) && if ((msg->features->has_lazy_pages == 1) &&
(msg->features->lazy_pages == true)) { (msg->features->lazy_pages == true)) {
ret = kerndat_uffd(true); ret = kerndat_uffd();
/* /*
* Not checking for specific UFFD features yet. * Not checking for specific UFFD features yet.
...@@ -909,7 +909,7 @@ static int handle_feature_check(int sk, CriuReq * msg) ...@@ -909,7 +909,7 @@ static int handle_feature_check(int sk, CriuReq * msg)
* be extended in the future for a more detailed * be extended in the future for a more detailed
* UFFD feature check. * UFFD feature check.
*/ */
if (ret) if (ret || !kdat.has_uffd)
feat.lazy_pages = false; feat.lazy_pages = false;
else else
feat.lazy_pages = true; feat.lazy_pages = true;
......
...@@ -49,6 +49,7 @@ struct kerndat_s { ...@@ -49,6 +49,7 @@ struct kerndat_s {
bool has_tcp_half_closed; bool has_tcp_half_closed;
bool stack_guard_gap_hidden; bool stack_guard_gap_hidden;
int lsm; int lsm;
bool has_uffd;
unsigned long uffd_features; unsigned long uffd_features;
}; };
...@@ -71,6 +72,6 @@ enum { ...@@ -71,6 +72,6 @@ enum {
extern int kerndat_fs_virtualized(unsigned int which, u32 kdev); extern int kerndat_fs_virtualized(unsigned int which, u32 kdev);
extern int kerndat_tcp_repair(); extern int kerndat_tcp_repair();
extern int kerndat_uffd(bool need_uffd); extern int kerndat_uffd(void);
#endif /* __CR_KERNDAT_H__ */ #endif /* __CR_KERNDAT_H__ */
...@@ -715,7 +715,7 @@ unl: ...@@ -715,7 +715,7 @@ unl:
} }
} }
int kerndat_uffd(bool need_uffd) int kerndat_uffd(void)
{ {
struct uffdio_api uffdio_api; struct uffdio_api uffdio_api;
int uffd; int uffd;
...@@ -727,14 +727,16 @@ int kerndat_uffd(bool need_uffd) ...@@ -727,14 +727,16 @@ int kerndat_uffd(bool need_uffd)
* on this system. Additionally checking for ENOSYS * on this system. Additionally checking for ENOSYS
* makes sure it is actually not implemented. * makes sure it is actually not implemented.
*/ */
if (uffd == -1 && errno == ENOSYS) { if (uffd == -1) {
if (!need_uffd) if (errno == ENOSYS)
return 0; return 0;
pr_err("Lazy pages are not available\n"); pr_err("Lazy pages are not available\n");
return -1; return -1;
} }
kdat.has_uffd = true;
uffdio_api.api = UFFD_API; uffdio_api.api = UFFD_API;
uffdio_api.features = 0; uffdio_api.features = 0;
if (ioctl(uffd, UFFDIO_API, &uffdio_api)) { if (ioctl(uffd, UFFDIO_API, &uffdio_api)) {
...@@ -792,7 +794,7 @@ int kerndat_init(void) ...@@ -792,7 +794,7 @@ int kerndat_init(void)
if (!ret) if (!ret)
ret = kerndat_detect_stack_guard_gap(); ret = kerndat_detect_stack_guard_gap();
if (!ret) if (!ret)
ret = kerndat_uffd(opts.lazy_pages); ret = kerndat_uffd();
kerndat_lsm(); kerndat_lsm();
kerndat_mmap_min_addr(); kerndat_mmap_min_addr();
......
...@@ -1115,7 +1115,7 @@ int cr_lazy_pages(bool daemon) ...@@ -1115,7 +1115,7 @@ int cr_lazy_pages(bool daemon)
int lazy_sk; int lazy_sk;
int ret; int ret;
if (kerndat_uffd(true)) if (kerndat_uffd() || !kdat.has_uffd)
return -1; return -1;
if (prepare_dummy_pstree()) if (prepare_dummy_pstree())
......
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