2020-03-06 13:33:29

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 00/20] Introduce common headers

Back in July last year we started having a problem in building compat
vDSOs on arm64 [1] [2] that was not present when the arm64 porting to
the Unified vDSO was done. In particular when the compat vDSO on such
architecture is built with gcc it generates the warning below:

In file included from ./arch/arm64/include/asm/thread_info.h:17:0,
from ./include/linux/thread_info.h:38,
from ./arch/arm64/include/asm/preempt.h:5,
from ./include/linux/preempt.h:78,
from ./include/linux/spinlock.h:51,
from ./include/linux/seqlock.h:36,
from ./include/linux/time.h:6,
from ./lib/vdso/gettimeofday.c:7,
from <command-line>:0:
./arch/arm64/include/asm/memory.h: In function ‘__tag_set’:
./arch/arm64/include/asm/memory.h:233:15: warning: cast from pointer
to integer of different size [-Wpointer-to-int-cast]
u64 __addr = (u64)addr & ~__tag_shifted(0xff);
^
In file included from ./arch/arm64/include/asm/pgtable-hwdef.h:8:0,
from ./arch/arm64/include/asm/processor.h:34,
from ./arch/arm64/include/asm/elf.h:118,
from ./include/linux/elf.h:5,
from ./include/linux/elfnote.h:62,
from arch/arm64/kernel/vdso32/note.c:11:
./arch/arm64/include/asm/memory.h: In function ‘__tag_set’:
./arch/arm64/include/asm/memory.h:233:15: warning: cast from pointer
to integer of different size [-Wpointer-to-int-cast]
u64 __addr = (u64)addr & ~__tag_shifted(0xff);

The same porting does not build at all when the selected compiler is
clang.

I started an investigation to try to understand better the problem and
after various discussions at Plumbers and Recipes last year the
conclusion was that the vDSO library as it stands it is including more
headers that it needs. In particular, being a user-space library, it
should require only the UAPI and a minimal vDSO kernel interface instead
of all the kernel-related inline functions which are not directly used
and in some cases can have side effects.

To solve the problem, I decided to use the approach below:
* Extract from include/linux/ the vDSO required kernel interface
and place it in include/common/
* Make sure that where meaningful the kernel includes "common"
* Limit the vDSO library to include headers coming only from UAPI
and "common" (with 2 exceptions compiler.h for barriers and
param.h for HZ).
* Adapt all the architectures that support the unified vDSO library
to use "common" headers.

According to me this approach allows up to exercise a better control on
what the vDSO library can include and to prevent potential issues in
future.

This patch series contains the implementation of the described approach.

The "common" headers have been verified on all the architectures that support
unified vDSO using the vdsotest [3] testsuite for what concerns the vDSO part
and randconfig to verify that they are included in the correct places.

To simplify the testing, a copy of the patchset on top of a recent linux
tree can be found at [4].

[1] https://github.com/ClangBuiltLinux/linux/issues/595
[2] https://lore.kernel.org/lkml/[email protected]
[3] https://github.com/nathanlynch/vdsotest
[4] git://linux-arm.org/linux-vf.git common-headers/v2

Changes:
--------
v2:
- Addressed review comments for clang support.
- Rebased on 5.6-rc4.

Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Russell King <[email protected]>
Cc: Paul Burton <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Stephen Boyd <[email protected]>
Cc: Mark Salyzyn <[email protected]>
Cc: Kees Cook <[email protected]>
Cc: Peter Collingbourne <[email protected]>
Cc: Dmitry Safonov <[email protected]>
Cc: Andrei Vagin <[email protected]>
Cc: Nick Desaulniers <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>

Vincenzo Frascino (20):
linux/const.h: Extract common header for vDSO
linux/bits.h: Extract common header for vDSO
linux/limits.h: Extract common header for vDSO
linux/math64.h: Extract common header for vDSO
linux/time.h: Extract common header for vDSO
linux/time32.h: Extract common header for vDSO
linux/time64.h: Extract common header for vDSO
linux/jiffies.h: Extract common header for vDSO
linux/ktime.h: Extract common header for vDSO
common: Introduce processor.h
linux/elfnote.h: Replace elf.h with UAPI equivalent
arm64: Introduce asm/common/processor.h
arm64: vdso: Include common headers in the vdso library
arm64: vdso32: Include common headers in the vdso library
arm64: Introduce asm/common/arch_timer.h
mips: vdso: Enable mips to use common headers
x86: vdso: Enable x86 to use common headers
arm: vdso: Enable arm to use common headers
lib: vdso: Enable common headers
arm64: vdso32: Enable Clang Compilation

arch/arm/include/asm/common/cp15.h | 38 +++++++++++++++++++
arch/arm/include/asm/common/processor.h | 22 +++++++++++
arch/arm/include/asm/cp15.h | 20 +---------
arch/arm/include/asm/processor.h | 11 +-----
arch/arm/include/asm/vdso/gettimeofday.h | 4 +-
arch/arm64/include/asm/arch_timer.h | 29 +++-----------
arch/arm64/include/asm/common/arch_timer.h | 33 ++++++++++++++++
arch/arm64/include/asm/common/processor.h | 31 +++++++++++++++
arch/arm64/include/asm/processor.h | 16 +-------
.../include/asm/vdso/compat_gettimeofday.h | 2 +-
arch/arm64/include/asm/vdso/gettimeofday.h | 8 ++--
arch/arm64/kernel/vdso/vgettimeofday.c | 2 -
arch/arm64/kernel/vdso32/Makefile | 13 ++++++-
arch/arm64/kernel/vdso32/vgettimeofday.c | 3 --
arch/mips/include/asm/common/processor.h | 27 +++++++++++++
arch/mips/include/asm/processor.h | 16 +-------
arch/mips/include/asm/vdso/gettimeofday.h | 4 --
arch/x86/include/asm/common/processor.h | 23 +++++++++++
arch/x86/include/asm/processor.h | 12 +-----
include/common/bits.h | 9 +++++
include/common/const.h | 10 +++++
include/common/jiffies.h | 11 ++++++
include/common/ktime.h | 16 ++++++++
include/common/limits.h | 18 +++++++++
include/common/math64.h | 24 ++++++++++++
include/common/processor.h | 14 +++++++
include/common/time.h | 12 ++++++
include/common/time32.h | 17 +++++++++
include/common/time64.h | 14 +++++++
include/linux/bits.h | 2 +-
include/linux/const.h | 5 +--
include/linux/elfnote.h | 2 +-
include/linux/jiffies.h | 4 +-
include/linux/ktime.h | 9 +----
include/linux/limits.h | 13 +------
include/linux/math64.h | 20 +---------
include/linux/time.h | 5 +--
include/linux/time32.h | 13 +------
include/linux/time64.h | 10 +----
include/vdso/datapage.h | 32 ++++++++++++++--
lib/vdso/gettimeofday.c | 21 ----------
41 files changed, 388 insertions(+), 207 deletions(-)
create mode 100644 arch/arm/include/asm/common/cp15.h
create mode 100644 arch/arm/include/asm/common/processor.h
create mode 100644 arch/arm64/include/asm/common/arch_timer.h
create mode 100644 arch/arm64/include/asm/common/processor.h
create mode 100644 arch/mips/include/asm/common/processor.h
create mode 100644 arch/x86/include/asm/common/processor.h
create mode 100644 include/common/bits.h
create mode 100644 include/common/const.h
create mode 100644 include/common/jiffies.h
create mode 100644 include/common/ktime.h
create mode 100644 include/common/limits.h
create mode 100644 include/common/math64.h
create mode 100644 include/common/processor.h
create mode 100644 include/common/time.h
create mode 100644 include/common/time32.h
create mode 100644 include/common/time64.h

--
2.25.1


2020-03-06 13:33:46

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 02/20] linux/bits.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split bits.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/bits.h | 9 +++++++++
include/linux/bits.h | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
create mode 100644 include/common/bits.h

diff --git a/include/common/bits.h b/include/common/bits.h
new file mode 100644
index 000000000000..6da493992e52
--- /dev/null
+++ b/include/common/bits.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_BITS_H
+#define __COMMON_BITS_H
+
+#include <common/const.h>
+
+#define BIT(nr) (UL(1) << (nr))
+
+#endif /* __COMMON_BITS_H */
diff --git a/include/linux/bits.h b/include/linux/bits.h
index 669d69441a62..aeb76fede77a 100644
--- a/include/linux/bits.h
+++ b/include/linux/bits.h
@@ -3,9 +3,9 @@
#define __LINUX_BITS_H

#include <linux/const.h>
+#include <common/bits.h>
#include <asm/bitsperlong.h>

-#define BIT(nr) (UL(1) << (nr))
#define BIT_ULL(nr) (ULL(1) << (nr))
#define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG))
#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
--
2.25.1

2020-03-06 13:33:48

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 03/20] linux/limits.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split limits.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/limits.h | 18 ++++++++++++++++++
include/linux/limits.h | 13 +------------
2 files changed, 19 insertions(+), 12 deletions(-)
create mode 100644 include/common/limits.h

