[PATCH v2 09/11] arm64: vdso: Parameterise vDSO data length assumptions in code
Mark Brown
broonie at kernel.org
Wed Jul 1 16:28:44 EDT 2020
In preparation for adding per-CPU data for the vDSO factor out the
assumptions about the vDSO having a single data page so that we use
a function vdso_data_size() to determine the actual length and a
vdso_data_pages to determine the number of pages mapped for data.
The actual data size and runtime behaviour are currently unaffected.
Signed-off-by: Mark Brown <broonie at kernel.org>
---
arch/arm64/include/asm/vdso.h | 7 +++++++
arch/arm64/kernel/vdso.c | 18 ++++++++++++------
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
index 07468428fd29..c7edf7a7491f 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -12,6 +12,13 @@
*/
#define VDSO_LBASE 0x0
+/*
+ * Hard code magic numbers since we need these in vdso.lds.S, there
+ * are BUILD_BUG_ON() checks in vdso.c to make sure these are correct.
+ */
+#define VDSO_BASE_DATA_SIZE 240
+#define VDSO_CS_BASES 2
+
#ifndef __ASSEMBLY__
#include <generated/vdso-offsets.h>
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index f78349faa6c4..e1146f424e6f 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -48,6 +48,7 @@ struct vdso_abi_info {
const char *vdso_code_start;
const char *vdso_code_end;
unsigned long vdso_text_pages;
+ unsigned long vdso_data_pages;
/* Data Mapping */
struct vm_special_mapping *dm;
/* Code Mapping */
@@ -110,6 +111,8 @@ static int __vdso_init(enum vdso_abi abi)
return -EINVAL;
}
+ BUILD_BUG_ON(sizeof(struct vdso_data) != VDSO_BASE_DATA_SIZE);
+
/*
* We ensure that the vDSO text is page aligned and an exact
* number of pages in vdso.S so don't need to round here.
@@ -123,9 +126,11 @@ static int __vdso_init(enum vdso_abi abi)
vdso_info[abi].vdso_code_end -
vdso_info[abi].vdso_code_start) >>
PAGE_SHIFT;
+ vdso_info[abi].vdso_data_pages = VDSO_DATA_PAGES;
vdso_info[abi].dm->pages =
- vdso_get_pages(sym_to_pfn(vdso_data), 1);
+ vdso_get_pages(sym_to_pfn(vdso_data),
+ vdso_info[abi].vdso_data_pages);
vdso_info[abi].cm->pages =
vdso_get_pages(sym_to_pfn(vdso_info[abi].vdso_code_start),
vdso_info[abi].vdso_text_pages);
@@ -141,13 +146,14 @@ static int __setup_additional_pages(enum vdso_abi abi,
struct linux_binprm *bprm,
int uses_interp)
{
- unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
+ unsigned long vdso_base, vdso_mapping_len;
+ unsigned long vdso_text_len, vdso_data_len;
unsigned long gp_flags = 0;
void *ret;
vdso_text_len = vdso_info[abi].vdso_text_pages << PAGE_SHIFT;
- /* Be sure to map the data page */
- vdso_mapping_len = vdso_text_len + PAGE_SIZE;
+ vdso_data_len = vdso_info[abi].vdso_data_pages << PAGE_SHIFT;
+ vdso_mapping_len = vdso_text_len + vdso_data_len;
vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0);
if (IS_ERR_VALUE(vdso_base)) {
@@ -155,7 +161,7 @@ static int __setup_additional_pages(enum vdso_abi abi,
goto up_fail;
}
- ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
+ ret = _install_special_mapping(mm, vdso_base, vdso_data_len,
VM_READ|VM_MAYREAD,
vdso_info[abi].dm);
if (IS_ERR(ret))
@@ -164,7 +170,7 @@ static int __setup_additional_pages(enum vdso_abi abi,
if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && system_supports_bti())
gp_flags = VM_ARM64_BTI;
- vdso_base += PAGE_SIZE;
+ vdso_base += vdso_data_len;
mm->context.vdso = (void *)vdso_base;
ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
VM_READ|VM_EXEC|gp_flags|
--
2.20.1
More information about the linux-arm-kernel
mailing list