summaryrefslogtreecommitdiff
path: root/arch/arm64/include
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2020-07-06 17:37:59 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-07-22 09:32:50 +0200
commit71d65a3fc62888505bcaff5eaabf8ffc6b6d7be2 (patch)
treefe9408757c3e318993f8dbd49e2441b1f3370cce /arch/arm64/include
parent36d60eba862d6842d6da4d3792b3cf1cde1c22b2 (diff)
arm64: Introduce a way to disable the 32bit vdso
commit 97884ca8c2925d14c32188e865069f21378b4b4f upstream. [this is a redesign rather than a backport] We have a class of errata (grouped under the ARM64_WORKAROUND_1418040 banner) that force the trapping of counter access from 32bit EL0. We would normally disable the whole vdso for such defect, except that it would disable it for 64bit userspace as well, which is a shame. Instead, add a new vdso_clock_mode, which signals that the vdso isn't usable for compat tasks. This gets checked in the new vdso_clocksource_ok() helper, now provided for the 32bit vdso. Signed-off-by: Marc Zyngier <maz@kernel.org> Acked-by: Mark Rutland <mark.rutland@arm.com> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20200706163802.1836732-2-maz@kernel.org Signed-off-by: Will Deacon <will@kernel.org> Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/arm64/include')
-rw-r--r--arch/arm64/include/asm/clocksource.h5
-rw-r--r--arch/arm64/include/asm/vdso/clocksource.h14
-rw-r--r--arch/arm64/include/asm/vdso/compat_gettimeofday.h5
-rw-r--r--arch/arm64/include/asm/vdso/gettimeofday.h6
-rw-r--r--arch/arm64/include/asm/vdso/vsyscall.h4
5 files changed, 26 insertions, 8 deletions
diff --git a/arch/arm64/include/asm/clocksource.h b/arch/arm64/include/asm/clocksource.h
index 0ece64a26c8c..0c7910447235 100644
--- a/arch/arm64/include/asm/clocksource.h
+++ b/arch/arm64/include/asm/clocksource.h
@@ -2,8 +2,11 @@
#ifndef _ASM_CLOCKSOURCE_H
#define _ASM_CLOCKSOURCE_H
+#include <asm/vdso/clocksource.h>
+
struct arch_clocksource_data {
- bool vdso_direct; /* Usable for direct VDSO access? */
+ /* Usable for direct VDSO access? */
+ enum vdso_arch_clockmode clock_mode;
};
#endif
diff --git a/arch/arm64/include/asm/vdso/clocksource.h b/arch/arm64/include/asm/vdso/clocksource.h
new file mode 100644
index 000000000000..8019f616e1f7
--- /dev/null
+++ b/arch/arm64/include/asm/vdso/clocksource.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSOCLOCKSOURCE_H
+#define __ASM_VDSOCLOCKSOURCE_H
+
+enum vdso_arch_clockmode {
+ /* vdso clocksource not usable */
+ VDSO_CLOCKMODE_NONE,
+ /* vdso clocksource for both 32 and 64bit tasks */
+ VDSO_CLOCKMODE_ARCHTIMER,
+ /* vdso clocksource for 64bit tasks only */
+ VDSO_CLOCKMODE_ARCHTIMER_NOCOMPAT,
+};
+
+#endif
diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index c50ee1b7d5cd..413d42e197c7 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -10,6 +10,7 @@
#include <asm/unistd.h>
#include <uapi/linux/time.h>
+#include <asm/vdso/clocksource.h>
#include <asm/vdso/compat_barrier.h>
#define __VDSO_USE_SYSCALL ULLONG_MAX
@@ -117,10 +118,10 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
u64 res;
/*
- * clock_mode == 0 implies that vDSO are enabled otherwise
+ * clock_mode == ARCHTIMER implies that vDSO are enabled otherwise
* fallback on syscall.
*/
- if (clock_mode)
+ if (clock_mode != VDSO_CLOCKMODE_ARCHTIMER)
return __VDSO_USE_SYSCALL;
/*
diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
index b08f476b72b4..ff83b8b574fc 100644
--- a/arch/arm64/include/asm/vdso/gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -10,6 +10,8 @@
#include <asm/unistd.h>
#include <uapi/linux/time.h>
+#include <asm/vdso/clocksource.h>
+
#define __VDSO_USE_SYSCALL ULLONG_MAX
#define VDSO_HAS_CLOCK_GETRES 1
@@ -71,10 +73,10 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
u64 res;
/*
- * clock_mode == 0 implies that vDSO are enabled otherwise
+ * clock_mode != NONE implies that vDSO are enabled otherwise
* fallback on syscall.
*/
- if (clock_mode)
+ if (clock_mode == VDSO_CLOCKMODE_NONE)
return __VDSO_USE_SYSCALL;
/*
diff --git a/arch/arm64/include/asm/vdso/vsyscall.h b/arch/arm64/include/asm/vdso/vsyscall.h
index 0c20a7c1bee5..e50f26741946 100644
--- a/arch/arm64/include/asm/vdso/vsyscall.h
+++ b/arch/arm64/include/asm/vdso/vsyscall.h
@@ -24,9 +24,7 @@ struct vdso_data *__arm64_get_k_vdso_data(void)
static __always_inline
int __arm64_get_clock_mode(struct timekeeper *tk)
{
- u32 use_syscall = !tk->tkr_mono.clock->archdata.vdso_direct;
-
- return use_syscall;
+ return tk->tkr_mono.clock->archdata.clock_mode;
}
#define __arch_get_clock_mode __arm64_get_clock_mode