diff --git a/include/common/limits.h b/include/common/limits.h
new file mode 100644
index 000000000000..587269010add
--- /dev/null
+++ b/include/common/limits.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_LIMITS_H
+#define __COMMON_LIMITS_H
+
+#define USHRT_MAX ((unsigned short)~0U)
+#define SHRT_MAX ((short)(USHRT_MAX >> 1))
+#define SHRT_MIN ((short)(-SHRT_MAX - 1))
+#define INT_MAX ((int)(~0U >> 1))
+#define INT_MIN (-INT_MAX - 1)
+#define UINT_MAX (~0U)
+#define LONG_MAX ((long)(~0UL >> 1))
+#define LONG_MIN (-LONG_MAX - 1)
+#define ULONG_MAX (~0UL)
+#define LLONG_MAX ((long long)(~0ULL >> 1))
+#define LLONG_MIN (-LLONG_MAX - 1)
+#define ULLONG_MAX (~0ULL)
+
+#endif /* __COMMON_LIMITS_H */
diff --git a/include/linux/limits.h b/include/linux/limits.h
index 76afcd24ff8c..ac20d2b2edd9 100644
--- a/include/linux/limits.h
+++ b/include/linux/limits.h
@@ -4,19 +4,8 @@

#include <uapi/linux/limits.h>
#include <linux/types.h>
+#include <common/limits.h>

-#define USHRT_MAX ((unsigned short)~0U)
-#define SHRT_MAX ((short)(USHRT_MAX >> 1))
-#define SHRT_MIN ((short)(-SHRT_MAX - 1))
-#define INT_MAX ((int)(~0U >> 1))
-#define INT_MIN (-INT_MAX - 1)
-#define UINT_MAX (~0U)
-#define LONG_MAX ((long)(~0UL >> 1))
-#define LONG_MIN (-LONG_MAX - 1)
-#define ULONG_MAX (~0UL)
-#define LLONG_MAX ((long long)(~0ULL >> 1))
-#define LLONG_MIN (-LLONG_MAX - 1)
-#define ULLONG_MAX (~0ULL)
#define SIZE_MAX (~(size_t)0)
#define PHYS_ADDR_MAX (~(phys_addr_t)0)

--
2.25.1

2020-03-06 13:33:54

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 05/20] linux/time.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split time.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/time.h | 12 ++++++++++++
include/linux/time.h | 5 +----
2 files changed, 13 insertions(+), 4 deletions(-)
create mode 100644 include/common/time.h

diff --git a/include/common/time.h b/include/common/time.h
new file mode 100644
index 000000000000..90eb9bdb40ec
--- /dev/null
+++ b/include/common/time.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_TIME_H
+#define __COMMON_TIME_H
+
+#include <uapi/linux/types.h>
+
+struct timens_offset {
+ s64 sec;
+ u64 nsec;
+};
+
+#endif /* __COMMON_TIME_H */
diff --git a/include/linux/time.h b/include/linux/time.h
index 8ef5e5cc9f57..617a01e2c8bb 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -111,9 +111,6 @@ static inline bool itimerspec64_valid(const struct itimerspec64 *its)
*/
#define time_between32(t, l, h) ((u32)(h) - (u32)(l) >= (u32)(t) - (u32)(l))

-struct timens_offset {
- s64 sec;
- u64 nsec;
-};
+# include <common/time.h>

#endif
--
2.25.1

2020-03-06 13:33:55

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 04/20] linux/math64.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split math64.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/math64.h | 24 ++++++++++++++++++++++++
include/linux/math64.h | 20 +-------------------
2 files changed, 25 insertions(+), 19 deletions(-)
create mode 100644 include/common/math64.h

diff --git a/include/common/math64.h b/include/common/math64.h
new file mode 100644
index 000000000000..4e1870e40182
--- /dev/null
+++ b/include/common/math64.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_MATH64_H
+#define __COMMON_MATH64_H
+
+static __always_inline u32
+__iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
+{
+ u32 ret = 0;
+
+ while (dividend >= divisor) {
+ /* The following asm() prevents the compiler from
+ optimising this loop into a modulo operation. */
+ asm("" : "+rm"(dividend));
+
+ dividend -= divisor;
+ ret++;
+ }
+
+ *remainder = dividend;
+
+ return ret;
+}
+
+#endif /* __COMMON_MATH64_H */
diff --git a/include/linux/math64.h b/include/linux/math64.h
index 65bef21cdddb..54eb486b5d1a 100644
--- a/include/linux/math64.h
+++ b/include/linux/math64.h
@@ -3,6 +3,7 @@
#define _LINUX_MATH64_H

#include <linux/types.h>
+#include <common/math64.h>
#include <asm/div64.h>

#if BITS_PER_LONG == 64
@@ -142,25 +143,6 @@ static inline s64 div_s64(s64 dividend, s32 divisor)

u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder);

-static __always_inline u32
-__iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
-{
- u32 ret = 0;
-
- while (dividend >= divisor) {
- /* The following asm() prevents the compiler from
- optimising this loop into a modulo operation. */
- asm("" : "+rm"(dividend));
-
- dividend -= divisor;
- ret++;
- }
-
- *remainder = dividend;
-
- return ret;
-}
-
#ifndef mul_u32_u32
/*
* Many a GCC version messes this up and generates a 64x64 mult :-(
--
2.25.1

2020-03-06 13:34:05

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 07/20] linux/time64.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split time64.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/time64.h | 14 ++++++++++++++
include/linux/time64.h | 10 +---------
2 files changed, 15 insertions(+), 9 deletions(-)
create mode 100644 include/common/time64.h

diff --git a/include/common/time64.h b/include/common/time64.h
new file mode 100644
index 000000000000..ff5a72fafb30
--- /dev/null
+++ b/include/common/time64.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_TIME64_H
+#define __COMMON_TIME64_H
+
+/* Parameters used to convert the timespec values: */
+#define MSEC_PER_SEC 1000L
+#define USEC_PER_MSEC 1000L
+#define NSEC_PER_USEC 1000L
+#define NSEC_PER_MSEC 1000000L
+#define USEC_PER_SEC 1000000L
+#define NSEC_PER_SEC 1000000000L
+#define FSEC_PER_SEC 1000000000000000LL
+
+#endif /* __COMMON_TIME64_H */
diff --git a/include/linux/time64.h b/include/linux/time64.h
index 19125489ae94..3d8b3739e885 100644
--- a/include/linux/time64.h
+++ b/include/linux/time64.h
@@ -3,6 +3,7 @@
#define _LINUX_TIME64_H

#include <linux/math64.h>
+#include <common/time64.h>

typedef __s64 time64_t;
typedef __u64 timeu64_t;
@@ -19,15 +20,6 @@ struct itimerspec64 {
struct timespec64 it_value;
};

-/* Parameters used to convert the timespec values: */
-#define MSEC_PER_SEC 1000L
-#define USEC_PER_MSEC 1000L
-#define NSEC_PER_USEC 1000L
-#define NSEC_PER_MSEC 1000000L
-#define USEC_PER_SEC 1000000L
-#define NSEC_PER_SEC 1000000000L
-#define FSEC_PER_SEC 1000000000000000LL
-
/* Located here for timespec[64]_valid_strict */
#define TIME64_MAX ((s64)~((u64)1 << 63))
#define TIME64_MIN (-TIME64_MAX - 1)
--
2.25.1

2020-03-06 13:34:07

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 08/20] linux/jiffies.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split jiffies.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/jiffies.h | 11 +++++++++++
include/linux/jiffies.h | 4 +---
2 files changed, 12 insertions(+), 3 deletions(-)
create mode 100644 include/common/jiffies.h

diff --git a/include/common/jiffies.h b/include/common/jiffies.h
new file mode 100644
index 000000000000..ff0207f00550
--- /dev/null
+++ b/include/common/jiffies.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_JIFFIES_H
+#define __COMMON_JIFFIES_H
+
+#include <asm/param.h> /* for HZ */
+#include <common/time64.h>
+
+/* TICK_NSEC is the time between ticks in nsec assuming SHIFTED_HZ */
+#define TICK_NSEC ((NSEC_PER_SEC+HZ/2)/HZ)
+
+#endif /* __COMMON_JIFFIES_H */
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index e3279ef24d28..710539d1e39b 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -8,6 +8,7 @@
#include <linux/types.h>
#include <linux/time.h>
#include <linux/timex.h>
+#include <common/jiffies.h>
#include <asm/param.h> /* for HZ */
#include <generated/timeconst.h>

@@ -59,9 +60,6 @@

extern int register_refined_jiffies(long clock_tick_rate);

-/* TICK_NSEC is the time between ticks in nsec assuming SHIFTED_HZ */
-#define TICK_NSEC ((NSEC_PER_SEC+HZ/2)/HZ)
-
/* TICK_USEC is the time between ticks in usec assuming SHIFTED_HZ */
#define TICK_USEC ((USEC_PER_SEC + HZ/2) / HZ)

--
2.25.1

2020-03-06 13:34:18

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 10/20] common: Introduce processor.h

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Introduce processor.h to contain all the processor specific functions
that are suitable for vDSO inclusion.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/processor.h | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 include/common/processor.h

diff --git a/include/common/processor.h b/include/common/processor.h
new file mode 100644
index 000000000000..f9f971cb4235
--- /dev/null
+++ b/include/common/processor.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+#ifndef __COMMON_PROCESSOR_H
+#define __COMMON_PROCESSOR_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/common/processor.h>
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __COMMON_PROCESSOR_H */
--
2.25.1

