d2b3e5
From c37583942c14d3574efbb42e39798bd21e65cfc3 Mon Sep 17 00:00:00 2001
d2b3e5
From: Dmitry Safonov <dima@arista.com>
d2b3e5
Date: Thu, 10 May 2018 19:14:48 +0100
d2b3e5
Subject: [PATCH 8/8] ppc64/aarch64: Dynamically define PAGE_SIZE
d2b3e5
d2b3e5
On ppc64/aarch64 Linux can be set to use Large pages, so the PAGE_SIZE
d2b3e5
isn't build-time constant anymore. Define it through _SC_PAGESIZE.
d2b3e5
d2b3e5
There are different sizes for a page on ppc64:
d2b3e5
: #if defined(CONFIG_PPC_256K_PAGES)
d2b3e5
: #define PAGE_SHIFT              18
d2b3e5
: #elif defined(CONFIG_PPC_64K_PAGES)
d2b3e5
: #define PAGE_SHIFT              16
d2b3e5
: #elif defined(CONFIG_PPC_16K_PAGES)
d2b3e5
: #define PAGE_SHIFT              14
d2b3e5
: #else
d2b3e5
: #define PAGE_SHIFT              12
d2b3e5
: #endif
d2b3e5
d2b3e5
And on aarch64 there are default sizes and possibly someone can set his
d2b3e5
own PAGE_SHIFT:
d2b3e5
: config ARM64_PAGE_SHIFT
d2b3e5
:         int
d2b3e5
:         default 16 if ARM64_64K_PAGES
d2b3e5
:         default 14 if ARM64_16K_PAGES
d2b3e5
:         default 12
d2b3e5
d2b3e5
On the downside - each time we need PAGE_SIZE, we're doing libc
d2b3e5
function call on aarch64/ppc64.
d2b3e5
d2b3e5
Fixes: #415
d2b3e5
d2b3e5
Tested-by: Adrian Reber <areber@redhat.com>
d2b3e5
Signed-off-by: Dmitry Safonov <dima@arista.com>
d2b3e5
Signed-off-by: Andrei Vagin <avagin@virtuozzo.com>
d2b3e5
---
d2b3e5
 criu/arch/aarch64/crtools.c            |  3 ++
d2b3e5
 criu/arch/ppc64/crtools.c              |  3 ++
d2b3e5
 include/common/arch/aarch64/asm/page.h | 42 +++++++++++++++++---------
d2b3e5
 include/common/arch/ppc64/asm/page.h   | 40 +++++++++++++++---------
d2b3e5
 4 files changed, 59 insertions(+), 29 deletions(-)
d2b3e5
d2b3e5
diff --git a/criu/arch/aarch64/crtools.c b/criu/arch/aarch64/crtools.c
d2b3e5
index f98743a23..b2ef1c312 100644
d2b3e5
--- a/criu/arch/aarch64/crtools.c
d2b3e5
+++ b/criu/arch/aarch64/crtools.c
d2b3e5
@@ -21,6 +21,9 @@
d2b3e5
 #include "restorer.h"
d2b3e5
 #include <compel/compel.h>
d2b3e5
 
d2b3e5
+unsigned __page_size = 0;
d2b3e5
+unsigned __page_shift = 0;
d2b3e5
+
d2b3e5
 #define assign_reg(dst, src, e)		dst->e = (__typeof__(dst->e))(src)->e
d2b3e5
 
d2b3e5
 int save_task_regs(void *x, user_regs_struct_t *regs, user_fpregs_struct_t *fpsimd)
d2b3e5
diff --git a/criu/arch/ppc64/crtools.c b/criu/arch/ppc64/crtools.c
d2b3e5
index 5a5966ad4..077c243b2 100644
d2b3e5
--- a/criu/arch/ppc64/crtools.c
d2b3e5
+++ b/criu/arch/ppc64/crtools.c
d2b3e5
@@ -23,6 +23,9 @@
d2b3e5
 #include "images/core.pb-c.h"
d2b3e5
 #include "images/creds.pb-c.h"
d2b3e5
 
d2b3e5
+unsigned __page_size = 0;
d2b3e5
+unsigned __page_shift = 0;
d2b3e5
+
d2b3e5
 static UserPpc64FpstateEntry *copy_fp_regs(uint64_t *fpregs)
