[CRIU] [PATCH 1/4] kerndat: Introduce task_size variable

Christopher Covington cov at codeaurora.org
Fri Jul 31 07:36:24 PDT 2015


If we want one CRIU binary to work across all AArch64 kernel
configurations, a single task size value cannot be hard coded.

Signed-off-by: Christopher Covington <cov at codeaurora.org>
---
 arch/aarch64/include/asm/types.h | 20 ++++++++++++++++++++
 arch/arm/include/asm/types.h     |  2 ++
 arch/ppc64/include/asm/types.h   |  2 ++
 arch/x86/include/asm/types.h     |  2 ++
 include/kerndat.h                |  1 +
 kerndat.c                        | 10 ++++++++++
 6 files changed, 37 insertions(+)

diff --git a/arch/aarch64/include/asm/types.h b/arch/aarch64/include/asm/types.h
index 6512f67..0846dd9 100644
--- a/arch/aarch64/include/asm/types.h
+++ b/arch/aarch64/include/asm/types.h
@@ -66,6 +66,26 @@ typedef struct user_pt_regs user_regs_struct_t;
 
 #define TASK_SIZE (1ULL << 39)
 
+/*
+ * Range for task size calculated from the following Linux kernel files:
+ *   arch/arm64/include/asm/memory.h
+ *   arch/arm64/Kconfig
+ */
+#define TASK_SIZE_MIN (1UL << 39)
+#define TASK_SIZE_MAX (1UL << 48)
+
+int munmap(void *addr, size_t length);
+
+static inline unsigned long task_size() {
+	unsigned long task_size;
+
+	for (task_size = TASK_SIZE_MIN; task_size < TASK_SIZE_MAX; task_size <<= 1)
+		if (munmap((void *)task_size, page_size()))
+			break;
+
+	return task_size;
+}
+
 #define AT_VECTOR_SIZE 40
 
 typedef UserAarch64RegsEntry UserRegsEntry;
diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h
index 4efebdd..915db61 100644
--- a/arch/arm/include/asm/types.h
+++ b/arch/arm/include/asm/types.h
@@ -98,6 +98,8 @@ struct user_vfp_exc {
 
 #define TASK_SIZE 0xbf000000
 
+static inline unsigned long task_size() { return TASK_SIZE; }
+
 #define AT_VECTOR_SIZE 40
 
 typedef UserArmRegsEntry UserRegsEntry;
diff --git a/arch/ppc64/include/asm/types.h b/arch/ppc64/include/asm/types.h
index 934a4fb..3412dc7 100644
--- a/arch/ppc64/include/asm/types.h
+++ b/arch/ppc64/include/asm/types.h
@@ -105,6 +105,8 @@ typedef uint64_t tls_t;
 #define TASK_SIZE_USER64 (0x0000400000000000UL)
 #define TASK_SIZE TASK_SIZE_USER64
 
+static inline unsigned long task_size() { return 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..b2d0189 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -119,6 +119,8 @@ typedef struct {
 # define TASK_SIZE	(0xffffe000)
 #endif
 
+static inline unsigned long task_size() { return TASK_SIZE; }
+
 typedef u64 auxv_t;
 typedef u32 tls_t;
 
diff --git a/include/kerndat.h b/include/kerndat.h
index c9e902a..b9ae749 100644
--- a/include/kerndat.h
+++ b/include/kerndat.h
@@ -23,6 +23,7 @@ struct kerndat_s {
 	bool has_dirty_track;
 	bool has_memfd;
 	bool has_fdinfo_lock;
+	unsigned long task_size;
 };
 
 extern struct kerndat_s kdat;
diff --git a/kerndat.c b/kerndat.c
index 54ba8c7..648ecdc 100644
--- a/kerndat.c
+++ b/kerndat.c
@@ -273,6 +273,12 @@ static bool kerndat_has_memfd_create(void)
 	return 0;
 }
 
+static int get_task_size(void) {
+	kdat.task_size = task_size();
+	pr_debug("Found task size of %lx\n", kdat.task_size);
+	return 0;
+}
+
 int kerndat_fdinfo_has_lock()
 {
 	int fd, pfd = -1, exit_code = -1, len;
@@ -323,6 +329,8 @@ int kerndat_init(void)
 		ret = get_last_cap();
 	if (!ret)
 		ret = kerndat_fdinfo_has_lock();
+	if (!ret)
+		ret = get_task_size();
 
 	kerndat_lsm();
 
@@ -344,6 +352,8 @@ int kerndat_init_rst(void)
 		ret = get_last_cap();
 	if (!ret)
 		ret = kerndat_has_memfd_create();
+	if (!ret)
+		ret = get_task_size();
 
 	kerndat_lsm();
 
-- 
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