2020-03-06 13:34:24

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 11/20] linux/elfnote.h: Replace elf.h with UAPI equivalent

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Replace linux/elf.h with UAPI equivalent in elfnote.h to make the header
suitable for vDSO inclusion.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/linux/elfnote.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/elfnote.h b/include/linux/elfnote.h
index f236f5b931b2..594d4e78654f 100644
--- a/include/linux/elfnote.h
+++ b/include/linux/elfnote.h
@@ -59,7 +59,7 @@
ELFNOTE_END

#else /* !__ASSEMBLER__ */
-#include <linux/elf.h>
+#include <uapi/linux/elf.h>
/*
* Use an anonymous structure which matches the shape of
* Elf{32,64}_Nhdr, but includes the name and desc data. The size and
--
2.25.1

2020-03-06 13:34:27

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 13/20] arm64: vdso: Include common headers in the vdso library

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Refactor the vdso implementation to include common headers.

Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/arm64/include/asm/vdso/gettimeofday.h | 1 -
arch/arm64/kernel/vdso/vgettimeofday.c | 2 --
2 files changed, 3 deletions(-)

diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
index b08f476b72b4..cc3456416096 100644
--- a/arch/arm64/include/asm/vdso/gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -8,7 +8,6 @@
#ifndef __ASSEMBLY__

#include <asm/unistd.h>
-#include <uapi/linux/time.h>

#define __VDSO_USE_SYSCALL ULLONG_MAX

diff --git a/arch/arm64/kernel/vdso/vgettimeofday.c b/arch/arm64/kernel/vdso/vgettimeofday.c
index 747635501a14..4236cf34d7d9 100644
--- a/arch/arm64/kernel/vdso/vgettimeofday.c
+++ b/arch/arm64/kernel/vdso/vgettimeofday.c
@@ -5,8 +5,6 @@
* Copyright (C) 2018 ARM Limited
*
*/
-#include <linux/time.h>
-#include <linux/types.h>

int __kernel_clock_gettime(clockid_t clock,
struct __kernel_timespec *ts)
--
2.25.1

2020-03-06 13:34:30

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 12/20] arm64: Introduce asm/common/processor.h

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Introduce asm/common/processor.h to contain all the arm64 specific
functions that are suitable for vDSO inclusion.

Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/arm64/include/asm/common/processor.h | 31 +++++++++++++++++++++++
arch/arm64/include/asm/processor.h | 16 ++----------
2 files changed, 33 insertions(+), 14 deletions(-)
create mode 100644 arch/arm64/include/asm/common/processor.h

diff --git a/arch/arm64/include/asm/common/processor.h b/arch/arm64/include/asm/common/processor.h
new file mode 100644
index 000000000000..d02b0f392923
--- /dev/null
+++ b/arch/arm64/include/asm/common/processor.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+#ifndef __ASM_COMMON_PROCESSOR_H
+#define __ASM_COMMON_PROCESSOR_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/page-def.h>
+
+#ifdef CONFIG_COMPAT
+#if defined(CONFIG_ARM64_64K_PAGES) && defined(CONFIG_KUSER_HELPERS)
+/*
+ * With CONFIG_ARM64_64K_PAGES enabled, the last page is occupied
+ * by the compat vectors page.
+ */
+#define TASK_SIZE_32 UL(0x100000000)
+#else
+#define TASK_SIZE_32 (UL(0x100000000) - PAGE_SIZE)
+#endif /* CONFIG_ARM64_64K_PAGES */
+#endif /* CONFIG_COMPAT */
+
+static inline void cpu_relax(void)
+{
+ asm volatile("yield" ::: "memory");
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_COMMON_PROCESSOR_H */
diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
index 5ba63204d078..2866afc33f24 100644
--- a/arch/arm64/include/asm/processor.h
+++ b/arch/arm64/include/asm/processor.h
@@ -28,6 +28,8 @@
#include <linux/string.h>
#include <linux/thread_info.h>

+#include <common/processor.h>
+
#include <asm/alternative.h>
#include <asm/cpufeature.h>
#include <asm/hw_breakpoint.h>
@@ -47,15 +49,6 @@
#define TASK_SIZE_64 (UL(1) << vabits_actual)

#ifdef CONFIG_COMPAT
-#if defined(CONFIG_ARM64_64K_PAGES) && defined(CONFIG_KUSER_HELPERS)
-/*
- * With CONFIG_ARM64_64K_PAGES enabled, the last page is occupied
- * by the compat vectors page.
- */
-#define TASK_SIZE_32 UL(0x100000000)
-#else
-#define TASK_SIZE_32 (UL(0x100000000) - PAGE_SIZE)
-#endif /* CONFIG_ARM64_64K_PAGES */
#define TASK_SIZE (test_thread_flag(TIF_32BIT) ? \
TASK_SIZE_32 : TASK_SIZE_64)
#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk, TIF_32BIT) ? \
@@ -256,11 +249,6 @@ extern void release_thread(struct task_struct *);

unsigned long get_wchan(struct task_struct *p);

-static inline void cpu_relax(void)
-{
- asm volatile("yield" ::: "memory");
-}
-
/* Thread switching */
extern struct task_struct *cpu_switch_to(struct task_struct *prev,
struct task_struct *next);
--
2.25.1

2020-03-06 13:34:30

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 14/20] arm64: vdso32: Include common headers in the vdso library

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Refactor the vdso32 implementation to include common headers.

Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/arm64/include/asm/vdso/compat_gettimeofday.h | 2 +-
arch/arm64/kernel/vdso32/vgettimeofday.c | 3 ---
2 files changed, 1 insertion(+), 4 deletions(-)

diff --git a/arch/arm64/include/asm/vdso/compat_gettimeofday.h b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
index 537b1e695365..a1f21474f11f 100644
--- a/arch/arm64/include/asm/vdso/compat_gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/compat_gettimeofday.h
@@ -8,7 +8,7 @@
#ifndef __ASSEMBLY__

#include <asm/unistd.h>
-#include <uapi/linux/time.h>
+#include <asm/errno.h>

#include <asm/vdso/compat_barrier.h>

diff --git a/arch/arm64/kernel/vdso32/vgettimeofday.c b/arch/arm64/kernel/vdso32/vgettimeofday.c
index 54fc1c2ce93f..9366ceb635a1 100644
--- a/arch/arm64/kernel/vdso32/vgettimeofday.c
+++ b/arch/arm64/kernel/vdso32/vgettimeofday.c
@@ -5,9 +5,6 @@
* Copyright (C) 2018 ARM Limited
*
*/
-#include <linux/time.h>
-#include <linux/types.h>
-
int __vdso_clock_gettime(clockid_t clock,
struct old_timespec32 *ts)
{
--
2.25.1

2020-03-06 13:34:32

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 01/20] linux/const.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split const.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/const.h | 10 ++++++++++
include/linux/const.h | 5 +----
2 files changed, 11 insertions(+), 4 deletions(-)
create mode 100644 include/common/const.h

diff --git a/include/common/const.h b/include/common/const.h
new file mode 100644
index 000000000000..cc209eec47a1
--- /dev/null
+++ b/include/common/const.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_CONST_H
+#define __COMMON_CONST_H
+
+#include <uapi/linux/const.h>
+
+#define UL(x) (_UL(x))
+#define ULL(x) (_ULL(x))
+
+#endif /* __COMMON_CONST_H */
diff --git a/include/linux/const.h b/include/linux/const.h
index 7b55a55f5911..447a5b98d5a3 100644
--- a/include/linux/const.h
+++ b/include/linux/const.h
@@ -1,9 +1,6 @@
#ifndef _LINUX_CONST_H
#define _LINUX_CONST_H

-#include <uapi/linux/const.h>
-
-#define UL(x) (_UL(x))
-#define ULL(x) (_ULL(x))
+#include <common/const.h>

#endif /* _LINUX_CONST_H */
--
2.25.1

2020-03-06 13:34:37

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 16/20] mips: vdso: Enable mips to use common headers

Enable mips to use only the common headers in the implementation of
the vDSO library.

Cc: Paul Burton <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/mips/include/asm/common/processor.h | 27 +++++++++++++++++++++++
arch/mips/include/asm/processor.h | 16 +-------------
arch/mips/include/asm/vdso/gettimeofday.h | 4 ----
3 files changed, 28 insertions(+), 19 deletions(-)
create mode 100644 arch/mips/include/asm/common/processor.h

diff --git a/arch/mips/include/asm/common/processor.h b/arch/mips/include/asm/common/processor.h
new file mode 100644
index 000000000000..d2ee5d397d2b
--- /dev/null
+++ b/arch/mips/include/asm/common/processor.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+#ifndef __ASM_COMMON_PROCESSOR_H
+#define __ASM_COMMON_PROCESSOR_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_CPU_LOONGSON64
+/*
+ * Loongson-3's SFB (Store-Fill-Buffer) may buffer writes indefinitely when a
+ * tight read loop is executed, because reads take priority over writes & the
+ * hardware (incorrectly) doesn't ensure that writes will eventually occur.
+ *
+ * Since spin loops of any kind should have a cpu_relax() in them, force an SFB
+ * flush from cpu_relax() such that any pending writes will become visible as
+ * expected.
+ */
+#define cpu_relax() smp_mb()
+#else
+#define cpu_relax() barrier()
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_COMMON_PROCESSOR_H */
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 7619ad319400..b7eca25e2066 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -22,6 +22,7 @@
#include <asm/dsemul.h>
#include <asm/mipsregs.h>
#include <asm/prefetch.h>
+#include <asm/common/processor.h>

