[CRIU] [RFC 3/3] Probe for task size in restorer
Christopher Covington
cov at codeaurora.org
Thu Jul 23 04:59:50 PDT 2015
If we want one CRIU binary to work across all AArch64 kernel
configurations, the task size cannot be hard coded. Introduce a
simple munmap based probing mechanism to detect the task size at
run time, searching between hard coded minimum, TASK_SIZE_MIN,
and maximum, TASK_SIZE_MAX, values. This fixes the following error
for CRIU on AArch64 kernels with CONFIG_ARM64_64K_PAGES=y.
pie: Error (pie/restorer.c:778): Unable to unmap (-): -1210712064
This change is implemented in generic code but done in a way that
shouldn't affect the functionality or performance of other platforms.
For 32-bit ARM, where TASK_SIZE_MIN and TASK_SIZE_MAX are equal, the
number of calls of the munmap wrapper from pie/restorer.o does not
increase with this change, while it increases by one for AArch64. (I
also tried checking x86_64, but found 0 occurrences of munmap in that
objdump output.)
Signed-off-by: Christopher Covington <cov at codeaurora.org>
---
arch/aarch64/include/asm/types.h | 3 ++-
arch/arm/include/asm/types.h | 2 ++
arch/ppc64/include/asm/types.h | 2 ++
arch/x86/include/asm/types.h | 3 +++
pie/restorer.c | 14 +++++++++++---
5 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/arch/aarch64/include/asm/types.h b/arch/aarch64/include/asm/types.h
index 6512f67..24fb27b 100644
--- a/arch/aarch64/include/asm/types.h
+++ b/arch/aarch64/include/asm/types.h
@@ -62,9 +62,10 @@ typedef struct user_pt_regs user_regs_struct_t;
#define REG_SYSCALL_NR(regs) ((u64)(regs).regs[8])
// Copied from the Linux kernel arch/arm64/include/asm/memory.h
-// FIXME: what about a 32bit task?
#define TASK_SIZE (1ULL << 39)
+#define TASK_SIZE_MIN (1ULL << 32)
+#define TASK_SIZE_MAX (1ULL << 48)
#define AT_VECTOR_SIZE 40
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
index 4efebdd..153f03f 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/asm/types.h
@@ -97,6 +97,8 @@ struct user_vfp_exc {
#define REG_SYSCALL_NR(regs) ((regs).ARM_r7)
#define TASK_SIZE 0xbf000000
+#define TASK_SIZE_MIN TASK_SIZE
+#define TASK_SIZE_MAX TASK_SIZE
#define AT_VECTOR_SIZE 40
diff --git a/arch/ppc64/include/asm/types.h b/arch/ppc64/include/asm/types.h
index 934a4fb..ea0f4fc 100644
--- a/arch/ppc64/include/asm/types.h
+++ b/arch/ppc64/include/asm/types.h
@@ -104,6 +104,8 @@ typedef uint64_t tls_t;
*/
#define TASK_SIZE_USER64 (0x0000400000000000UL)
#define TASK_SIZE TASK_SIZE_USER64
+#define TASK_SIZE_MIN TASK_SIZE
+#define TASK_SIZE_MAX TASK_SIZE
static inline void *decode_pointer(uint64_t v) { return (void*)v; }
static inline uint64_t encode_pointer(void *p) { return (uint64_t)p; }
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index db41b75..c54478a 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -119,6 +119,9 @@ typedef struct {
# define TASK_SIZE (0xffffe000)
#endif
+# define TASK_SIZE_MIN TASK_SIZE
+# define TASK_SIZE_MAX TASK_SIZE
+
typedef u64 auxv_t;
typedef u32 tls_t;
diff --git a/pie/restorer.c b/pie/restorer.c
index fa336fc..30f0323 100644
--- a/pie/restorer.c
+++ b/pie/restorer.c
@@ -744,7 +744,7 @@ void __export_unmap(void)
static int unmap_old_vmas(void *premmapped_addr, unsigned long premmapped_len,
void *bootstrap_start, unsigned long bootstrap_len)
{
- unsigned long s1, s2;
+ unsigned long s1, s2, task_size;
void *p1, *p2;
int ret;
@@ -772,10 +772,18 @@ static int unmap_old_vmas(void *premmapped_addr, unsigned long premmapped_len,
return -1;
}
- ret = sys_munmap(p2 + s2, (void *) TASK_SIZE - (p2 + s2));
+ /* TODO: Use args->mm_saved_aux to get page size */
+ for (task_size = TASK_SIZE_MIN; task_size < TASK_SIZE_MAX; task_size <<= 1)
+ if (sys_munmap((void *)task_size, 65536))
+ break;
+
+ if (TASK_SIZE_MIN != TASK_SIZE_MAX)
+ pr_info("Found task size of %lx\n", task_size);
+
+ ret = sys_munmap(p2 + s2, (void *) task_size - (p2 + s2));
if (ret) {
pr_err("Unable to unmap (%p-%p): %d\n",
- p2 + s2, (void *)TASK_SIZE, ret);
+ p2 + s2, (void *)task_size, ret);
return -1;
}
--
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
More information about the CRIU
mailing list