[LEDE-DEV] [PATCH] kernel: fix VDSO problem on MIPS
Hauke Mehrtens
hauke at hauke-m.de
Thu Aug 10 15:14:27 PDT 2017
This fixes the VDSO problems on the Lantiq VR9 MIPS SoC.
The gettimeofday() sometimes returned old data because of a cache
aliasing problems on MIPS CPUs, to work around this problem VDSO
gettimeofday support was deactivated for MIPS in LEDE.
This problem made ping show very high times like a delay of 4289967.657
ms.
1.000.000 calls to clock_gettime(CLOCK_MONOTONIC, &tp); take 1 second
without VDSO support and 0.35 seconds with VDSO support on Lantiq VR9.
Signed-off-by: Hauke Mehrtens <hauke at hauke-m.de>
---
...MIPS-work-around-aliasing-issue-with-VDSO.patch | 63 ++++++++++++++++++++++
.../pending-4.4/206-mips-disable-vdso.patch | 21 --------
...MIPS-work-around-aliasing-issue-with-VDSO.patch | 63 ++++++++++++++++++++++
.../pending-4.9/206-mips-disable-vdso.patch | 28 ----------
4 files changed, 126 insertions(+), 49 deletions(-)
create mode 100644 target/linux/generic/pending-4.4/206-MIPS-work-around-aliasing-issue-with-VDSO.patch
delete mode 100644 target/linux/generic/pending-4.4/206-mips-disable-vdso.patch
create mode 100644 target/linux/generic/pending-4.9/206-MIPS-work-around-aliasing-issue-with-VDSO.patch
delete mode 100644 target/linux/generic/pending-4.9/206-mips-disable-vdso.patch
diff --git a/target/linux/generic/pending-4.4/206-MIPS-work-around-aliasing-issue-with-VDSO.patch b/target/linux/generic/pending-4.4/206-MIPS-work-around-aliasing-issue-with-VDSO.patch
new file mode 100644
index 0000000000..b62557b7b5
--- /dev/null
+++ b/target/linux/generic/pending-4.4/206-MIPS-work-around-aliasing-issue-with-VDSO.patch
@@ -0,0 +1,63 @@
+From a5513a09cbb946e9d031fb65d6c2ac7c32c9042c Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan at imgtec.com>
+Date: Thu, 10 Aug 2017 22:56:47 +0200
+Subject: MIPS: work around aliasing issue with VDSO
+
+I notice that the mips_vdso_data is updated by update_vsyscall() via
+kseg0, however userland will be accessing it via the mapping 1 page
+below the VDSO.
+
+If the kernel data happened to be placed such that the mips_vdso_data in
+kseg0 and the user mapping had different page colours then you could
+easily hit aliasing issues. A couple of well placed flushes or some more
+careful placement of the VDSO data might well fix it, as could some
+random patch changing the positioning of the data such that it
+coincidentally lined up on the same colour.
+
+The patch unfortunately hacks arch_get_unmapped_area_common so that it
+does the colour alignment on non-shared anonymous pages, as long as
+non-zero pgoff is provided. Hopefully no userland code would try
+mmap'ing anonymous memory with a file offset, and so it should be
+harmless.
+
+It doesn't look like we can just pass MAP_SHARED to avoid the hack as
+then pgoff will get cleared by get_unmapped_area()).
+---
+ arch/mips/kernel/vdso.c | 7 ++++++-
+ arch/mips/mm/mmap.c | 2 +-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
+index f9dbfb14af33..9509b5122e70 100644
+--- a/arch/mips/kernel/vdso.c
++++ b/arch/mips/kernel/vdso.c
+@@ -129,7 +129,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ vvar_size = gic_size + PAGE_SIZE;
+ size = vvar_size + image->size;
+
+- base = get_unmapped_area(NULL, 0, size, 0, 0);
++ /*
++ * Hack to get the user mapping of the VDSO data page matching the cache
++ * colour of its kseg0 address.
++ */
++ base = get_unmapped_area(NULL, 0, size,
++ (virt_to_phys(&vdso_data) - gic_size) >> PAGE_SHIFT, 0);
+ if (IS_ERR_VALUE(base)) {
+ ret = base;
+ goto out;
+diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
+index d08ea3ff0f53..cb468b0ea45c 100644
+--- a/arch/mips/mm/mmap.c
++++ b/arch/mips/mm/mmap.c
+@@ -80,7 +80,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+ }
+
+ do_color_align = 0;
+- if (filp || (flags & MAP_SHARED))
++ if (filp || (flags & MAP_SHARED) || pgoff)
+ do_color_align = 1;
+
+ /* requesting a specific address */
+--
+2.11.0
+
diff --git a/target/linux/generic/pending-4.4/206-mips-disable-vdso.patch b/target/linux/generic/pending-4.4/206-mips-disable-vdso.patch
deleted file mode 100644
index 51b1d041bf..0000000000
--- a/target/linux/generic/pending-4.4/206-mips-disable-vdso.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-Disable MIPS VDSO until the cache issues have been sorted out.
-
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
-
---- a/arch/mips/vdso/Makefile
-+++ b/arch/mips/vdso/Makefile
-@@ -28,11 +28,11 @@ aflags-vdso := $(ccflags-vdso) \
- # the comments on that file.
- #
- ifndef CONFIG_CPU_MIPSR6
-- ifeq ($(call ld-ifversion, -lt, 22500000, y),y)
-- $(warning MIPS VDSO requires binutils >= 2.25)
-+# ifeq ($(call ld-ifversion, -lt, 22500000, y),y)
-+# $(warning MIPS VDSO requires binutils >= 2.25)
- obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
- ccflags-vdso += -DDISABLE_MIPS_VDSO
-- endif
-+# endif
- endif
-
- # VDSO linker flags.
diff --git a/target/linux/generic/pending-4.9/206-MIPS-work-around-aliasing-issue-with-VDSO.patch b/target/linux/generic/pending-4.9/206-MIPS-work-around-aliasing-issue-with-VDSO.patch
new file mode 100644
index 0000000000..b62557b7b5
--- /dev/null
+++ b/target/linux/generic/pending-4.9/206-MIPS-work-around-aliasing-issue-with-VDSO.patch
@@ -0,0 +1,63 @@
+From a5513a09cbb946e9d031fb65d6c2ac7c32c9042c Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan at imgtec.com>
+Date: Thu, 10 Aug 2017 22:56:47 +0200
+Subject: MIPS: work around aliasing issue with VDSO
+
+I notice that the mips_vdso_data is updated by update_vsyscall() via
+kseg0, however userland will be accessing it via the mapping 1 page
+below the VDSO.
+
+If the kernel data happened to be placed such that the mips_vdso_data in
+kseg0 and the user mapping had different page colours then you could
+easily hit aliasing issues. A couple of well placed flushes or some more
+careful placement of the VDSO data might well fix it, as could some
+random patch changing the positioning of the data such that it
+coincidentally lined up on the same colour.
+
+The patch unfortunately hacks arch_get_unmapped_area_common so that it
+does the colour alignment on non-shared anonymous pages, as long as
+non-zero pgoff is provided. Hopefully no userland code would try
+mmap'ing anonymous memory with a file offset, and so it should be
+harmless.
+
+It doesn't look like we can just pass MAP_SHARED to avoid the hack as
+then pgoff will get cleared by get_unmapped_area()).
+---
+ arch/mips/kernel/vdso.c | 7 ++++++-
+ arch/mips/mm/mmap.c | 2 +-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c
+index f9dbfb14af33..9509b5122e70 100644
+--- a/arch/mips/kernel/vdso.c
++++ b/arch/mips/kernel/vdso.c
+@@ -129,7 +129,12 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
+ vvar_size = gic_size + PAGE_SIZE;
+ size = vvar_size + image->size;
+
+- base = get_unmapped_area(NULL, 0, size, 0, 0);
++ /*
++ * Hack to get the user mapping of the VDSO data page matching the cache
++ * colour of its kseg0 address.
++ */
++ base = get_unmapped_area(NULL, 0, size,
++ (virt_to_phys(&vdso_data) - gic_size) >> PAGE_SHIFT, 0);
+ if (IS_ERR_VALUE(base)) {
+ ret = base;
+ goto out;
+diff --git a/arch/mips/mm/mmap.c b/arch/mips/mm/mmap.c
+index d08ea3ff0f53..cb468b0ea45c 100644
+--- a/arch/mips/mm/mmap.c
++++ b/arch/mips/mm/mmap.c
+@@ -80,7 +80,7 @@ static unsigned long arch_get_unmapped_area_common(struct file *filp,
+ }
+
+ do_color_align = 0;
+- if (filp || (flags & MAP_SHARED))
++ if (filp || (flags & MAP_SHARED) || pgoff)
+ do_color_align = 1;
+
+ /* requesting a specific address */
+--
+2.11.0
+
diff --git a/target/linux/generic/pending-4.9/206-mips-disable-vdso.patch b/target/linux/generic/pending-4.9/206-mips-disable-vdso.patch
deleted file mode 100644
index 9785f932e7..0000000000
--- a/target/linux/generic/pending-4.9/206-mips-disable-vdso.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-From: Felix Fietkau <nbd at nbd.name>
-Subject: kernel: disable MIPS VDSO by default until the cache issues have been resolved
-
-lede-commit: 1185e645a773c86aa88cf04d0e2911dc62eb43f5
-Signed-off-by: Felix Fietkau <nbd at nbd.name>
----
- arch/mips/vdso/Makefile | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
-index c3dc12a8b7d9..28f66e3bb2c3 100644
---- a/arch/mips/vdso/Makefile
-+++ b/arch/mips/vdso/Makefile
-@@ -28,9 +28,9 @@ aflags-vdso := $(ccflags-vdso) \
- ifndef CONFIG_CPU_MIPSR6
- ifeq ($(call ld-ifversion, -lt, 225000000, y),y)
- $(warning MIPS VDSO requires binutils >= 2.25)
-- obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
-- ccflags-vdso += -DDISABLE_MIPS_VDSO
- endif
-+ obj-vdso-y := $(filter-out gettimeofday.o, $(obj-vdso-y))
-+ ccflags-vdso += -DDISABLE_MIPS_VDSO
- endif
-
- # VDSO linker flags.
---
-2.11.0
-
--
2.11.0
More information about the Lede-dev
mailing list