/*
* System setup and hardware flags..
@@ -385,21 +386,6 @@ unsigned long get_wchan(struct task_struct *p);
#define KSTK_ESP(tsk) (task_pt_regs(tsk)->regs[29])
#define KSTK_STATUS(tsk) (task_pt_regs(tsk)->cp0_status)

-#ifdef CONFIG_CPU_LOONGSON64
-/*
- * Loongson-3's SFB (Store-Fill-Buffer) may buffer writes indefinitely when a
- * tight read loop is executed, because reads take priority over writes & the
- * hardware (incorrectly) doesn't ensure that writes will eventually occur.
- *
- * Since spin loops of any kind should have a cpu_relax() in them, force an SFB
- * flush from cpu_relax() such that any pending writes will become visible as
- * expected.
- */
-#define cpu_relax() smp_mb()
-#else
-#define cpu_relax() barrier()
-#endif
-
/*
* Return_address is a replacement for __builtin_return_address(count)
* which on certain architectures cannot reasonably be implemented in GCC
diff --git a/arch/mips/include/asm/vdso/gettimeofday.h b/arch/mips/include/asm/vdso/gettimeofday.h
index a58687e26c5d..e8ab2fafe067 100644
--- a/arch/mips/include/asm/vdso/gettimeofday.h
+++ b/arch/mips/include/asm/vdso/gettimeofday.h
@@ -13,12 +13,8 @@

#ifndef __ASSEMBLY__

-#include <linux/compiler.h>
-#include <linux/time.h>
-
#include <asm/vdso/vdso.h>
#include <asm/clocksource.h>
-#include <asm/io.h>
#include <asm/unistd.h>
#include <asm/vdso.h>

--
2.25.1

2020-03-06 13:34:43

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 17/20] x86: vdso: Enable x86 to use common headers

Enable x86 to use only the common headers in the implementation
of the vDSO library.

Cc: Thomas Gleixner <[email protected]>
Cc: Andy Lutomirski <[email protected]>
Cc: Ingo Molnar <[email protected]>
Cc: Borislav Petkov <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/x86/include/asm/common/processor.h | 23 +++++++++++++++++++++++
arch/x86/include/asm/processor.h | 12 +-----------
2 files changed, 24 insertions(+), 11 deletions(-)
create mode 100644 arch/x86/include/asm/common/processor.h

diff --git a/arch/x86/include/asm/common/processor.h b/arch/x86/include/asm/common/processor.h
new file mode 100644
index 000000000000..60ca2ee6e672
--- /dev/null
+++ b/arch/x86/include/asm/common/processor.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+#ifndef __ASM_COMMON_PROCESSOR_H
+#define __ASM_COMMON_PROCESSOR_H
+
+#ifndef __ASSEMBLY__
+
+/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
+static __always_inline void rep_nop(void)
+{
+ asm volatile("rep; nop" ::: "memory");
+}
+
+static __always_inline void cpu_relax(void)
+{
+ rep_nop();
+}
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_COMMON_PROCESSOR_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 09705ccc393c..d66c5dd42cff 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -26,6 +26,7 @@ struct vm86;
#include <asm/fpu/types.h>
#include <asm/unwind_hints.h>
#include <asm/vmxfeatures.h>
+#include <asm/common/processor.h>

#include <linux/personality.h>
#include <linux/cache.h>
@@ -677,17 +678,6 @@ static inline unsigned int cpuid_edx(unsigned int op)
return edx;
}

-/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
-static __always_inline void rep_nop(void)
-{
- asm volatile("rep; nop" ::: "memory");
-}
-
-static __always_inline void cpu_relax(void)
-{
- rep_nop();
-}
-
/*
* This function forces the icache and prefetched instruction stream to
* catch up with reality in two very specific cases:
--
2.25.1

2020-03-06 13:34:50

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 18/20] arm: vdso: Enable arm to use common headers

Enable arm to use only the common headers in the implementation
of the vDSO library.

Cc: Russell King <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/arm/include/asm/common/cp15.h | 38 ++++++++++++++++++++++++
arch/arm/include/asm/common/processor.h | 22 ++++++++++++++
arch/arm/include/asm/cp15.h | 20 +------------
arch/arm/include/asm/processor.h | 11 +------
arch/arm/include/asm/vdso/gettimeofday.h | 4 +--
5 files changed, 64 insertions(+), 31 deletions(-)
create mode 100644 arch/arm/include/asm/common/cp15.h
create mode 100644 arch/arm/include/asm/common/processor.h

diff --git a/arch/arm/include/asm/common/cp15.h b/arch/arm/include/asm/common/cp15.h
new file mode 100644
index 000000000000..d1412c80120f
--- /dev/null
+++ b/arch/arm/include/asm/common/cp15.h
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+#ifndef __ASM_COMMON_CP15_H
+#define __ASM_COMMON_CP15_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_CPU_CP15
+
+#include <linux/stringify.h>
+
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2) \
+ "mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
+#define __ACCESS_CP15_64(Op1, CRm) \
+ "mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
+
+#define __read_sysreg(r, w, c, t) ({ \
+ t __val; \
+ asm volatile(r " " c : "=r" (__val)); \
+ __val; \
+})
+#define read_sysreg(...) __read_sysreg(__VA_ARGS__)
+
+#define __write_sysreg(v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))
+#define write_sysreg(v, ...) __write_sysreg(v, __VA_ARGS__)
+
+#define BPIALL __ACCESS_CP15(c7, 0, c5, 6)
+#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0)
+
+#define CNTVCT __ACCESS_CP15_64(1, c14)
+
+#endif /* CONFIG_CPU_CP15 */
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_COMMON_CP15_H */
diff --git a/arch/arm/include/asm/common/processor.h b/arch/arm/include/asm/common/processor.h
new file mode 100644
index 000000000000..0e76f3cb0d0d
--- /dev/null
+++ b/arch/arm/include/asm/common/processor.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+#ifndef __ASM_COMMON_PROCESSOR_H
+#define __ASM_COMMON_PROCESSOR_H
+
+#ifndef __ASSEMBLY__
+
+#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
+#define cpu_relax() \
+ do { \
+ smp_mb(); \
+ __asm__ __volatile__("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); \
+ } while (0)
+#else
+#define cpu_relax() barrier()
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_COMMON_PROCESSOR_H */
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
index d2453e2d3f1f..fe47a65130ab 100644
--- a/arch/arm/include/asm/cp15.h
+++ b/arch/arm/include/asm/cp15.h
@@ -50,25 +50,7 @@

#ifdef CONFIG_CPU_CP15

-#define __ACCESS_CP15(CRn, Op1, CRm, Op2) \
- "mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
-#define __ACCESS_CP15_64(Op1, CRm) \
- "mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
-
-#define __read_sysreg(r, w, c, t) ({ \
- t __val; \
- asm volatile(r " " c : "=r" (__val)); \
- __val; \
-})
-#define read_sysreg(...) __read_sysreg(__VA_ARGS__)
-
-#define __write_sysreg(v, r, w, c, t) asm volatile(w " " c : : "r" ((t)(v)))
-#define write_sysreg(v, ...) __write_sysreg(v, __VA_ARGS__)
-
-#define BPIALL __ACCESS_CP15(c7, 0, c5, 6)
-#define ICIALLU __ACCESS_CP15(c7, 0, c5, 0)
-
-#define CNTVCT __ACCESS_CP15_64(1, c14)
+#include <asm/common/cp15.h>

extern unsigned long cr_alignment; /* defined in entry-armv.S */

diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 614bf829e454..c098d95a88fa 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -14,6 +14,7 @@
#include <asm/ptrace.h>
#include <asm/types.h>
#include <asm/unified.h>
+#include <asm/common/processor.h>

#ifdef __KERNEL__
#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \
@@ -85,16 +86,6 @@ extern void release_thread(struct task_struct *);

unsigned long get_wchan(struct task_struct *p);

-#if __LINUX_ARM_ARCH__ == 6 || defined(CONFIG_ARM_ERRATA_754327)
-#define cpu_relax() \
- do { \
- smp_mb(); \
- __asm__ __volatile__("nop; nop; nop; nop; nop; nop; nop; nop; nop; nop;"); \
- } while (0)
-#else
-#define cpu_relax() barrier()
-#endif
-
#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)

diff --git a/arch/arm/include/asm/vdso/gettimeofday.h b/arch/arm/include/asm/vdso/gettimeofday.h
index fe6e1f65932d..ffb88cef8cbb 100644
--- a/arch/arm/include/asm/vdso/gettimeofday.h
+++ b/arch/arm/include/asm/vdso/gettimeofday.h
@@ -7,9 +7,9 @@

#ifndef __ASSEMBLY__

-#include <asm/barrier.h>
-#include <asm/cp15.h>
+#include <asm/errno.h>
#include <asm/unistd.h>
+#include <asm/common/cp15.h>
#include <uapi/linux/time.h>

#define VDSO_HAS_CLOCK_GETRES 1
--
2.25.1

2020-03-06 13:34:56

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 19/20] lib: vdso: Enable common headers

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Refactor the unified vdso code to use the common headers.

Cc: Andy Lutomirski <[email protected]>
Cc: Thomas Gleixner <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/vdso/datapage.h | 32 +++++++++++++++++++++++++++++---
lib/vdso/gettimeofday.c | 21 ---------------------
2 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/include/vdso/datapage.h b/include/vdso/datapage.h
index c5f347cc5e55..21842a73cbcf 100644
--- a/include/vdso/datapage.h
+++ b/include/vdso/datapage.h
@@ -4,9 +4,19 @@

