From 0ae9f381e1790e119a2b343e9bdbade2b131522e Mon Sep 17 00:00:00 2001 From: Michal Clapinski Date: Fri, 8 Sep 2023 23:34:53 +0200 Subject: [PATCH] membarrier Signed-off-by: Michal Clapinski --- criu/include/kerndat.h | 1 + criu/include/parasite.h | 2 ++ criu/kerndat.c | 22 ++++++++++++++++++++++ criu/parasite-syscall.c | 1 + criu/pie/parasite.c | 39 +++++++++++++++++++++++++++------------ 5 files changed, 53 insertions(+), 12 deletions(-) diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index 0b2f715f383..f5d409acbfb 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -85,6 +85,7 @@ struct kerndat_s { bool has_ptrace_get_rseq_conf; struct __ptrace_rseq_configuration libc_rseq_conf; bool has_ipv6_freebind; + bool has_membarrier_get_registrations; }; extern struct kerndat_s kdat; diff --git a/criu/include/parasite.h b/criu/include/parasite.h index 5209b6da221..b7d0ca6ed68 100644 --- a/criu/include/parasite.h +++ b/criu/include/parasite.h @@ -118,6 +118,8 @@ static inline int posix_timers_dump_size(int timer_n) */ struct parasite_dump_misc { + bool has_membarrier_get_registrations; // this is sent from criu to parasite. + unsigned long brk; u32 pid; diff --git a/criu/kerndat.c b/criu/kerndat.c index 37b265d8def..c77c28ff703 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -17,6 +17,7 @@ #include #include #include +#include #if defined(CONFIG_HAS_NFTABLES_LIB_API_0) || defined(CONFIG_HAS_NFTABLES_LIB_API_1) #include @@ -1636,6 +1637,23 @@ static int kerndat_has_ipv6_freebind(void) return ret; } +static int kerndat_has_membarrier_get_registrations(void) +{ + const int cmd_get_registrations = 1 << 9; + int ret = syscall(__NR_membarrier, cmd_get_registrations, 0); + if (ret < 0) { + if (errno != EINVAL) { + return ret; + } + + kdat.has_membarrier_get_registrations = false; + } else { + kdat.has_membarrier_get_registrations = true; + } + + return 0; +} + /* * Some features depend on resource that can be dynamically changed * at the OS runtime. There are cases that we cannot determine the @@ -1879,6 +1897,10 @@ int kerndat_init(void) pr_err("kerndat_has_ipv6_freebind failed when initializing kerndat.\n"); ret = -1; } + if (!ret && kerndat_has_membarrier_get_registrations()) { + pr_err("kerndat_has_membarrier_get_registrations failed when initializing kerndat.\n"); + ret = -1; + } kerndat_lsm(); kerndat_mmap_min_addr(); diff --git a/criu/parasite-syscall.c b/criu/parasite-syscall.c index c08ed09b189..295e404ec56 100644 --- a/criu/parasite-syscall.c +++ b/criu/parasite-syscall.c @@ -433,6 +433,7 @@ int parasite_dump_misc_seized(struct parasite_ctl *ctl, struct parasite_dump_mis struct parasite_dump_misc *ma; ma = compel_parasite_args(ctl, struct parasite_dump_misc); + ma->has_membarrier_get_registrations = kdat.has_membarrier_get_registrations; if (compel_rpc_call_sync(PARASITE_CMD_DUMP_MISC, ctl) < 0) return -1; diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c index c0604903b99..d151572aea7 100644 --- a/criu/pie/parasite.c +++ b/criu/pie/parasite.c @@ -246,6 +246,25 @@ static int get_membarrier_registration_mask(int cmd_bit) #define MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED 3 #define MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_SYNC_CORE 5 #define MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_RSEQ 7 +#define MEMBARRIER_CMDBIT_GET_REGISTRATIONS 9 + +static int dump_membarrier_compat(int *membarrier_registration_mask) +{ + args->membarrier_registration_mask = 0; + ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED); + if (ret < 0) + return -1; + args->membarrier_registration_mask |= ret; + ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_SYNC_CORE); + if (ret < 0) + return -1; + args->membarrier_registration_mask |= ret; + ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_RSEQ); + if (ret < 0) + return -1; + args->membarrier_registration_mask |= ret; + return 0; +} static int dump_misc(struct parasite_dump_misc *args) { @@ -261,19 +280,15 @@ static int dump_misc(struct parasite_dump_misc *args) args->dumpable = sys_prctl(PR_GET_DUMPABLE, 0, 0, 0, 0); args->thp_disabled = sys_prctl(PR_GET_THP_DISABLE, 0, 0, 0, 0); - args->membarrier_registration_mask = 0; - ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED); - if (ret < 0) - return -1; - args->membarrier_registration_mask |= ret; - ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_SYNC_CORE); - if (ret < 0) + if (args->has_membarrier_get_registrations) { + args->membarrier_registration_mask = sys_membarrier(1 << MEMBARRIER_CMDBIT_GET_REGISTRATIONS, 0, 0); + pr_err("mclapinskilog has: %d\n", args->membarrier_registration_mask); return -1; - args->membarrier_registration_mask |= ret; - ret = get_membarrier_registration_mask(MEMBARRIER_CMDBIT_PRIVATE_EXPEDITED_RSEQ); - if (ret < 0) - return -1; - args->membarrier_registration_mask |= ret; + } else { + ret = dump_membarrier_compat(&args->membarrier_registration_mask); + if (ret) + return ret; + } ret = sys_prctl(PR_GET_CHILD_SUBREAPER, (unsigned long)&args->child_subreaper, 0, 0, 0); if (ret)