[PATCH v4 02/12] arm: vdso: add include file defining __get_datapage()
Mark Salyzyn
salyzyn at android.com
Tue Oct 31 11:30:54 PDT 2017
Take an effort to recode the arm64 vdso code from assembler to C
previously submitted by Andrew Pinski <apinski at cavium.com>, rework
it for use in both arm and arm64, overlapping any optimizations
for each architecture. But instead of landing it in arm64, land the
result into lib/vdso and unify both implementations to simplify
future maintenance.
Define the prototype for __get_datapage() in local datapage.h header.
Rename all vdata variable that point to the datapage shortened to vd
to relect a consistent and concise style. Make sure that all
references to the datapage in vdso operations are readonly (const).
Make sure datapage is first parameter to all subroutines to also
be consistent.
Signed-off-by: Mark Salyzyn <salyzyn at android.com>
Cc: James Morse <james.morse at arm.com>
Cc: Russell King <linux at armlinux.org.uk>
Cc: Catalin Marinas <catalin.marinas at arm.com>
Cc: Will Deacon <will.deacon at arm.com>
Cc: Andy Lutomirski <luto at amacapital.net>
Cc: Dmitry Safonov <dsafonov at virtuozzo.com>
Cc: John Stultz <john.stultz at linaro.org>
Cc: Mark Rutland <mark.rutland at arm.com>
Cc: Laura Abbott <labbott at redhat.com>
Cc: Kees Cook <keescook at chromium.org>
Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Cc: Andy Gross <andy.gross at linaro.org>
Cc: Kevin Brodsky <kevin.brodsky at arm.com>
Cc: Andrew Pinski <apinski at cavium.com>
Cc: Thomas Gleixner <tglx at linutronix.de>
Cc: linux-kernel at vger.kernel.org
Cc: linux-arm-kernel at lists.infradead.org
v2:
- split first CL into 2 of 7 pieces
v4:
- update commit message to reflect overall reasoning
---
arch/arm/vdso/datapage.h | 25 +++++++++++
arch/arm/vdso/vgettimeofday.c | 99 +++++++++++++++++++++----------------------
2 files changed, 73 insertions(+), 51 deletions(-)
create mode 100644 arch/arm/vdso/datapage.h
diff --git a/arch/arm/vdso/datapage.h b/arch/arm/vdso/datapage.h
new file mode 100644
index 000000000000..e3088bdfb946
--- /dev/null
+++ b/arch/arm/vdso/datapage.h
@@ -0,0 +1,25 @@
+/*
+ * Userspace implementations of __get_datapage
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __VDSO_DATAPAGE_H
+#define __VDSO_DATAPAGE_H
+
+#include <linux/types.h>
+#include <asm/vdso_datapage.h>
+
+extern const struct vdso_data *__get_datapage(void);
+
+#endif /* __VDSO_DATAPAGE_H */
diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c
index 8cf13af1323c..2474c17dc356 100644
--- a/arch/arm/vdso/vgettimeofday.c
+++ b/arch/arm/vdso/vgettimeofday.c
@@ -30,20 +30,19 @@
#include <asm/bug.h>
#include <asm/page.h>
#include <asm/unistd.h>
-#include <asm/vdso_datapage.h>
#ifndef CONFIG_AEABI
#error This code depends on AEABI system call conventions
#endif
-extern struct vdso_data *__get_datapage(void);
+#include "datapage.h"
-static notrace u32 vdso_read_begin(const struct vdso_data *vdata)
+static notrace u32 vdso_read_begin(const struct vdso_data *vd)
{
u32 seq;
do {
- seq = READ_ONCE(vdata->tb_seq_count);
+ seq = READ_ONCE(vd->tb_seq_count);
if ((seq & 1) == 0)
break;
@@ -55,12 +54,12 @@ static notrace u32 vdso_read_begin(const struct vdso_data *vdata)
return seq;
}
-static notrace int vdso_read_retry(const struct vdso_data *vdata, u32 start)
+static notrace int vdso_read_retry(const struct vdso_data *vd, u32 start)
{
u32 seq;
smp_rmb(); /* Pairs with first smp_wmb in update_vsyscall */
- seq = READ_ONCE(vdata->tb_seq_count);
+ seq = READ_ONCE(vd->tb_seq_count);
return seq != start;
}
@@ -81,38 +80,38 @@ static notrace long clock_gettime_fallback(clockid_t _clkid,
return ret;
}
-static notrace int do_realtime_coarse(struct timespec *ts,
- struct vdso_data *vdata)
+static notrace int do_realtime_coarse(const struct vdso_data *vd,
+ struct timespec *ts)
{
u32 seq;
do {
- seq = vdso_read_begin(vdata);
+ seq = vdso_read_begin(vd);
- ts->tv_sec = vdata->xtime_coarse_sec;
- ts->tv_nsec = vdata->xtime_coarse_nsec;
+ ts->tv_sec = vd->xtime_coarse_sec;
+ ts->tv_nsec = vd->xtime_coarse_nsec;
- } while (vdso_read_retry(vdata, seq));
+ } while (vdso_read_retry(vd, seq));
return 0;
}
-static notrace int do_monotonic_coarse(struct timespec *ts,
- struct vdso_data *vdata)
+static notrace int do_monotonic_coarse(const struct vdso_data *vd,
+ struct timespec *ts)
{
struct timespec tomono;
u32 seq;
do {
- seq = vdso_read_begin(vdata);
+ seq = vdso_read_begin(vd);
- ts->tv_sec = vdata->xtime_coarse_sec;
- ts->tv_nsec = vdata->xtime_coarse_nsec;
+ ts->tv_sec = vd->xtime_coarse_sec;
+ ts->tv_nsec = vd->xtime_coarse_nsec;
- tomono.tv_sec = vdata->wtm_clock_sec;
- tomono.tv_nsec = vdata->wtm_clock_nsec;
+ tomono.tv_sec = vd->wtm_clock_sec;
+ tomono.tv_nsec = vd->wtm_clock_nsec;
- } while (vdso_read_retry(vdata, seq));
+ } while (vdso_read_retry(vd, seq));
ts->tv_sec += tomono.tv_sec;
timespec_add_ns(ts, tomono.tv_nsec);
@@ -122,7 +121,7 @@ static notrace int do_monotonic_coarse(struct timespec *ts,
#ifdef CONFIG_ARM_ARCH_TIMER
-static notrace u64 get_ns(struct vdso_data *vdata)
+static notrace u64 get_ns(const struct vdso_data *vd)
{
u64 cycle_delta;
u64 cycle_now;
@@ -130,29 +129,29 @@ static notrace u64 get_ns(struct vdso_data *vdata)
cycle_now = arch_counter_get_cntvct();
- cycle_delta = (cycle_now - vdata->cs_cycle_last) & vdata->cs_mask;
+ cycle_delta = (cycle_now - vd->cs_cycle_last) & vd->cs_mask;
- nsec = (cycle_delta * vdata->cs_mono_mult) + vdata->xtime_clock_snsec;
- nsec >>= vdata->cs_shift;
+ nsec = (cycle_delta * vd->cs_mono_mult) + vd->xtime_clock_snsec;
+ nsec >>= vd->cs_shift;
return nsec;
}
-static notrace int do_realtime(struct timespec *ts, struct vdso_data *vdata)
+static notrace int do_realtime(const struct vdso_data *vd, struct timespec *ts)
{
u64 nsecs;
u32 seq;
do {
- seq = vdso_read_begin(vdata);
+ seq = vdso_read_begin(vd);
- if (vdata->use_syscall)
+ if (vd->use_syscall)
return -1;
- ts->tv_sec = vdata->xtime_clock_sec;
- nsecs = get_ns(vdata);
+ ts->tv_sec = vd->xtime_clock_sec;
+ nsecs = get_ns(vd);
- } while (vdso_read_retry(vdata, seq));
+ } while (vdso_read_retry(vd, seq));
ts->tv_nsec = 0;
timespec_add_ns(ts, nsecs);
@@ -160,25 +159,25 @@ static notrace int do_realtime(struct timespec *ts, struct vdso_data *vdata)
return 0;
}
-static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+static notrace int do_monotonic(const struct vdso_data *vd, struct timespec *ts)
{
struct timespec tomono;
u64 nsecs;
u32 seq;
do {
- seq = vdso_read_begin(vdata);
+ seq = vdso_read_begin(vd);
- if (vdata->use_syscall)
+ if (vd->use_syscall)
return -1;
- ts->tv_sec = vdata->xtime_clock_sec;
- nsecs = get_ns(vdata);
+ ts->tv_sec = vd->xtime_clock_sec;
+ nsecs = get_ns(vd);
- tomono.tv_sec = vdata->wtm_clock_sec;
- tomono.tv_nsec = vdata->wtm_clock_nsec;
+ tomono.tv_sec = vd->wtm_clock_sec;
+ tomono.tv_nsec = vd->wtm_clock_nsec;
- } while (vdso_read_retry(vdata, seq));
+ } while (vdso_read_retry(vd, seq));
ts->tv_sec += tomono.tv_sec;
ts->tv_nsec = 0;
@@ -189,12 +188,12 @@ static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
#else /* CONFIG_ARM_ARCH_TIMER */
-static notrace int do_realtime(struct timespec *ts, struct vdso_data *vdata)
+static notrace int do_realtime(const struct vdso_data *vd, struct timespec *ts)
{
return -1;
}
-static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
+static notrace int do_monotonic(const struct vdso_data *vd, struct timespec *ts)
{
return -1;
}
@@ -203,23 +202,22 @@ static notrace int do_monotonic(struct timespec *ts, struct vdso_data *vdata)
notrace int __vdso_clock_gettime(clockid_t clkid, struct timespec *ts)
{
- struct vdso_data *vdata;
int ret = -1;
- vdata = __get_datapage();
+ const struct vdso_data *vd = __get_datapage();
switch (clkid) {
case CLOCK_REALTIME_COARSE:
- ret = do_realtime_coarse(ts, vdata);
+ ret = do_realtime_coarse(vd, ts);
break;
case CLOCK_MONOTONIC_COARSE:
- ret = do_monotonic_coarse(ts, vdata);
+ ret = do_monotonic_coarse(vd, ts);
break;
case CLOCK_REALTIME:
- ret = do_realtime(ts, vdata);
+ ret = do_realtime(vd, ts);
break;
case CLOCK_MONOTONIC:
- ret = do_monotonic(ts, vdata);
+ ret = do_monotonic(vd, ts);
break;
default:
break;
@@ -251,12 +249,11 @@ static notrace long gettimeofday_fallback(struct timeval *_tv,
notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
{
struct timespec ts;
- struct vdso_data *vdata;
int ret;
- vdata = __get_datapage();
+ const struct vdso_data *vd = __get_datapage();
- ret = do_realtime(&ts, vdata);
+ ret = do_realtime(vd, &ts);
if (ret)
return gettimeofday_fallback(tv, tz);
@@ -265,8 +262,8 @@ notrace int __vdso_gettimeofday(struct timeval *tv, struct timezone *tz)
tv->tv_usec = ts.tv_nsec / 1000;
}
if (tz) {
- tz->tz_minuteswest = vdata->tz_minuteswest;
- tz->tz_dsttime = vdata->tz_dsttime;
+ tz->tz_minuteswest = vd->tz_minuteswest;
+ tz->tz_dsttime = vd->tz_dsttime;
}
return ret;
--
2.15.0.rc2.357.g7e34df9404-goog
More information about the linux-arm-kernel
mailing list