#ifndef __ASSEMBLY__

-#include <linux/bits.h>
-#include <linux/time.h>
-#include <linux/types.h>
+#include <linux/compiler.h>
+#include <uapi/linux/time.h>
+#include <uapi/linux/types.h>
+#include <uapi/asm-generic/errno-base.h>
+
+#include <common/bits.h>
+#include <common/ktime.h>
+#include <common/limits.h>
+#include <common/math64.h>
+#include <common/processor.h>
+#include <common/time.h>
+#include <common/time32.h>
+#include <common/time64.h>

#define VDSO_BASES (CLOCK_TAI + 1)
#define VDSO_HRES (BIT(CLOCK_REALTIME) | \
@@ -101,6 +111,22 @@ struct vdso_data {
*/
extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden")));

+/*
+ * The generic vDSO implementation requires that gettimeofday.h
+ * provides:
+ * - __arch_get_vdso_data(): to get the vdso datapage.
+ * - __arch_get_hw_counter(): to get the hw counter based on the
+ * clock_mode.
+ * - gettimeofday_fallback(): fallback for gettimeofday.
+ * - clock_gettime_fallback(): fallback for clock_gettime.
+ * - clock_getres_fallback(): fallback for clock_getres.
+ */
+#ifdef ENABLE_COMPAT_VDSO
+#include <asm/vdso/compat_gettimeofday.h>
+#else
+#include <asm/vdso/gettimeofday.h>
+#endif /* ENABLE_COMPAT_VDSO */
+
#endif /* !__ASSEMBLY__ */

#endif /* __VDSO_DATAPAGE_H */
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index f8b8ec5e63ac..e3244f74feea 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -2,30 +2,9 @@
/*
* Generic userspace implementations of gettimeofday() and similar.
*/
-#include <linux/compiler.h>
-#include <linux/math64.h>
-#include <linux/time.h>
-#include <linux/kernel.h>
-#include <linux/hrtimer_defs.h>
#include <vdso/datapage.h>
#include <vdso/helpers.h>

-/*
- * The generic vDSO implementation requires that gettimeofday.h
- * provides:
- * - __arch_get_vdso_data(): to get the vdso datapage.
- * - __arch_get_hw_counter(): to get the hw counter based on the
- * clock_mode.
- * - gettimeofday_fallback(): fallback for gettimeofday.
- * - clock_gettime_fallback(): fallback for clock_gettime.
- * - clock_getres_fallback(): fallback for clock_getres.
- */
-#ifdef ENABLE_COMPAT_VDSO
-#include <asm/vdso/compat_gettimeofday.h>
-#else
-#include <asm/vdso/gettimeofday.h>
-#endif /* ENABLE_COMPAT_VDSO */
-
#ifndef vdso_calc_delta
/*
* Default implementation which works for all sane clocksources. That
--
2.25.1

2020-03-06 13:34:57

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 06/20] linux/time32.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split time32.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/time32.h | 17 +++++++++++++++++
include/linux/time32.h | 13 +------------
2 files changed, 18 insertions(+), 12 deletions(-)
create mode 100644 include/common/time32.h

diff --git a/include/common/time32.h b/include/common/time32.h
new file mode 100644
index 000000000000..d5b85abdfaf1
--- /dev/null
+++ b/include/common/time32.h
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_TIME32_H
+#define __COMMON_TIME32_H
+
+typedef s32 old_time32_t;
+
+struct old_timespec32 {
+ old_time32_t tv_sec;
+ s32 tv_nsec;
+};
+
+struct old_timeval32 {
+ old_time32_t tv_sec;
+ s32 tv_usec;
+};
+
+#endif /* __COMMON_TIME32_H */
diff --git a/include/linux/time32.h b/include/linux/time32.h
index cf9320cd2d0b..e75dd5f9df8f 100644
--- a/include/linux/time32.h
+++ b/include/linux/time32.h
@@ -11,18 +11,7 @@

#include <linux/time64.h>
#include <linux/timex.h>
-
-typedef s32 old_time32_t;
-
-struct old_timespec32 {
- old_time32_t tv_sec;
- s32 tv_nsec;
-};
-
-struct old_timeval32 {
- old_time32_t tv_sec;
- s32 tv_usec;
-};
+#include <common/time32.h>

struct old_itimerspec32 {
struct old_timespec32 it_interval;
--
2.25.1

2020-03-06 13:35:05

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 09/20] linux/ktime.h: Extract common header for vDSO

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Split ktime.h into linux and common headers to make the latter suitable
for inclusion in the vDSO library.

Signed-off-by: Vincenzo Frascino <[email protected]>
---
include/common/ktime.h | 16 ++++++++++++++++
include/linux/ktime.h | 9 +--------
2 files changed, 17 insertions(+), 8 deletions(-)
create mode 100644 include/common/ktime.h

diff --git a/include/common/ktime.h b/include/common/ktime.h
new file mode 100644
index 000000000000..4dd6c6762ad4
--- /dev/null
+++ b/include/common/ktime.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __COMMON_KTIME_H
+#define __COMMON_KTIME_H
+
+#include <common/jiffies.h>
+
+/*
+ * The resolution of the clocks. The resolution value is returned in
+ * the clock_getres() system call to give application programmers an
+ * idea of the (in)accuracy of timers. Timer values are rounded up to
+ * this resolution values.
+ */
+#define LOW_RES_NSEC TICK_NSEC
+#define KTIME_LOW_RES (LOW_RES_NSEC)
+
+#endif /* __COMMON_KTIME_H */
diff --git a/include/linux/ktime.h b/include/linux/ktime.h
index d1fb05135665..c456b33c80e1 100644
--- a/include/linux/ktime.h
+++ b/include/linux/ktime.h
@@ -216,14 +216,7 @@ static inline __must_check bool ktime_to_timespec64_cond(const ktime_t kt,
}
}

-/*
- * The resolution of the clocks. The resolution value is returned in
- * the clock_getres() system call to give application programmers an
- * idea of the (in)accuracy of timers. Timer values are rounded up to
- * this resolution values.
- */
-#define LOW_RES_NSEC TICK_NSEC
-#define KTIME_LOW_RES (LOW_RES_NSEC)
+#include <common/ktime.h>

static inline ktime_t ns_to_ktime(u64 ns)
{
--
2.25.1

2020-03-06 13:35:14

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 15/20] arm64: Introduce asm/common/arch_timer.h

The vDSO library should only include the necessary headers required for
a userspace library (UAPI and a minimal set of kernel headers). To make
this possible it is necessary to isolate from the kernel headers the
common parts that are strictly necessary to build the library.

Introduce asm/common/arch_timer.h to contain all the arm64 specific
code. This allows to replace the second isb() in __arch_get_hw_counter()
with a fake dependent stack read of the counter which improves the vdso
library peformances of ~4.5%. Below the results of vdsotest [1] ran for
100 iterations.

Before the patch:
=================
clock-gettime-monotonic: syscall: 771 nsec/call
clock-gettime-monotonic: libc: 130 nsec/call
clock-gettime-monotonic: vdso: 111 nsec/call
...
clock-gettime-realtime: syscall: 762 nsec/call
clock-gettime-realtime: libc: 130 nsec/call
clock-gettime-realtime: vdso: 111 nsec/call

After the patch:
================
clock-gettime-monotonic: syscall: 792 nsec/call
clock-gettime-monotonic: libc: 124 nsec/call
clock-gettime-monotonic: vdso: 106 nsec/call
...
clock-gettime-realtime: syscall: 776 nsec/call
clock-gettime-realtime: libc: 124 nsec/call
clock-gettime-realtime: vdso: 106 nsec/call

[1] https://github.com/nathanlynch/vdsotest

Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/arm64/include/asm/arch_timer.h | 29 ++++---------------
arch/arm64/include/asm/common/arch_timer.h | 33 ++++++++++++++++++++++
arch/arm64/include/asm/vdso/gettimeofday.h | 7 +++--
3 files changed, 42 insertions(+), 27 deletions(-)
create mode 100644 arch/arm64/include/asm/common/arch_timer.h

diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h
index 7ae54d7d333a..6567e20a76b2 100644
--- a/arch/arm64/include/asm/arch_timer.h
+++ b/arch/arm64/include/asm/arch_timer.h
@@ -164,24 +164,7 @@ static inline void arch_timer_set_cntkctl(u32 cntkctl)
isb();
}

-/*
- * Ensure that reads of the counter are treated the same as memory reads
- * for the purposes of ordering by subsequent memory barriers.
- *
- * This insanity brought to you by speculative system register reads,
- * out-of-order memory accesses, sequence locks and Thomas Gleixner.
- *
- * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html
- */
-#define arch_counter_enforce_ordering(val) do { \
- u64 tmp, _val = (val); \
- \
- asm volatile( \
- " eor %0, %1, %1\n" \
- " add %0, sp, %0\n" \
- " ldr xzr, [%0]" \
- : "=r" (tmp) : "r" (_val)); \
-} while (0)
+#include <asm/common/arch_timer.h>

static __always_inline u64 __arch_counter_get_cntpct_stable(void)
{
@@ -189,7 +172,7 @@ static __always_inline u64 __arch_counter_get_cntpct_stable(void)

isb();
cnt = arch_timer_reg_read_stable(cntpct_el0);
- arch_counter_enforce_ordering(cnt);
+ cnt = arch_counter_enforce_ordering(cnt);
return cnt;
}

