diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
index fc96b78a8102..45d2ddff662a 100644
--- a/arch/arm/include/asm/elf.h
+++ b/arch/arm/include/asm/elf.h
@@ -3,6 +3,7 @@
 
 #include <asm/auxvec.h>
 #include <asm/hwcap.h>
+#include <asm/vdso_datapage.h>
 
 /*
  * ELF register definitions..
@@ -131,10 +132,12 @@ extern unsigned long arch_randomize_brk(struct mm_struct *mm);
 
 #ifdef CONFIG_MMU
 #ifdef CONFIG_VDSO
-#define ARCH_DLINFO							\
-do {									\
-	NEW_AUX_ENT(AT_SYSINFO_EHDR,					\
-		    (elf_addr_t)current->mm->context.vdso);		\
+#define ARCH_DLINFO								\
+do {										\
+	/* Account for the data page at the beginning of the [vdso] VMA. */	\
+	NEW_AUX_ENT(AT_SYSINFO_EHDR,						\
+		    (elf_addr_t)current->mm->context.vdso +			\
+		    sizeof(union vdso_data_store));				\
 } while (0)
 #endif
 #define ARCH_HAS_SETUP_ADDITIONAL_PAGES 1
diff --git a/arch/arm/include/asm/vdso_datapage.h b/arch/arm/include/asm/vdso_datapage.h
index 9011ec75a24b..f08bdb73d3f4 100644
--- a/arch/arm/include/asm/vdso_datapage.h
+++ b/arch/arm/include/asm/vdso_datapage.h
@@ -22,6 +22,8 @@
 
 #ifndef __ASSEMBLY__
 
+#include <asm/page.h>
+
 /* Try to be cache-friendly on systems that don't implement the
  * generic timer: fit the unconditionally updated fields in the first
  * 32 bytes.
@@ -46,6 +48,11 @@ struct vdso_data {
 	u32 tz_dsttime;
 };
 
+union vdso_data_store {
+	struct vdso_data data;
+	u8 page[PAGE_SIZE];
+};
+
 #endif /* !__ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c
index ded041711beb..dda3363ef0bf 100644
--- a/arch/arm/kernel/asm-offsets.c
+++ b/arch/arm/kernel/asm-offsets.c
@@ -24,6 +24,7 @@
 #include <asm/memory.h>
 #include <asm/procinfo.h>
 #include <asm/suspend.h>
+#include <asm/vdso_datapage.h>
 #include <asm/hardware/cache-l2x0.h>
 #include <linux/kbuild.h>
 
@@ -199,5 +200,9 @@ int main(void)
 #endif
   DEFINE(KVM_VTTBR,		offsetof(struct kvm, arch.vttbr));
 #endif
+  BLANK();
+#ifdef CONFIG_VDSO
+  DEFINE(VDSO_DATA_SIZE,	sizeof(union vdso_data_store));
+#endif
   return 0; 
 }
diff --git a/arch/arm/kernel/vdso.c b/arch/arm/kernel/vdso.c
index 91cbc5f14fb5..1a2bc699c1ac 100644
--- a/arch/arm/kernel/vdso.c
+++ b/arch/arm/kernel/vdso.c
@@ -33,11 +33,8 @@ static unsigned long vdso_pages;
 static unsigned long vdso_mapping_len;
 static struct page **vdso_pagelist;
 
-static union {
-	struct vdso_data	data;
-	u8			page[PAGE_SIZE];
-} vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = &vdso_data_store.data;
+static union vdso_data_store vdso_data_store __page_aligned_data;
+static struct vdso_data *vdso_data = &vdso_data_store.data;
 
 /*
  * The vDSO data page.
@@ -62,12 +59,13 @@ static int __init vdso_init(void)
 	if (vdso_pagelist == NULL)
 		return -ENOMEM;
 
+	/* Grab the vDSO data page. */
+	vdso_pagelist[0] = virt_to_page(vdso_data);
+
 	/* Grab the vDSO code pages. */
 	for (i = 0; i < vdso_pages; i++)
-		vdso_pagelist[i] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+		vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
 
-	/* Grab the vDSO data page. */
-	vdso_pagelist[i] = virt_to_page(vdso_data);
 
 	/* Precompute the mapping size */
 	vdso_mapping_len = (vdso_pages + 1) << PAGE_SHIFT;
diff --git a/arch/arm/kernel/vdso/datapage.S b/arch/arm/kernel/vdso/datapage.S
index 91b19b815888..fbf36d75da06 100644
--- a/arch/arm/kernel/vdso/datapage.S
+++ b/arch/arm/kernel/vdso/datapage.S
@@ -1,8 +1,9 @@
 #include <linux/linkage.h>
+#include <asm/asm-offsets.h>
 
 	.align 2
 .L_vdso_data_ptr:
-	.long	_vdso_data - .
+	.long	_start - . - VDSO_DATA_SIZE
 
 ENTRY(__get_datapage)
 	.cfi_startproc
diff --git a/arch/arm/kernel/vdso/vdso.lds.S b/arch/arm/kernel/vdso/vdso.lds.S
index 24dd7b84e366..799d259f86e0 100644
--- a/arch/arm/kernel/vdso/vdso.lds.S
+++ b/arch/arm/kernel/vdso/vdso.lds.S
@@ -30,6 +30,8 @@ OUTPUT_ARCH(arm)
 
 SECTIONS
 {
+	PROVIDE(_start = .);
+
 	. = VDSO_LBASE + SIZEOF_HEADERS;
 
 	.hash		: { *(.hash) }			:text
@@ -55,14 +57,12 @@ SECTIONS
 	.got		: { *(.got) }
 	.rel.plt	: { *(.rel.plt) }
 
-	. = ALIGN(PAGE_SIZE);
-	PROVIDE(_vdso_data = .);
-
 	/DISCARD/	: {
 		*(.note.GNU-stack)
 		*(.data .data.* .gnu.linkonce.d.* .sdata*)
 		*(.bss .sbss .dynbss .dynsbss)
 	}
+
 }
 
 /*
