diff --git a/repos/dde_linux/src/include/lx_emul/shadow/arch/arm/include/asm/pgtable.h b/repos/dde_linux/src/include/lx_emul/shadow/arch/arm/include/asm/pgtable.h
index 0eae2a7ca7..ad6689b95f 100644
--- a/repos/dde_linux/src/include/lx_emul/shadow/arch/arm/include/asm/pgtable.h
+++ b/repos/dde_linux/src/include/lx_emul/shadow/arch/arm/include/asm/pgtable.h
@@ -22,6 +22,9 @@
 
 #ifndef __ASSEMBLY__
 
+extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) ((void)(vaddr),virt_to_page(empty_zero_page))
+
 pte_t pte_mkwrite(pte_t pte);
 
 int pte_none(pte_t pte);
diff --git a/repos/dde_linux/src/include/lx_emul/shadow/arch/arm64/include/asm/pgtable.h b/repos/dde_linux/src/include/lx_emul/shadow/arch/arm64/include/asm/pgtable.h
index 74707276cc..b90712e359 100644
--- a/repos/dde_linux/src/include/lx_emul/shadow/arch/arm64/include/asm/pgtable.h
+++ b/repos/dde_linux/src/include/lx_emul/shadow/arch/arm64/include/asm/pgtable.h
@@ -25,6 +25,9 @@
 
 #include <lx_emul/debug.h>
 
+extern unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)];
+#define ZERO_PAGE(vaddr) ((void)(vaddr),virt_to_page(empty_zero_page))
+
 pte_t pte_mkwrite(pte_t pte);
 
 pte_t pte_get(pte_t pte);
diff --git a/repos/dde_linux/src/lib/lx_emul/spec/arm/start.c b/repos/dde_linux/src/lib/lx_emul/spec/arm/start.c
index d0f0bedb6a..475e0f44b5 100644
--- a/repos/dde_linux/src/lib/lx_emul/spec/arm/start.c
+++ b/repos/dde_linux/src/lib/lx_emul/spec/arm/start.c
@@ -30,6 +30,15 @@ void time_init(void)
 }
 
 
+#include <asm/pgtable.h>
+
+/*
+ * Note that empty_zero_page lands in the BSS section and is therefore
+ * automatically zeroed at program startup.
+ */
+unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
+__attribute__((aligned(PAGE_SIZE)));
+
 void lx_emul_setup_arch(void *dtb)
 {
 	/* calls from setup_arch of arch/arm64/kernel/setup.c */