@@ -199,7 +182,7 @@ static __always_inline u64 __arch_counter_get_cntpct(void)

isb();
cnt = read_sysreg(cntpct_el0);
- arch_counter_enforce_ordering(cnt);
+ cnt = arch_counter_enforce_ordering(cnt);
return cnt;
}

@@ -209,7 +192,7 @@ static __always_inline u64 __arch_counter_get_cntvct_stable(void)

isb();
cnt = arch_timer_reg_read_stable(cntvct_el0);
- arch_counter_enforce_ordering(cnt);
+ cnt = arch_counter_enforce_ordering(cnt);
return cnt;
}

@@ -219,12 +202,10 @@ static __always_inline u64 __arch_counter_get_cntvct(void)

isb();
cnt = read_sysreg(cntvct_el0);
- arch_counter_enforce_ordering(cnt);
+ cnt = arch_counter_enforce_ordering(cnt);
return cnt;
}

-#undef arch_counter_enforce_ordering
-
static inline int arch_timer_arch_init(void)
{
return 0;
diff --git a/arch/arm64/include/asm/common/arch_timer.h b/arch/arm64/include/asm/common/arch_timer.h
new file mode 100644
index 000000000000..b11bd67a366e
--- /dev/null
+++ b/arch/arm64/include/asm/common/arch_timer.h
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (C) 2020 ARM Ltd.
+ */
+#ifndef __ASM_COMMON_ARCH_TIMER_H
+#define __ASM_COMMON_ARCH_TIMER_H
+
+#include <uapi/linux/types.h>
+
+/*
+ * Ensure that reads of the counter are treated the same as memory reads
+ * for the purposes of ordering by subsequent memory barriers.
+ *
+ * This insanity brought to you by speculative system register reads,
+ * out-of-order memory accesses, sequence locks and Thomas Gleixner.
+ *
+ * http://lists.infradead.org/pipermail/linux-arm-kernel/2019-February/631195.html
+ *
+ */
+static u64 arch_counter_enforce_ordering(u64 val)
+{
+ u64 tmp, _val = (val);
+
+ asm volatile(
+ " eor %0, %1, %1\n"
+ " add %0, sp, %0\n"
+ " ldr xzr, [%0]"
+ : "=r" (tmp) : "r" (_val));
+
+ return _val;
+}
+
+#endif /* __ASM_COMMON_ARCH_TIMER_H */
diff --git a/arch/arm64/include/asm/vdso/gettimeofday.h b/arch/arm64/include/asm/vdso/gettimeofday.h
index cc3456416096..628bb3b187c4 100644
--- a/arch/arm64/include/asm/vdso/gettimeofday.h
+++ b/arch/arm64/include/asm/vdso/gettimeofday.h
@@ -8,6 +8,7 @@
#ifndef __ASSEMBLY__

#include <asm/unistd.h>
+#include <asm/common/arch_timer.h>

#define __VDSO_USE_SYSCALL ULLONG_MAX

@@ -83,10 +84,10 @@ static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
isb();
asm volatile("mrs %0, cntvct_el0" : "=r" (res) :: "memory");
/*
- * This isb() is required to prevent that the seq lock is
- * speculated.#
+ * arch_counter_enforce_ordering() is required to prevent that
+ * the seq lock is speculated.
*/
- isb();
+ res = arch_counter_enforce_ordering(res);

return res;
}
--
2.25.1

2020-03-06 13:35:53

by Vincenzo Frascino

[permalink] [raw]
Subject: [PATCH v2 20/20] arm64: vdso32: Enable Clang Compilation

Enable Clang Compilation for the vdso32 library.

Cc: Catalin Marinas <[email protected]>
Cc: Will Deacon <[email protected]>
Signed-off-by: Vincenzo Frascino <[email protected]>
---
arch/arm64/kernel/vdso32/Makefile | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
index 04df57b43cb1..650cfc5757eb 100644
--- a/arch/arm64/kernel/vdso32/Makefile
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -10,7 +10,18 @@ include $(srctree)/lib/vdso/Makefile

# Same as cc-*option, but using CC_COMPAT instead of CC
ifeq ($(CONFIG_CC_IS_CLANG), y)
-CC_COMPAT ?= $(CC)
+COMPAT_GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE_COMPAT)elfedit))
+COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..)
+
+CLANG_CC_COMPAT := $(CC)
+CLANG_CC_COMPAT += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
+CLANG_CC_COMPAT += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
+CLANG_CC_COMPAT += -no-integrated-as -Qunused-arguments
+ifneq ($(COMPAT_GCC_TOOLCHAIN),)
+CLANG_CC_COMPAT += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
+endif
+
+CC_COMPAT ?= $(CLANG_CC_COMPAT)
else
CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc
endif
--
2.25.1

2020-03-06 16:06:08

by Andy Lutomirski

[permalink] [raw]
Subject: Re: [PATCH v2 00/20] Introduce common headers



> On Mar 6, 2020, at 5:32 AM, Vincenzo Frascino <[email protected]> wrote:
>
> Back in July last year we started having a problem in building compat
> vDSOs on arm64 [1] [2] that was not present when the arm64 porting to
> the Unified vDSO was done. In particular when the compat vDSO on such
> architecture is built with gcc it generates the warning below:
>
> In file included from ./arch/arm64/include/asm/thread_info.h:17:0,
> from ./include/linux/thread_info.h:38,
> from ./arch/arm64/include/asm/preempt.h:5,
> from ./include/linux/preempt.h:78,
> from ./include/linux/spinlock.h:51,
> from ./include/linux/seqlock.h:36,
> from ./include/linux/time.h:6,
> from ./lib/vdso/gettimeofday.c:7,
> from <command-line>:0:
> ./arch/arm64/include/asm/memory.h: In function ‘__tag_set’:
> ./arch/arm64/include/asm/memory.h:233:15: warning: cast from pointer
> to integer of different size [-Wpointer-to-int-cast]
> u64 __addr = (u64)addr & ~__tag_shifted(0xff);
> ^
> In file included from ./arch/arm64/include/asm/pgtable-hwdef.h:8:0,
> from ./arch/arm64/include/asm/processor.h:34,
> from ./arch/arm64/include/asm/elf.h:118,
> from ./include/linux/elf.h:5,
> from ./include/linux/elfnote.h:62,
> from arch/arm64/kernel/vdso32/note.c:11:
> ./arch/arm64/include/asm/memory.h: In function ‘__tag_set’:
> ./arch/arm64/include/asm/memory.h:233:15: warning: cast from pointer
> to integer of different size [-Wpointer-to-int-cast]
> u64 __addr = (u64)addr & ~__tag_shifted(0xff);
>
> The same porting does not build at all when the selected compiler is
> clang.
>
> I started an investigation to try to understand better the problem and
> after various discussions at Plumbers and Recipes last year the
> conclusion was that the vDSO library as it stands it is including more
> headers that it needs. In particular, being a user-space library, it
> should require only the UAPI and a minimal vDSO kernel interface instead
> of all the kernel-related inline functions which are not directly used
> and in some cases can have side effects.
>
> To solve the problem, I decided to use the approach below:
> * Extract from include/linux/ the vDSO required kernel interface
> and place it in include/common/

I really like the approach, but I’m wondering if “common” is the right name. This directory is headers that aren’t stable ABI like uapi but are shared between the kernel and the vDSO. Regular user code should *not* include these, right?

Would “vdso” or perhaps “private-abi” be clearer?

> * Make sure that where meaningful the kernel includes "common"
> * Limit the vDSO library to include headers coming only from UAPI
> and "common" (with 2 exceptions compiler.h for barriers and
> param.h for HZ).
> * Adapt all the architectures that support the unified vDSO library
> to use "common" headers.