d2b3e5
 {
d2b3e5
 	UserPpc64FpstateEntry *fpe;
d2b3e5
diff --git a/include/common/arch/aarch64/asm/page.h b/include/common/arch/aarch64/asm/page.h
d2b3e5
index 4126c8474..bd8fe8f71 100644
d2b3e5
--- a/include/common/arch/aarch64/asm/page.h
d2b3e5
+++ b/include/common/arch/aarch64/asm/page.h
d2b3e5
@@ -4,22 +4,36 @@
d2b3e5
 #define ARCH_HAS_LONG_PAGES
d2b3e5
 
d2b3e5
 #ifndef CR_NOGLIBC
d2b3e5
-#include <unistd.h>
d2b3e5
-
d2b3e5
-#ifndef PAGE_SHIFT
d2b3e5
-# define PAGE_SHIFT	12
d2b3e5
-#endif
d2b3e5
-
d2b3e5
-#ifndef PAGE_SIZE
d2b3e5
-# define PAGE_SIZE	(1UL << PAGE_SHIFT)
d2b3e5
-#endif
d2b3e5
-
d2b3e5
-#ifndef PAGE_MASK
d2b3e5
-# define PAGE_MASK	(~(PAGE_SIZE - 1))
d2b3e5
-#endif
d2b3e5
+#include <string.h> /* ffsl() */
d2b3e5
+#include <unistd.h> /* _SC_PAGESIZE */
d2b3e5
+
d2b3e5
+extern unsigned __page_size;
d2b3e5
+extern unsigned __page_shift;
d2b3e5
+
d2b3e5
+static inline unsigned page_size(void)
d2b3e5
+{
d2b3e5
+	if (!__page_size)
d2b3e5
+		__page_size = sysconf(_SC_PAGESIZE);
d2b3e5
+	return __page_size;
d2b3e5
+}
d2b3e5
+
d2b3e5
+static inline unsigned page_shift(void)
d2b3e5
+{
d2b3e5
+	if (!__page_shift)
d2b3e5
+		__page_shift = (ffsl(page_size()) - 1);
d2b3e5
+	return __page_shift;
d2b3e5
+}
d2b3e5
+
d2b3e5
+/*
d2b3e5
+ * Don't add ifdefs for PAGE_SIZE: if any header defines it as a constant
d2b3e5
+ * on aarch64, then we need refrain using PAGE_SIZE in criu and use
d2b3e5
+ * page_size() across sources (as it may differ on aarch64).
d2b3e5
+ */
d2b3e5
+#define PAGE_SIZE	page_size()
d2b3e5
+#define PAGE_MASK	(~(PAGE_SIZE - 1))
d2b3e5
+#define PAGE_SHIFT	page_shift()
d2b3e5
 
d2b3e5
 #define PAGE_PFN(addr)	((addr) / PAGE_SIZE)
d2b3e5
-#define page_size()	sysconf(_SC_PAGESIZE)
d2b3e5
 
d2b3e5
 #else /* CR_NOGLIBC */
d2b3e5
 
d2b3e5
diff --git a/include/common/arch/ppc64/asm/page.h b/include/common/arch/ppc64/asm/page.h
d2b3e5
index a95af55ef..5107cb8e0 100644
d2b3e5
--- a/include/common/arch/ppc64/asm/page.h
d2b3e5
+++ b/include/common/arch/ppc64/asm/page.h
d2b3e5
@@ -4,26 +4,36 @@
d2b3e5
 #define ARCH_HAS_LONG_PAGES
d2b3e5
 
d2b3e5
 #ifndef CR_NOGLIBC
d2b3e5
-#include <unistd.h>
d2b3e5
+#include <string.h> /* ffsl() */
d2b3e5
+#include <unistd.h> /* _SC_PAGESIZE */
d2b3e5
+
d2b3e5
+extern unsigned __page_size;
d2b3e5
+extern unsigned __page_shift;
d2b3e5
+
d2b3e5
+static inline unsigned page_size(void)
d2b3e5
+{
d2b3e5
+	if (!__page_size)
d2b3e5
+		__page_size = sysconf(_SC_PAGESIZE);
d2b3e5
+	return __page_size;
d2b3e5
+}
d2b3e5
+
d2b3e5
+static inline unsigned page_shift(void)
d2b3e5
+{
d2b3e5
+	if (!__page_shift)
d2b3e5
+		__page_shift = (ffsl(page_size()) - 1);
d2b3e5
+	return __page_shift;
d2b3e5
+}
d2b3e5
 
d2b3e5
 /*
d2b3e5
- * Default config for Pseries is to use 64K pages.
d2b3e5
- * See kernel file arch/powerpc/configs/pseries_*defconfig
d2b3e5
+ * Don't add ifdefs for PAGE_SIZE: if any header defines it as a constant
d2b3e5
+ * on ppc64, then we need refrain using PAGE_SIZE in criu and use
d2b3e5
+ * page_size() across sources (as it may differ on ppc64).
d2b3e5
  */
d2b3e5
-#ifndef PAGE_SHIFT
d2b3e5
-# define PAGE_SHIFT	16
d2b3e5
-#endif
d2b3e5
-
d2b3e5
-#ifndef PAGE_SIZE
d2b3e5
-# define PAGE_SIZE	(1UL << PAGE_SHIFT)
d2b3e5
-#endif
d2b3e5
-
d2b3e5
-#ifndef PAGE_MASK
d2b3e5
-# define PAGE_MASK	(~(PAGE_SIZE - 1))
d2b3e5
-#endif
d2b3e5
+#define PAGE_SIZE	page_size()
d2b3e5
+#define PAGE_MASK	(~(PAGE_SIZE - 1))
d2b3e5
+#define PAGE_SHIFT	page_shift()
d2b3e5
 
d2b3e5
 #define PAGE_PFN(addr)	((addr) / PAGE_SIZE)
d2b3e5
-#define page_size()	sysconf(_SC_PAGESIZE)
d2b3e5
 
d2b3e5
 #else /* CR_NOGLIBC */
d2b3e5
 
d2b3e5
-- 
d2b3e5
2.17.0
d2b3e5