>
> According to me this approach allows up to exercise a better control on
> what the vDSO library can include and to prevent potential issues in
> future.
>
> This patch series contains the implementation of the described approach.
>
> The "common" headers have been verified on all the architectures that support
> unified vDSO using the vdsotest [3] testsuite for what concerns the vDSO part
> and randconfig to verify that they are included in the correct places.
>
> To simplify the testing, a copy of the patchset on top of a recent linux
> tree can be found at [4].
>
> [1] https://github.com/ClangBuiltLinux/linux/issues/595
> [2] https://lore.kernel.org/lkml/[email protected]
> [3] https://github.com/nathanlynch/vdsotest
> [4] git://linux-arm.org/linux-vf.git common-headers/v2
>
> Changes:
> --------
> v2:
> - Addressed review comments for clang support.
> - Rebased on 5.6-rc4.
>
> Cc: Catalin Marinas <[email protected]>
> Cc: Will Deacon <[email protected]>
> Cc: Arnd Bergmann <[email protected]>
> Cc: Russell King <[email protected]>
> Cc: Paul Burton <[email protected]>
> Cc: Thomas Gleixner <[email protected]>
> Cc: Andy Lutomirski <[email protected]>
> Cc: Ingo Molnar <[email protected]>
> Cc: Borislav Petkov <[email protected]>
> Cc: Stephen Boyd <[email protected]>
> Cc: Mark Salyzyn <[email protected]>
> Cc: Kees Cook <[email protected]>
> Cc: Peter Collingbourne <[email protected]>
> Cc: Dmitry Safonov <[email protected]>
> Cc: Andrei Vagin <[email protected]>
> Cc: Nick Desaulniers <[email protected]>
> Signed-off-by: Vincenzo Frascino <[email protected]>
>
> Vincenzo Frascino (20):
> linux/const.h: Extract common header for vDSO
> linux/bits.h: Extract common header for vDSO
> linux/limits.h: Extract common header for vDSO
> linux/math64.h: Extract common header for vDSO
> linux/time.h: Extract common header for vDSO
> linux/time32.h: Extract common header for vDSO
> linux/time64.h: Extract common header for vDSO
> linux/jiffies.h: Extract common header for vDSO
> linux/ktime.h: Extract common header for vDSO
> common: Introduce processor.h
> linux/elfnote.h: Replace elf.h with UAPI equivalent
> arm64: Introduce asm/common/processor.h
> arm64: vdso: Include common headers in the vdso library
> arm64: vdso32: Include common headers in the vdso library
> arm64: Introduce asm/common/arch_timer.h
> mips: vdso: Enable mips to use common headers
> x86: vdso: Enable x86 to use common headers
> arm: vdso: Enable arm to use common headers
> lib: vdso: Enable common headers
> arm64: vdso32: Enable Clang Compilation
>
> arch/arm/include/asm/common/cp15.h | 38 +++++++++++++++++++
> arch/arm/include/asm/common/processor.h | 22 +++++++++++
> arch/arm/include/asm/cp15.h | 20 +---------
> arch/arm/include/asm/processor.h | 11 +-----
> arch/arm/include/asm/vdso/gettimeofday.h | 4 +-
> arch/arm64/include/asm/arch_timer.h | 29 +++-----------
> arch/arm64/include/asm/common/arch_timer.h | 33 ++++++++++++++++
> arch/arm64/include/asm/common/processor.h | 31 +++++++++++++++
> arch/arm64/include/asm/processor.h | 16 +-------
> .../include/asm/vdso/compat_gettimeofday.h | 2 +-
> arch/arm64/include/asm/vdso/gettimeofday.h | 8 ++--
> arch/arm64/kernel/vdso/vgettimeofday.c | 2 -
> arch/arm64/kernel/vdso32/Makefile | 13 ++++++-
> arch/arm64/kernel/vdso32/vgettimeofday.c | 3 --
> arch/mips/include/asm/common/processor.h | 27 +++++++++++++
> arch/mips/include/asm/processor.h | 16 +-------
> arch/mips/include/asm/vdso/gettimeofday.h | 4 --
> arch/x86/include/asm/common/processor.h | 23 +++++++++++
> arch/x86/include/asm/processor.h | 12 +-----
> include/common/bits.h | 9 +++++
> include/common/const.h | 10 +++++
> include/common/jiffies.h | 11 ++++++
> include/common/ktime.h | 16 ++++++++
> include/common/limits.h | 18 +++++++++
> include/common/math64.h | 24 ++++++++++++
> include/common/processor.h | 14 +++++++
> include/common/time.h | 12 ++++++
> include/common/time32.h | 17 +++++++++
> include/common/time64.h | 14 +++++++
> include/linux/bits.h | 2 +-
> include/linux/const.h | 5 +--
> include/linux/elfnote.h | 2 +-
> include/linux/jiffies.h | 4 +-
> include/linux/ktime.h | 9 +----
> include/linux/limits.h | 13 +------
> include/linux/math64.h | 20 +---------
> include/linux/time.h | 5 +--
> include/linux/time32.h | 13 +------
> include/linux/time64.h | 10 +----
> include/vdso/datapage.h | 32 ++++++++++++++--
> lib/vdso/gettimeofday.c | 21 ----------
> 41 files changed, 388 insertions(+), 207 deletions(-)
> create mode 100644 arch/arm/include/asm/common/cp15.h
> create mode 100644 arch/arm/include/asm/common/processor.h
> create mode 100644 arch/arm64/include/asm/common/arch_timer.h
> create mode 100644 arch/arm64/include/asm/common/processor.h
> create mode 100644 arch/mips/include/asm/common/processor.h
> create mode 100644 arch/x86/include/asm/common/processor.h
> create mode 100644 include/common/bits.h
> create mode 100644 include/common/const.h
> create mode 100644 include/common/jiffies.h
> create mode 100644 include/common/ktime.h
> create mode 100644 include/common/limits.h
> create mode 100644 include/common/math64.h
> create mode 100644 include/common/processor.h
> create mode 100644 include/common/time.h
> create mode 100644 include/common/time32.h
> create mode 100644 include/common/time64.h
>
> --
> 2.25.1
>

2020-03-07 01:24:02

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v2 11/20] linux/elfnote.h: Replace elf.h with UAPI equivalent

Hi Vincenzo,

I love your patch! Perhaps something to improve:

[auto build test WARNING on arm64/for-next/core]
[also build test WARNING on linus/master v5.6-rc4 next-20200306]
[cannot apply to tip/x86/core tip/timers/vdso]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/Vincenzo-Frascino/Introduce-common-headers/20200307-042945
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
config: parisc-generic-64bit_defconfig (attached as .config)
compiler: hppa64-linux-gcc (GCC) 7.5.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.5.0 make.cross ARCH=parisc

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <[email protected]>

All warnings (new ones prefixed by >>):

In file included from include/linux/elf.h:5:0,
from include/linux/module.h:18,
from crypto/arc4.mod.c:2:
>> arch/parisc/include/asm/elf.h:324:0: warning: "ELF_OSABI" redefined
#define ELF_OSABI ELFOSABI_LINUX

In file included from include/linux/elfnote.h:62:0,
from include/linux/build-salt.h:4,
from crypto/arc4.mod.c:1:
include/uapi/linux/elf.h:363:0: note: this is the location of the previous definition
#define ELF_OSABI ELFOSABI_NONE


vim +/ELF_OSABI +324 arch/parisc/include/asm/elf.h

^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 312
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 313
71d577db01a5177 arch/parisc/include/asm/elf.h Helge Deller 2018-04-11 314 #define elf_check_arch(x) \
71d577db01a5177 arch/parisc/include/asm/elf.h Helge Deller 2018-04-11 315 ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELF_CLASS)
71d577db01a5177 arch/parisc/include/asm/elf.h Helge Deller 2018-04-11 316 #define compat_elf_check_arch(x) \
71d577db01a5177 arch/parisc/include/asm/elf.h Helge Deller 2018-04-11 317 ((x)->e_machine == EM_PARISC && (x)->e_ident[EI_CLASS] == ELFCLASS32)
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 318
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 319 /*
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 320 * These are used to set parameters in the core dumps.
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 321 */
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 322 #define ELF_DATA ELFDATA2MSB
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 323 #define ELF_ARCH EM_PARISC
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 @324 #define ELF_OSABI ELFOSABI_LINUX
^1da177e4c3f415 include/asm-parisc/elf.h Linus Torvalds 2005-04-16 325

:::::: The code at line 324 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2

:::::: TO: Linus Torvalds <[email protected]>
:::::: CC: Linus Torvalds <[email protected]>

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (3.53 kB)
.config.gz (19.53 kB)
Download all attachments

2020-03-09 11:08:32

by Vincenzo Frascino

[permalink] [raw]
Subject: Re: [PATCH v2 00/20] Introduce common headers

Hi Andy,

On 3/6/20 4:04 PM, Andy Lutomirski wrote:

[...]

>>
>> To solve the problem, I decided to use the approach below:
>> * Extract from include/linux/ the vDSO required kernel interface
>> and place it in include/common/
>
> I really like the approach, but I’m wondering if “common” is the right name. This directory is headers that aren’t stable ABI like uapi but are shared between the kernel and the vDSO. Regular user code should *not* include these, right?
>
> Would “vdso” or perhaps “private-abi” be clearer?
>

Thanks! These headers are definitely not "uapi" like and they are meant to
evolve in future like any other kernel header. We have just to make sure that
the evolution does not break what we are trying to achieve with this series.

I have to admit that I spent quite some time in choosing the name and I am not
completely satisfied with "common" either. The reason why I ended up with this
is that the headers are common in between the kernel and the vdso (userspace)
but I agree that it does not make completely self explanatory.

Using "vdso" would mean according to me that those are vdso only headers,
probably "private-abi" is the best choice here. If there is enough consensus, I
am happy to rework my patches accordingly. What do you think?

>> * Make sure that where meaningful the kernel includes "common"
>> * Limit the vDSO library to include headers coming only from UAPI
>> and "common" (with 2 exceptions compiler.h for barriers and
>> param.h for HZ).
>> * Adapt all the architectures that support the unified vDSO library
>> to use "common" headers.
>
[...]

--
Regards,
Vincenzo

2020-03-09 12:26:07

by Mark Rutland

[permalink] [raw]
Subject: Re: [PATCH v2 00/20] Introduce common headers

On Mon, Mar 09, 2020 at 11:07:08AM +0000, Vincenzo Frascino wrote:
> Hi Andy,
>
> On 3/6/20 4:04 PM, Andy Lutomirski wrote:
>
> [...]
>
> >>
> >> To solve the problem, I decided to use the approach below:
> >> * Extract from include/linux/ the vDSO required kernel interface
> >> and place it in include/common/
> >
> > I really like the approach, but I’m wondering if “common” is the
> > right name. This directory is headers that aren’t stable ABI like
> > uapi but are shared between the kernel and the vDSO. Regular user
> > code should *not* include these, right?
> >
> > Would “vdso” or perhaps “private-abi” be clearer?
>
> Thanks! These headers are definitely not "uapi" like and they are meant to
> evolve in future like any other kernel header. We have just to make sure that
> the evolution does not break what we are trying to achieve with this series.

Given we already include uapi/* headers in kernel code, I think placing
these in a vdso/* namespace would be fine. I think that more clearly
expresses the constraints on the headers than private-abi/* would.

Thanks,
Mark.

2020-03-09 19:24:26

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [PATCH v2 00/20] Introduce common headers

Mark Rutland <[email protected]> writes:
> On Mon, Mar 09, 2020 at 11:07:08AM +0000, Vincenzo Frascino wrote:
>> On 3/6/20 4:04 PM, Andy Lutomirski wrote:
>> >> To solve the problem, I decided to use the approach below:
>> >> * Extract from include/linux/ the vDSO required kernel interface
>> >> and place it in include/common/
>> >
>> > I really like the approach, but I’m wondering if “common” is the
>> > right name. This directory is headers that aren’t stable ABI like
>> > uapi but are shared between the kernel and the vDSO. Regular user
>> > code should *not* include these, right?
>> >
>> > Would “vdso” or perhaps “private-abi” be clearer?
>>
>> Thanks! These headers are definitely not "uapi" like and they are meant to
>> evolve in future like any other kernel header. We have just to make sure that
>> the evolution does not break what we are trying to achieve with this series.
>
> Given we already include uapi/* headers in kernel code, I think placing
> these in a vdso/* namespace would be fine. I think that more clearly
> expresses the constraints on the headers than private-abi/* would.

Yes, that makes most sense.

Thanks,

tglx

2020-03-10 01:41:14

by Nathan Chancellor

[permalink] [raw]
Subject: Re: [PATCH v2 20/20] arm64: vdso32: Enable Clang Compilation

On Fri, Mar 06, 2020 at 01:32:42PM +0000, Vincenzo Frascino wrote:
> Enable Clang Compilation for the vdso32 library.
>
> Cc: Catalin Marinas <[email protected]>
> Cc: Will Deacon <[email protected]>
> Signed-off-by: Vincenzo Frascino <[email protected]>
> ---
> arch/arm64/kernel/vdso32/Makefile | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
> index 04df57b43cb1..650cfc5757eb 100644
> --- a/arch/arm64/kernel/vdso32/Makefile
> +++ b/arch/arm64/kernel/vdso32/Makefile
> @@ -10,7 +10,18 @@ include $(srctree)/lib/vdso/Makefile
>
> # Same as cc-*option, but using CC_COMPAT instead of CC
> ifeq ($(CONFIG_CC_IS_CLANG), y)
> -CC_COMPAT ?= $(CC)
> +COMPAT_GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE_COMPAT)elfedit))
> +COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..)
> +
> +CLANG_CC_COMPAT := $(CC)
> +CLANG_CC_COMPAT += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
> +CLANG_CC_COMPAT += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
> +CLANG_CC_COMPAT += -no-integrated-as -Qunused-arguments
> +ifneq ($(COMPAT_GCC_TOOLCHAIN),)
> +CLANG_CC_COMPAT += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
> +endif
> +
> +CC_COMPAT ?= $(CLANG_CC_COMPAT)
> else
> CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc
> endif
> --
> 2.25.1
>
If CC_COMPAT is ever specified on the command line as clang (maybe by
some unsuspecting user), we'd loose all of the above flags. Maybe it
would be better to build a set of COMPAT_CLANG_FLAGS and append them to
CC_COMPAT, maybe like below?

Regardless, the current approach works in my testing with clang 9.0.1
and master (clang 11.0.0). This patch specifically is:

Reviewed-by: Nathan Chancellor <[email protected]>
Tested-by: Nathan Chancellor <[email protected]> # build

==================================================================================

diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
index 650cfc5757eb..df5145fab287 100644
--- a/arch/arm64/kernel/vdso32/Makefile
+++ b/arch/arm64/kernel/vdso32/Makefile
@@ -13,15 +13,16 @@ ifeq ($(CONFIG_CC_IS_CLANG), y)
COMPAT_GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE_COMPAT)elfedit))
COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..)

-CLANG_CC_COMPAT := $(CC)
-CLANG_CC_COMPAT += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
-CLANG_CC_COMPAT += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
-CLANG_CC_COMPAT += -no-integrated-as -Qunused-arguments
+COMPAT_CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
+COMPAT_CLANG_FLAGS += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
+COMPAT_CLANG_FLAGS += -no-integrated-as -Qunused-arguments
ifneq ($(COMPAT_GCC_TOOLCHAIN),)
-CLANG_CC_COMPAT += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
+COMPAT_CLANG_FLAGS += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
endif

-CC_COMPAT ?= $(CLANG_CC_COMPAT)
+CC_COMPAT ?= $(CC)
+CC_COMPAT += $(COMPAT_CLANG_FLAGS)
+
else
CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc
endif

2020-03-13 12:02:55

by Vincenzo Frascino

[permalink] [raw]
Subject: Re: [PATCH v2 20/20] arm64: vdso32: Enable Clang Compilation

On 3/10/20 1:40 AM, Nathan Chancellor wrote:
> On Fri, Mar 06, 2020 at 01:32:42PM +0000, Vincenzo Frascino wrote:
>> Enable Clang Compilation for the vdso32 library.
>>
>> Cc: Catalin Marinas <[email protected]>
>> Cc: Will Deacon <[email protected]>
>> Signed-off-by: Vincenzo Frascino <[email protected]>
>> ---
>> arch/arm64/kernel/vdso32/Makefile | 13 ++++++++++++-
>> 1 file changed, 12 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
>> index 04df57b43cb1..650cfc5757eb 100644
>> --- a/arch/arm64/kernel/vdso32/Makefile
>> +++ b/arch/arm64/kernel/vdso32/Makefile
>> @@ -10,7 +10,18 @@ include $(srctree)/lib/vdso/Makefile
>>
>> # Same as cc-*option, but using CC_COMPAT instead of CC
>> ifeq ($(CONFIG_CC_IS_CLANG), y)
>> -CC_COMPAT ?= $(CC)
>> +COMPAT_GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE_COMPAT)elfedit))
>> +COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..)
>> +
>> +CLANG_CC_COMPAT := $(CC)
>> +CLANG_CC_COMPAT += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
>> +CLANG_CC_COMPAT += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
>> +CLANG_CC_COMPAT += -no-integrated-as -Qunused-arguments
>> +ifneq ($(COMPAT_GCC_TOOLCHAIN),)
>> +CLANG_CC_COMPAT += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
>> +endif
>> +
>> +CC_COMPAT ?= $(CLANG_CC_COMPAT)
>> else
>> CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc
>> endif
>> --
>> 2.25.1
>>
> If CC_COMPAT is ever specified on the command line as clang (maybe by
> some unsuspecting user), we'd loose all of the above flags. Maybe it
> would be better to build a set of COMPAT_CLANG_FLAGS and append them to
> CC_COMPAT, maybe like below?
>

Fine by me.

> Regardless, the current approach works in my testing with clang 9.0.1
> and master (clang 11.0.0). This patch specifically is:
>

Good to hear. I will add your tags to the patch.

> Reviewed-by: Nathan Chancellor <[email protected]>
> Tested-by: Nathan Chancellor <[email protected]> # build
>
> ==================================================================================
>
> diff --git a/arch/arm64/kernel/vdso32/Makefile b/arch/arm64/kernel/vdso32/Makefile
> index 650cfc5757eb..df5145fab287 100644
> --- a/arch/arm64/kernel/vdso32/Makefile
> +++ b/arch/arm64/kernel/vdso32/Makefile
> @@ -13,15 +13,16 @@ ifeq ($(CONFIG_CC_IS_CLANG), y)
> COMPAT_GCC_TOOLCHAIN_DIR := $(dir $(shell which $(CROSS_COMPILE_COMPAT)elfedit))
> COMPAT_GCC_TOOLCHAIN := $(realpath $(COMPAT_GCC_TOOLCHAIN_DIR)/..)
>
> -CLANG_CC_COMPAT := $(CC)
> -CLANG_CC_COMPAT += --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
> -CLANG_CC_COMPAT += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
> -CLANG_CC_COMPAT += -no-integrated-as -Qunused-arguments
> +COMPAT_CLANG_FLAGS := --target=$(notdir $(CROSS_COMPILE_COMPAT:%-=%))
> +COMPAT_CLANG_FLAGS += --prefix=$(COMPAT_GCC_TOOLCHAIN_DIR)
> +COMPAT_CLANG_FLAGS += -no-integrated-as -Qunused-arguments
> ifneq ($(COMPAT_GCC_TOOLCHAIN),)
> -CLANG_CC_COMPAT += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
> +COMPAT_CLANG_FLAGS += --gcc-toolchain=$(COMPAT_GCC_TOOLCHAIN)
> endif
>
> -CC_COMPAT ?= $(CLANG_CC_COMPAT)
> +CC_COMPAT ?= $(CC)
> +CC_COMPAT += $(COMPAT_CLANG_FLAGS)
> +
> else
> CC_COMPAT ?= $(CROSS_COMPILE_COMPAT)gcc
> endif
>

--
Regards,
Vincenzo