Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1391270 > unrolled thread
| Started by | Catalin Marinas <catalin.marinas@arm.com> |
|---|---|
| First post | 2016-04-29 18:10 +0200 |
| Last post | 2016-05-03 11:10 +0200 |
| Articles | 12 — 5 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Catalin Marinas <catalin.marinas@arm.com> - 2016-04-29 18:10 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Arnd Bergmann <arnd@arndb.de> - 2016-04-29 19:40 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Arnd Bergmann <arnd@arndb.de> - 2016-05-03 11:10 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> - 2016-05-03 13:20 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> - 2016-05-03 14:50 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov <ynorov@caviumnetworks.com> - 2016-05-05 00:00 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Andrew Pinski <pinskia@gmail.com> - 2016-05-05 01:30 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> - 2016-05-05 04:30 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Andrew Pinski <pinskia@gmail.com> - 2016-05-05 08:50 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> - 2016-05-09 12:20 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Yury Norov <ynorov@caviumnetworks.com> - 2016-05-05 10:30 +0200
Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return Catalin Marinas <catalin.marinas@arm.com> - 2016-05-03 11:10 +0200
| From | Catalin Marinas <catalin.marinas@arm.com> |
|---|---|
| Date | 2016-04-29 18:10 +0200 |
| Subject | Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return |
| Message-ID | <rtj9o-xI-3@gated-at.bofh.it> |
On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote: > ILP32 VDSO exports next symbols: > __kernel_rt_sigreturn; > __kernel_gettimeofday; > __kernel_clock_gettime; > __kernel_clock_getres; [...] > +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S > + $(call if_changed_dep,vdso-ilp32as) Are struct timeval and timespec the same between ILP32 and LP64? For example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in asm-offsets.c based on the LP64 timeval. > +$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S > + $(call if_changed_dep,vdso-ilp32as) This one should be fine because ILP32 uses the same generic __NR_rt_sigreturn syscall number. -- Catalin
[toc] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-04-29 19:40 +0200 |
| Subject | Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return |
| Message-ID | <rtkyu-1rQ-3@gated-at.bofh.it> |
| In reply to | #1391270 |
On Friday 29 April 2016 17:01:55 Catalin Marinas wrote: > On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote: > > ILP32 VDSO exports next symbols: > > __kernel_rt_sigreturn; > > __kernel_gettimeofday; > > __kernel_clock_gettime; > > __kernel_clock_getres; > > [...] > > > +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S > > + $(call if_changed_dep,vdso-ilp32as) > > Are struct timeval and timespec the same between ILP32 and LP64? For > example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in > asm-offsets.c based on the LP64 timeval. No, ilp32 uses the generic 32-bit data structures, which have a 32-bit time_t. I guess that means it can work for little-endian but not big-endian, right? Arnd
[toc] | [prev] | [next] | [standalone]
| From | Arnd Bergmann <arnd@arndb.de> |
|---|---|
| Date | 2016-05-03 11:10 +0200 |
| Subject | Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return |
| Message-ID | <ruEv7-5nI-1@gated-at.bofh.it> |
| In reply to | #1391302 |
On Tuesday 03 May 2016 10:00:45 Catalin Marinas wrote: > On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote: > > On Friday 29 April 2016 17:01:55 Catalin Marinas wrote: > > > On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote: > > > > ILP32 VDSO exports next symbols: > > > > __kernel_rt_sigreturn; > > > > __kernel_gettimeofday; > > > > __kernel_clock_gettime; > > > > __kernel_clock_getres; > > > > > > [...] > > > > > > > +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S > > > > + $(call if_changed_dep,vdso-ilp32as) > > > > > > Are struct timeval and timespec the same between ILP32 and LP64? For > > > example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in > > > asm-offsets.c based on the LP64 timeval. > > > > No, ilp32 uses the generic 32-bit data structures, which have a 32-bit > > time_t. I guess that means it can work for little-endian but not > > big-endian, right? > > I don't think it works for little-endian either. The LP64 struct timeval > is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is > storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC]) You are right. Yury asked pointed out the same thing on IRC as well. Using the 64-bit gettimeofday() will put the right number in the .tv_sec member on little-endian, but will write zeroes to tv_nsec and corrupt the memory following it. Yury also tried it out and noticed that for a (so far) unknown reason, the vdso gets never used by his glibc build, so it has not triggered any test case failures. Arnd
[toc] | [prev] | [next] | [standalone]
| From | "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> |
|---|---|
| Date | 2016-05-03 13:20 +0200 |
| Message-ID | <ruGwW-7bI-13@gated-at.bofh.it> |
| In reply to | #1393208 |
On 2016/5/3 17:05, Arnd Bergmann wrote:
> On Tuesday 03 May 2016 10:00:45 Catalin Marinas wrote:
>> On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote:
>>> On Friday 29 April 2016 17:01:55 Catalin Marinas wrote:
>>>> On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
>>>>> ILP32 VDSO exports next symbols:
>>>>> __kernel_rt_sigreturn;
>>>>> __kernel_gettimeofday;
>>>>> __kernel_clock_gettime;
>>>>> __kernel_clock_getres;
>>>>
>>>> [...]
>>>>
>>>>> +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
>>>>> + $(call if_changed_dep,vdso-ilp32as)
>>>>
>>>> Are struct timeval and timespec the same between ILP32 and LP64? For
>>>> example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
>>>> asm-offsets.c based on the LP64 timeval.
>>>
>>> No, ilp32 uses the generic 32-bit data structures, which have a 32-bit
>>> time_t. I guess that means it can work for little-endian but not
>>> big-endian, right?
>>
>> I don't think it works for little-endian either. The LP64 struct timeval
>> is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is
>> storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC])
>
> You are right. Yury asked pointed out the same thing on IRC as well.
> Using the 64-bit gettimeofday() will put the right number in the
> .tv_sec member on little-endian, but will write zeroes to tv_nsec
> and corrupt the memory following it.
>
> Yury also tried it out and noticed that for a (so far) unknown reason,
> the vdso gets never used by his glibc build, so it has not triggered
> any test case failures.
We found this issue too. And it is because the version is different from
the glibc wanted. We define 2.6.39 for lp64 but 2.6 for ilp32 in vdso
in kernel:
+VERSION
+{
+ LINUX_2.6 {
+ global:
+ __kernel_rt_sigreturn;
+ __kernel_gettimeofday;
+ __kernel_clock_gettime;
+ __kernel_clock_getres;
+ local: *;
+ };
+}
If I change 2.6 to 2.6.39, the ilp32 application will call vdso instead
of syscall. But the result is wrong as Catalin mentioned before.
Should we set this version to 4.6 or higher version? We will need to update
the version in "sysdeps/unix/sysv/linux/aarch64/init-first.c" too:
static inline void
_libc_vdso_platform_setup (void)
{
PREPARE_VERSION (linux2639, "LINUX_2.6.39", 123718537);
void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639);
PTR_MANGLE (p);
VDSO_SYMBOL(gettimeofday) = p;
p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2639);
PTR_MANGLE (p);
VDSO_SYMBOL(clock_gettime) = p;
p = _dl_vdso_vsym ("__kernel_clock_getres", &linux2639);
PTR_MANGLE (p);
VDSO_SYMBOL(clock_getres) = p;
}
Regards
Bamvor
>
> Arnd
>
[toc] | [prev] | [next] | [standalone]
| From | "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> |
|---|---|
| Date | 2016-05-03 14:50 +0200 |
| Message-ID | <ruHW3-8fC-21@gated-at.bofh.it> |
| In reply to | #1393339 |
Hi, all
On 2016/5/3 19:07, Zhangjian (Bamvor) wrote:
>
>
> On 2016/5/3 17:05, Arnd Bergmann wrote:
>> On Tuesday 03 May 2016 10:00:45 Catalin Marinas wrote:
>>> On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote:
>>>> On Friday 29 April 2016 17:01:55 Catalin Marinas wrote:
>>>>> On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote:
>>>>>> ILP32 VDSO exports next symbols:
>>>>>> __kernel_rt_sigreturn;
>>>>>> __kernel_gettimeofday;
>>>>>> __kernel_clock_gettime;
>>>>>> __kernel_clock_getres;
>>>>>
>>>>> [...]
>>>>>
>>>>>> +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
>>>>>> + $(call if_changed_dep,vdso-ilp32as)
>>>>>
>>>>> Are struct timeval and timespec the same between ILP32 and LP64? For
>>>>> example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in
>>>>> asm-offsets.c based on the LP64 timeval.
>>>>
>>>> No, ilp32 uses the generic 32-bit data structures, which have a 32-bit
>>>> time_t. I guess that means it can work for little-endian but not
>>>> big-endian, right?
>>>
>>> I don't think it works for little-endian either. The LP64 struct timeval
>>> is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is
>>> storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC])
>>
>> You are right. Yury asked pointed out the same thing on IRC as well.
>> Using the 64-bit gettimeofday() will put the right number in the
>> .tv_sec member on little-endian, but will write zeroes to tv_nsec
>> and corrupt the memory following it.
>>
>> Yury also tried it out and noticed that for a (so far) unknown reason,
>> the vdso gets never used by his glibc build, so it has not triggered
>> any test case failures.
> We found this issue too. And it is because the version is different from
> the glibc wanted. We define 2.6.39 for lp64 but 2.6 for ilp32 in vdso
> in kernel:
> +VERSION
> +{
> + LINUX_2.6 {
> + global:
> + __kernel_rt_sigreturn;
> + __kernel_gettimeofday;
> + __kernel_clock_gettime;
> + __kernel_clock_getres;
> + local: *;
> + };
> +}
> If I change 2.6 to 2.6.39, the ilp32 application will call vdso instead
> of syscall. But the result is wrong as Catalin mentioned before.
>
> Should we set this version to 4.6 or higher version? We will need to update
> the version in "sysdeps/unix/sysv/linux/aarch64/init-first.c" too:
> static inline void
> _libc_vdso_platform_setup (void)
> {
> PREPARE_VERSION (linux2639, "LINUX_2.6.39", 123718537);
>
> void *p = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2639);
> PTR_MANGLE (p);
> VDSO_SYMBOL(gettimeofday) = p;
>
> p = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2639);
> PTR_MANGLE (p);
> VDSO_SYMBOL(clock_gettime) = p;
>
> p = _dl_vdso_vsym ("__kernel_clock_getres", &linux2639);
> PTR_MANGLE (p);
> VDSO_SYMBOL(clock_getres) = p;
> }
After apply this patch with my small testcase, the vsyscall of gettimeofday in
ilp32 works in both big endian and small endian. In this patch, I use the
different register and offset for ilp32 and lp64. Actually, the
COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and
TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version
of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index 574081f..c8e32eb 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -101,6 +101,11 @@ int main(void)
DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec));
BLANK();
+ DEFINE(COMPAT_TVAL_TV_SEC, offsetof(struct compat_timeval, tv_sec));
+ DEFINE(COMPAT_TVAL_TV_USEC, offsetof(struct compat_timeval, tv_usec));
+ DEFINE(COMPAT_TSPEC_TV_SEC, offsetof(struct compat_timespec, tv_sec));
+ DEFINE(COMPAT_TSPEC_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
+ BLANK();
DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
index ddc63fd..d182a8d 100644
--- a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -79,7 +79,7 @@ PHDRS
*/
VERSION
{
- LINUX_2.6 {
+ LINUX_4.6 {
global:
__kernel_rt_sigreturn;
__kernel_gettimeofday;
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
index efa79e8..4551f55 100644
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -25,6 +25,14 @@
#define NSEC_PER_SEC_LO16 0xca00
#define NSEC_PER_SEC_HI16 0x3b9a
+#ifdef __LP64__
+#define PTR_REG(n) x##n
+#define OFFSET(n) n
+#else
+#define PTR_REG(n) w##n
+#define OFFSET(n) COMPAT_##n
+#endif
+
vdso_data .req x6
use_syscall .req w7
seqcnt .req w8
@@ -68,7 +76,7 @@ ENTRY(__kernel_gettimeofday)
mov x13, #1000
lsl x13, x13, x12
udiv x11, x11, x13
- stp x10, x11, [x0, #TVAL_TV_SEC]
+ stp PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)]
2:
/* If tz is NULL, return 0. */
cbz x1, 3f
@@ -159,7 +167,7 @@ ENTRY(__kernel_clock_gettime)
6: /* Store to the user timespec. */
lsr x11, x11, x12
- stp x10, x11, [x1, #TSPEC_TV_SEC]
+ stp PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)]
mov x0, xzr
ret
7:
--
1.8.4.5
I am not sure if I should merge above patch into original one. If I
merge it with another patch I send in 13, April, The overall patch is
as follows. I could resend the following patch to this thread if
needed:
From b0a74395cbf18643f3f5b410be425df85d8d68d1 Mon Sep 17 00:00:00 2001
From: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Date: Wed, 6 Apr 2016 01:08:46 +0300
Subject: [PATCH] arm64:ilp32: add vdso-ilp32 and use for signal return
ILP32 VDSO exports next symbols:
__kernel_rt_sigreturn;
__kernel_gettimeofday;
__kernel_clock_gettime;
__kernel_clock_getres;
What shared object to use, kernel selects depending on result of
is_ilp32_compat_task() in arch/arm64/kernel/vdso.c, so it substitutes
correct pages and spec.
Adjusted to move the move data page before code pages in sync with
commit 601255ae3c98fdeeee3a8bb4696425e4f868b4f1
Care must be taken when we update time to user space for ilp32.
Because the size of time struct(timeval, timespec) is different from
lp64.
Signed-off-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
Signed-off-by: Christoph Muellner <christoph.muellner@theobroma-systems.com>
Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
Signed-off-by: Bamvor Jian Zhang <bamvor.zhangjian@huawei.com>
---
arch/arm64/include/asm/vdso.h | 6 ++
arch/arm64/kernel/Makefile | 7 ++
arch/arm64/kernel/asm-offsets.c | 5 ++
arch/arm64/kernel/signal.c | 2 +
arch/arm64/kernel/vdso-ilp32/.gitignore | 2 +
arch/arm64/kernel/vdso-ilp32/Makefile | 72 ++++++++++++++++++++
arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S | 33 ++++++++++
arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 95 +++++++++++++++++++++++++++
arch/arm64/kernel/vdso.c | 61 ++++++++++++++---
arch/arm64/kernel/vdso/gettimeofday.S | 12 +++-
10 files changed, 283 insertions(+), 12 deletions(-)
create mode 100644 arch/arm64/kernel/vdso-ilp32/.gitignore
create mode 100644 arch/arm64/kernel/vdso-ilp32/Makefile
create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
create mode 100644 arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
diff --git a/arch/arm64/include/asm/vdso.h b/arch/arm64/include/asm/vdso.h
index 839ce00..649a9a4 100644
--- a/arch/arm64/include/asm/vdso.h
+++ b/arch/arm64/include/asm/vdso.h
@@ -29,6 +29,12 @@
#include <generated/vdso-offsets.h>
+#ifdef CONFIG_ARM64_ILP32
+#include <generated/vdso-ilp32-offsets.h>
+#else
+#define vdso_offset_sigtramp_ilp32
+#endif
+
#define VDSO_SYMBOL(base, name) \
({ \
(void *)(vdso_offset_##name - VDSO_LBASE + (unsigned long)(base)); \
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 09e4373..0f27a10 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -50,6 +50,7 @@ arm64-obj-$(CONFIG_PARAVIRT) += paravirt.o
arm64-obj-$(CONFIG_RANDOMIZE_BASE) += kaslr.o
obj-y += $(arm64-obj-y) vdso/
+obj-$(CONFIG_ARM64_ILP32) += vdso-ilp32/
obj-m += $(arm64-obj-m)
head-y := head.o
extra-y += $(head-y) vmlinux.lds
@@ -57,3 +58,9 @@ extra-y += $(head-y) vmlinux.lds
# vDSO - this must be built first to generate the symbol offsets
$(call objectify,$(arm64-obj-y)): $(obj)/vdso/vdso-offsets.h
$(obj)/vdso/vdso-offsets.h: $(obj)/vdso
+
+# vDSO - this must be built first to generate the symbol offsets
+ifeq ($(CONFIG_ARM64_ILP32),y)
+$(call objectify,$(arm64-obj-y)): $(obj)/vdso-ilp32/vdso-ilp32-offsets.h
+$(obj)/vdso-ilp32/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32
+endif
diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
index e229525..e5db887 100644
--- a/arch/arm64/kernel/asm-offsets.c
+++ b/arch/arm64/kernel/asm-offsets.c
@@ -101,6 +101,11 @@ int main(void)
DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec));
BLANK();
+ DEFINE(COMPAT_TVAL_TV_SEC, offsetof(struct compat_timeval, tv_sec));
+ DEFINE(COMPAT_TVAL_TV_USEC, offsetof(struct compat_timeval, tv_usec));
+ DEFINE(COMPAT_TSPEC_TV_SEC, offsetof(struct compat_timespec, tv_sec));
+ DEFINE(COMPAT_TSPEC_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
+ BLANK();
DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
BLANK();
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index 45bcd96..933cdcf 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -264,6 +264,8 @@ void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
if (ka->sa.sa_flags & SA_RESTORER)
sigtramp = ka->sa.sa_restorer;
+ else if (is_ilp32_compat_task())
+ sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp_ilp32);
else
sigtramp = VDSO_SYMBOL(current->mm->context.vdso, sigtramp);
diff --git a/arch/arm64/kernel/vdso-ilp32/.gitignore b/arch/arm64/kernel/vdso-ilp32/.gitignore
new file mode 100644
index 0000000..61806c3
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/.gitignore
@@ -0,0 +1,2 @@
+vdso-ilp32.lds
+vdso-ilp32-offsets.h
diff --git a/arch/arm64/kernel/vdso-ilp32/Makefile b/arch/arm64/kernel/vdso-ilp32/Makefile
new file mode 100644
index 0000000..c8f5472
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/Makefile
@@ -0,0 +1,72 @@
+#
+# Building a vDSO image for AArch64.
+#
+# Author: Will Deacon <will.deacon@arm.com>
+# Heavily based on the vDSO Makefiles for other archs.
+#
+
+obj-ilp32-vdso := gettimeofday-ilp32.o note-ilp32.o sigreturn-ilp32.o
+
+# Build rules
+targets := $(obj-ilp32-vdso) vdso-ilp32.so vdso-ilp32.so.dbg
+obj-ilp32-vdso := $(addprefix $(obj)/, $(obj-ilp32-vdso))
+
+ccflags-y := -shared -fno-common -fno-builtin
+ccflags-y += -nostdlib -Wl,-soname=linux-ilp32-vdso.so.1 \
+ $(call cc-ldoption, -Wl$(comma)--hash-style=sysv)
+
+obj-y += vdso-ilp32.o
+extra-y += vdso-ilp32.lds vdso-ilp32-offsets.h
+CPPFLAGS_vdso-ilp32.lds += -P -C -U$(ARCH) -mabi=ilp32
+
+# Force dependency (incbin is bad)
+$(obj)/vdso-ilp32.o : $(obj)/vdso-ilp32.so
+
+# Link rule for the .so file, .lds has to be first
+$(obj)/vdso-ilp32.so.dbg: $(src)/vdso-ilp32.lds $(obj-ilp32-vdso)
+ $(call if_changed,vdso-ilp32ld)
+
+# Strip rule for the .so file
+$(obj)/%.so: OBJCOPYFLAGS := -S
+$(obj)/%.so: $(obj)/%.so.dbg FORCE
+ $(call if_changed,objcopy)
+
+# Generate VDSO offsets using helper script
+gen-vdsosym := $(srctree)/$(src)/../vdso/gen_vdso_offsets.sh
+quiet_cmd_vdsosym = VDSOSYM $@
+define cmd_vdsosym
+ $(NM) $< | $(gen-vdsosym) | LC_ALL=C sort > $@ && \
+ cp $@ include/generated/
+endef
+
+$(obj)/vdso-ilp32-offsets.h: $(obj)/vdso-ilp32.so.dbg FORCE
+ $(call if_changed,vdsosym)
+
+# Assembly rules for the .S files
+#$(obj-ilp32-vdso): %.o: $(src)/../vdso/$(subst -ilp32,,%.S)
+# $(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S
+ $(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/note-ilp32.o: $(src)/../vdso/note.S
+ $(call if_changed_dep,vdso-ilp32as)
+
+$(obj)/sigreturn-ilp32.o: $(src)/../vdso/sigreturn.S
+ $(call if_changed_dep,vdso-ilp32as)
+
+# Actual build commands
+quiet_cmd_vdso-ilp32ld = VDSOILP32L $@
+ cmd_vdso-ilp32ld = $(CC) $(c_flags) -mabi=ilp32 -Wl,-n -Wl,-T $^ -o $@
+quiet_cmd_vdso-ilp32as = VDSOILP32A $@
+ cmd_vdso-ilp32as = $(CC) $(a_flags) -mabi=ilp32 -c -o $@ $<
+
+# Install commands for the unstripped file
+quiet_cmd_vdso_install = INSTALL $@
+ cmd_vdso_install = cp $(obj)/$@.dbg $(MODLIB)/vdso/$@
+
+vdso-ilp32.so: $(obj)/vdso-ilp32.so.dbg
+ @mkdir -p $(MODLIB)/vdso
+ $(call cmd,vdso_install)
+
+vdso_install: vdso-ilp32.so
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
new file mode 100644
index 0000000..46ac072
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.S
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ */
+
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/const.h>
+#include <asm/page.h>
+
+ __PAGE_ALIGNED_DATA
+
+ .globl vdso_ilp32_start, vdso_ilp32_end
+ .balign PAGE_SIZE
+vdso_ilp32_start:
+ .incbin "arch/arm64/kernel/vdso-ilp32/vdso-ilp32.so"
+ .balign PAGE_SIZE
+vdso_ilp32_end:
+
+ .previous
diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
new file mode 100644
index 0000000..d182a8d
--- /dev/null
+++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
@@ -0,0 +1,95 @@
+/*
+ * GNU linker script for the VDSO library.
+ *
+ * Copyright (C) 2012 ARM Limited
+ *
+ * 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/>.
+ *
+ * Author: Will Deacon <will.deacon@arm.com>
+ * Heavily based on the vDSO linker scripts for other archs.
+ */
+
+#include <linux/const.h>
+#include <asm/page.h>
+#include <asm/vdso.h>
+
+SECTIONS
+{
+ PROVIDE(_vdso_data = . - PAGE_SIZE);
+ . = VDSO_LBASE + SIZEOF_HEADERS;
+
+ .hash : { *(.hash) } :text
+ .gnu.hash : { *(.gnu.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .gnu.version : { *(.gnu.version) }
+ .gnu.version_d : { *(.gnu.version_d) }
+ .gnu.version_r : { *(.gnu.version_r) }
+
+ .note : { *(.note.*) } :text :note
+
+ . = ALIGN(16);
+
+ .text : { *(.text*) } :text =0xd503201f
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+
+ .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
+ .eh_frame : { KEEP (*(.eh_frame)) } :text
+
+ .dynamic : { *(.dynamic) } :text :dynamic
+
+ .rodata : { *(.rodata*) } :text
+
+ _end = .;
+ PROVIDE(end = .);
+
+ /DISCARD/ : {
+ *(.note.GNU-stack)
+ *(.data .data.* .gnu.linkonce.d.* .sdata*)
+ *(.bss .sbss .dynbss .dynsbss)
+ }
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+ text PT_LOAD FLAGS(5) FILEHDR PHDRS; /* PF_R|PF_X */
+ dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
+ note PT_NOTE FLAGS(4); /* PF_R */
+ eh_frame_hdr PT_GNU_EH_FRAME;
+}
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+ LINUX_4.6 {
+ global:
+ __kernel_rt_sigreturn;
+ __kernel_gettimeofday;
+ __kernel_clock_gettime;
+ __kernel_clock_getres;
+ local: *;
+ };
+}
+
+/*
+ * Make the sigreturn code visible to the kernel.
+ */
+VDSO_sigtramp_ilp32 = __kernel_rt_sigreturn;
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index 26352a6..521a8e4 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -40,6 +40,12 @@ extern char vdso_start, vdso_end;
static unsigned long vdso_pages;
static struct page **vdso_pagelist;
+#ifdef CONFIG_ARM64_ILP32
+extern char vdso_ilp32_start, vdso_ilp32_end;
+static unsigned long vdso_ilp32_pages;
+static struct page **vdso_ilp32_pagelist;
+#endif
+
/*
* The vDSO data page.
*/
@@ -109,24 +115,29 @@ int aarch32_setup_vectors_page(struct linux_binprm *bprm, int uses_interp)
}
#endif /* CONFIG_AARCH32_EL0 */
-static struct vm_special_mapping vdso_spec[2];
-
-static int __init vdso_init(void)
+static int __init vdso_init_common(char *vdso_start, char *vdso_end,
+ unsigned long *vdso_pagesp,
+ struct page ***vdso_pagelistp,
+ struct vm_special_mapping* vdso_spec)
{
int i;
+ unsigned long vdso_pages;
+ struct page **vdso_pagelist;
- if (memcmp(&vdso_start, "\177ELF", 4)) {
+ if (memcmp(vdso_start, "\177ELF", 4)) {
pr_err("vDSO is not a valid ELF object!\n");
return -EINVAL;
}
- vdso_pages = (&vdso_end - &vdso_start) >> PAGE_SHIFT;
+ vdso_pages = (vdso_end - vdso_start) >> PAGE_SHIFT;
+ *vdso_pagesp = vdso_pages;
pr_info("vdso: %ld pages (%ld code @ %p, %ld data @ %p)\n",
- vdso_pages + 1, vdso_pages, &vdso_start, 1L, vdso_data);
+ vdso_pages + 1, vdso_pages, vdso_start, 1L, vdso_data);
/* Allocate the vDSO pagelist, plus a page for the data. */
vdso_pagelist = kcalloc(vdso_pages + 1, sizeof(struct page *),
GFP_KERNEL);
+ *vdso_pagelistp = vdso_pagelist;
if (vdso_pagelist == NULL)
return -ENOMEM;
@@ -135,7 +146,7 @@ static int __init vdso_init(void)
/* Grab the vDSO code pages. */
for (i = 0; i < vdso_pages; i++)
- vdso_pagelist[i + 1] = virt_to_page(&vdso_start + i * PAGE_SIZE);
+ vdso_pagelist[i + 1] = virt_to_page(vdso_start + i * PAGE_SIZE);
/* Populate the special mapping structures */
vdso_spec[0] = (struct vm_special_mapping) {
@@ -150,16 +161,46 @@ static int __init vdso_init(void)
return 0;
}
+
+static struct vm_special_mapping vdso_spec[2];
+
+static int __init vdso_init(void)
+{
+ return vdso_init_common(&vdso_start, &vdso_end,
+ &vdso_pages, &vdso_pagelist,
+ vdso_spec);
+}
arch_initcall(vdso_init);
+#ifdef CONFIG_ARM64_ILP32
+static struct vm_special_mapping vdso_ilp32_spec[2];
+
+static int __init vdso_ilp32_init(void)
+{
+ return vdso_init_common(&vdso_ilp32_start, &vdso_ilp32_end,
+ &vdso_ilp32_pages, &vdso_ilp32_pagelist,
+ vdso_ilp32_spec);
+}
+arch_initcall(vdso_ilp32_init);
+#endif
+
int arch_setup_additional_pages(struct linux_binprm *bprm,
int uses_interp)
{
struct mm_struct *mm = current->mm;
unsigned long vdso_base, vdso_text_len, vdso_mapping_len;
void *ret;
+ unsigned long pages = vdso_pages;
+ struct vm_special_mapping *spec = vdso_spec;
+
+#ifdef CONFIG_ARM64_ILP32
+ if (is_ilp32_compat_task()) {
+ pages = vdso_ilp32_pages;
+ spec = vdso_ilp32_spec;
+ }
+#endif
- vdso_text_len = vdso_pages << PAGE_SHIFT;
+ vdso_text_len = pages << PAGE_SHIFT;
/* Be sure to map the data page */
vdso_mapping_len = vdso_text_len + PAGE_SIZE;
@@ -171,7 +212,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
}
ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE,
VM_READ|VM_MAYREAD,
- &vdso_spec[0]);
+ &spec[0]);
if (IS_ERR(ret))
goto up_fail;
@@ -180,7 +221,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm,
ret = _install_special_mapping(mm, vdso_base, vdso_text_len,
VM_READ|VM_EXEC|
VM_MAYREAD|VM_MAYWRITE|VM_MAYEXEC,
- &vdso_spec[1]);
+ &spec[1]);
if (IS_ERR(ret))
goto up_fail;
diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
index efa79e8..4551f55 100644
--- a/arch/arm64/kernel/vdso/gettimeofday.S
+++ b/arch/arm64/kernel/vdso/gettimeofday.S
@@ -25,6 +25,14 @@
#define NSEC_PER_SEC_LO16 0xca00
#define NSEC_PER_SEC_HI16 0x3b9a
+#ifdef __LP64__
+#define PTR_REG(n) x##n
+#define OFFSET(n) n
+#else
+#define PTR_REG(n) w##n
+#define OFFSET(n) COMPAT_##n
+#endif
+
vdso_data .req x6
use_syscall .req w7
seqcnt .req w8
@@ -68,7 +76,7 @@ ENTRY(__kernel_gettimeofday)
mov x13, #1000
lsl x13, x13, x12
udiv x11, x11, x13
- stp x10, x11, [x0, #TVAL_TV_SEC]
+ stp PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)]
2:
/* If tz is NULL, return 0. */
cbz x1, 3f
@@ -159,7 +167,7 @@ ENTRY(__kernel_clock_gettime)
6: /* Store to the user timespec. */
lsr x11, x11, x12
- stp x10, x11, [x1, #TSPEC_TV_SEC]
+ stp PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)]
mov x0, xzr
ret
7:
--
1.8.4.5
Regads
Bamvor
> Regards
>
> Bamvor
>
>>
>> Arnd
>>
>
[toc] | [prev] | [next] | [standalone]
| From | Yury Norov <ynorov@caviumnetworks.com> |
|---|---|
| Date | 2016-05-05 00:00 +0200 |
| Message-ID | <rvcZQ-3pD-21@gated-at.bofh.it> |
| In reply to | #1393396 |
On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote: > Hi, all > > After apply this patch with my small testcase, the vsyscall of gettimeofday in > ilp32 works in both big endian and small endian. In this patch, I use the > different register and offset for ilp32 and lp64. Actually, the > COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and > TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version > of vdso to 4.6. It should change to 2.6.39 if glibc is not update. > [...] Hi Bamvor, It works for me as well. Thank you. I'll incorporate it in next submission. Yury.
[toc] | [prev] | [next] | [standalone]
| From | Andrew Pinski <pinskia@gmail.com> |
|---|---|
| Date | 2016-05-05 01:30 +0200 |
| Subject | Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return |
| Message-ID | <rveoW-4Yr-25@gated-at.bofh.it> |
| In reply to | #1394744 |
On Wed, May 4, 2016 at 2:49 PM, Yury Norov <ynorov@caviumnetworks.com> wrote:
> On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote:
>> Hi, all
>>
>> After apply this patch with my small testcase, the vsyscall of gettimeofday in
>> ilp32 works in both big endian and small endian. In this patch, I use the
>> different register and offset for ilp32 and lp64. Actually, the
>> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and
>> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version
>> of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
>>
>
> [...]
>
> Hi Bamvor,
>
> It works for me as well. Thank you.
> I'll incorporate it in next submission.
We should add the following so we are complaint to the ILP32 ABI
dealing with pointers don't have to be zero extended for arguments,
Note ZERO should most likely be ZERO_PTR or something to do that
effect, I am not so good with names.
#ifdef __LP64__
#define ZERO(n)
#else
#define ZERO(n) mov w##n, w##n
#endif
...
ENTRY(__kernel_gettimeofday)
.cfi_startproc
ZERO(0)
ZERO(1)
...
ENTRY(__kernel_clock_gettime)
.cfi_startproc
ZERO(1)
...
ENTRY(__kernel_clock_getres)
.cfi_startproc
ZERO(1)
Thanks,
Andrew Pinski
>
> Yury.
[toc] | [prev] | [next] | [standalone]
| From | "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> |
|---|---|
| Date | 2016-05-05 04:30 +0200 |
| Message-ID | <rvhd7-7Ph-1@gated-at.bofh.it> |
| In reply to | #1394787 |
Hi, On 2016/5/5 7:23, Andrew Pinski wrote: > On Wed, May 4, 2016 at 2:49 PM, Yury Norov <ynorov@caviumnetworks.com> wrote: >> On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote: >>> Hi, all >>> >>> After apply this patch with my small testcase, the vsyscall of gettimeofday in >>> ilp32 works in both big endian and small endian. In this patch, I use the >>> different register and offset for ilp32 and lp64. Actually, the >>> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and >>> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version >>> of vdso to 4.6. It should change to 2.6.39 if glibc is not update. >>> >> >> [...] >> >> Hi Bamvor, >> >> It works for me as well. Thank you. >> I'll incorporate it in next submission. > > We should add the following so we are complaint to the ILP32 ABI > dealing with pointers don't have to be zero extended for arguments, > Note ZERO should most likely be ZERO_PTR or something to do that > effect, I am not so good with names. > #ifdef __LP64__ > #define ZERO(n) > #else > #define ZERO(n) mov w##n, w##n > #endif > > ... > ENTRY(__kernel_gettimeofday) > .cfi_startproc > ZERO(0) > ZERO(1) > ... > ENTRY(__kernel_clock_gettime) > .cfi_startproc > ZERO(1) > ... > ENTRY(__kernel_clock_getres) > .cfi_startproc > ZERO(1) Thanks. I will test and send a new version. Thanks. Bamvor > Thanks, > Andrew Pinski > >> >> Yury.
[toc] | [prev] | [next] | [standalone]
| From | Andrew Pinski <pinskia@gmail.com> |
|---|---|
| Date | 2016-05-05 08:50 +0200 |
| Subject | Re: [PATCH 24/25] arm64:ilp32: add vdso-ilp32 and use for signal return |
| Message-ID | <rvlgJ-2Wk-7@gated-at.bofh.it> |
| In reply to | #1394828 |
On Wed, May 4, 2016 at 7:24 PM, Zhangjian (Bamvor)
<bamvor.zhangjian@huawei.com> wrote:
> Hi,
>
>
> On 2016/5/5 7:23, Andrew Pinski wrote:
>>
>> On Wed, May 4, 2016 at 2:49 PM, Yury Norov <ynorov@caviumnetworks.com>
>> wrote:
>>>
>>> On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote:
>>>>
>>>> Hi, all
>>>>
>>>> After apply this patch with my small testcase, the vsyscall of
>>>> gettimeofday in
>>>> ilp32 works in both big endian and small endian. In this patch, I use
>>>> the
>>>> different register and offset for ilp32 and lp64. Actually, the
>>>> COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC
>>>> and
>>>> TSPEC_TV_SEC). I add it to keep the logic clear. I also change the
>>>> version
>>>> of vdso to 4.6. It should change to 2.6.39 if glibc is not update.
>>>>
>>>
>>> [...]
>>>
>>> Hi Bamvor,
>>>
>>> It works for me as well. Thank you.
>>> I'll incorporate it in next submission.
>>
>>
>> We should add the following so we are complaint to the ILP32 ABI
>> dealing with pointers don't have to be zero extended for arguments,
>> Note ZERO should most likely be ZERO_PTR or something to do that
>> effect, I am not so good with names.
>> #ifdef __LP64__
>> #define ZERO(n)
>> #else
>> #define ZERO(n) mov w##n, w##n
>> #endif
>>
>> ...
>> ENTRY(__kernel_gettimeofday)
>> .cfi_startproc
>> ZERO(0)
>> ZERO(1)
>> ...
>> ENTRY(__kernel_clock_gettime)
>> .cfi_startproc
>> ZERO(1)
>> ...
>> ENTRY(__kernel_clock_getres)
>> .cfi_startproc
>> ZERO(1)
>
> Thanks. I will test and send a new version.
Note there is one more patch needed to __kernel_clock_getres to store
using 32bit rather than 64bit too.
@@ -213,7 +213,7 @@ ENTRY(__kernel_clock_getres)
ldr x2, 6f
2:
cbz w1, 3f
- stp xzr, x2, [x1]
+ stp PTR_REG(zr), PTR_REG(2), [x1]
3: /* res == NULL. */
mov w0, wzr
Thanks,
Andrew
>
> Thanks.
>
> Bamvor
>>
>> Thanks,
>> Andrew Pinski
>>
>>>
>>> Yury.
>
>
[toc] | [prev] | [next] | [standalone]
| From | "Zhangjian (Bamvor)" <bamvor.zhangjian@huawei.com> |
|---|---|
| Date | 2016-05-09 12:20 +0200 |
| Message-ID | <rwQsa-3re-11@gated-at.bofh.it> |
| In reply to | #1394903 |
Hi, yury
I tested successful in both little endian and big endian.
Just two comments below:
On 2016/5/6 22:00, Yury Norov wrote:
> Hello colleagues,
>
> After all comments, VDSO fix looks like this for me.
>
> Note I renamed Andrew's ZERO macro to DELOUSE, as
> there already is __SC_DELOUSE which does the same,
> but in C, not asm.
>
> Like Bamvor, I'm not sure how we'd apply this patch -
> standalone or meld to VDSO. I think, VDSO patch is too
> big and bad-structurized, and if I find how to refactor
> it, I'll incorporate this fix.
>
> Signed-off-by: Yury Norov <ynorov@caviumnetworks.com>
> ---
> arch/arm64/kernel/asm-offsets.c | 7 +++++++
> arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S | 2 +-
> arch/arm64/kernel/vdso/gettimeofday.S | 20 +++++++++++++++++---
> 3 files changed, 25 insertions(+), 4 deletions(-)
>
> diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
> index e229525..fcfd087 100644
> --- a/arch/arm64/kernel/asm-offsets.c
> +++ b/arch/arm64/kernel/asm-offsets.c
> @@ -101,6 +101,13 @@ int main(void)
> DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec));
> DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec));
> BLANK();
> +#ifdef CONFIG_ARM64_ILP32
The following structs exist in both aarch32 el0 and ilp32. How about change it to
"#ifdef CONFIG_COMPAT"?
> + DEFINE(COMPAT_TVAL_TV_SEC, offsetof(struct compat_timeval, tv_sec));
> + DEFINE(COMPAT_TVAL_TV_USEC, offsetof(struct compat_timeval, tv_usec));
> + DEFINE(COMPAT_TSPEC_TV_SEC, offsetof(struct compat_timespec, tv_sec));
> + DEFINE(COMPAT_TSPEC_TV_NSEC, offsetof(struct compat_timespec, tv_nsec));
> + BLANK();
> +#endif
> DEFINE(TZ_MINWEST, offsetof(struct timezone, tz_minuteswest));
> DEFINE(TZ_DSTTIME, offsetof(struct timezone, tz_dsttime));
> BLANK();
> diff --git a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> index ddc63fd..d182a8d 100644
> --- a/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> +++ b/arch/arm64/kernel/vdso-ilp32/vdso-ilp32.lds.S
> @@ -79,7 +79,7 @@ PHDRS
> */
> VERSION
> {
> - LINUX_2.6 {
> + LINUX_2.6.39 {
Do we really want to this version? Maybe 4.x is better?
Regards
Bamvor
> global:
> __kernel_rt_sigreturn;
> __kernel_gettimeofday;
> diff --git a/arch/arm64/kernel/vdso/gettimeofday.S b/arch/arm64/kernel/vdso/gettimeofday.S
> index efa79e8..a2d8a70 100644
> --- a/arch/arm64/kernel/vdso/gettimeofday.S
> +++ b/arch/arm64/kernel/vdso/gettimeofday.S
> @@ -25,6 +25,16 @@
> #define NSEC_PER_SEC_LO16 0xca00
> #define NSEC_PER_SEC_HI16 0x3b9a
>
> +#ifdef __LP64__
> +#define PTR_REG(n) x##n
> +#define OFFSET(n) n
> +#define DELOUSE(n)
> +#else
> +#define PTR_REG(n) w##n
> +#define OFFSET(n) COMPAT_##n
> +#define DELOUSE(n) mov w##n, w##n
> +#endif
> +
> vdso_data .req x6
> use_syscall .req w7
> seqcnt .req w8
> @@ -51,6 +61,8 @@ seqcnt .req w8
> /* int __kernel_gettimeofday(struct timeval *tv, struct timezone *tz); */
> ENTRY(__kernel_gettimeofday)
> .cfi_startproc
> + DELOUSE(0)
> + DELOUSE(1)
> mov x2, x30
> .cfi_register x30, x2
>
> @@ -68,7 +80,7 @@ ENTRY(__kernel_gettimeofday)
> mov x13, #1000
> lsl x13, x13, x12
> udiv x11, x11, x13
> - stp x10, x11, [x0, #TVAL_TV_SEC]
> + stp PTR_REG(10), PTR_REG(11), [x0, #OFFSET(TVAL_TV_SEC)]
> 2:
> /* If tz is NULL, return 0. */
> cbz x1, 3f
> @@ -88,6 +100,7 @@ ENDPROC(__kernel_gettimeofday)
> /* int __kernel_clock_gettime(clockid_t clock_id, struct timespec *tp); */
> ENTRY(__kernel_clock_gettime)
> .cfi_startproc
> + DELOUSE(1)
> cmp w0, #CLOCK_REALTIME
> ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
> b.ne 2f
> @@ -159,7 +172,7 @@ ENTRY(__kernel_clock_gettime)
>
> 6: /* Store to the user timespec. */
> lsr x11, x11, x12
> - stp x10, x11, [x1, #TSPEC_TV_SEC]
> + stp PTR_REG(10), PTR_REG(11), [x1, #OFFSET(TSPEC_TV_SEC)]
> mov x0, xzr
> ret
> 7:
> @@ -174,6 +187,7 @@ ENDPROC(__kernel_clock_gettime)
> /* int __kernel_clock_getres(clockid_t clock_id, struct timespec *res); */
> ENTRY(__kernel_clock_getres)
> .cfi_startproc
> + DELOUSE(1)
> cmp w0, #CLOCK_REALTIME
> ccmp w0, #CLOCK_MONOTONIC, #0x4, ne
> b.ne 1f
> @@ -187,7 +201,7 @@ ENTRY(__kernel_clock_getres)
> ldr x2, 6f
> 2:
> cbz w1, 3f
> - stp xzr, x2, [x1]
> + stp PTR_REG(zr), PTR_REG(2), [x1]
>
> 3: /* res == NULL. */
> mov w0, wzr
>
[toc] | [prev] | [next] | [standalone]
| From | Yury Norov <ynorov@caviumnetworks.com> |
|---|---|
| Date | 2016-05-05 10:30 +0200 |
| Message-ID | <rvmPy-4Dm-57@gated-at.bofh.it> |
| In reply to | #1393396 |
On Tue, May 03, 2016 at 08:41:25PM +0800, Zhangjian (Bamvor) wrote: [...] > After apply this patch with my small testcase, the vsyscall of gettimeofday in > ilp32 works in both big endian and small endian. In this patch, I use the > different register and offset for ilp32 and lp64. Actually, the > COMPAT_TVAL_TV_SEC is same as TVAL_TV_SEC(so as to COMPAT_TSPEC_TV_SEC and > TSPEC_TV_SEC). I add it to keep the logic clear. I also change the version > of vdso to 4.6. It should change to 2.6.39 if glibc is not update. > > diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c > index 574081f..c8e32eb 100644 > --- a/arch/arm64/kernel/asm-offsets.c > +++ b/arch/arm64/kernel/asm-offsets.c > @@ -101,6 +101,11 @@ int main(void) > DEFINE(TSPEC_TV_SEC, offsetof(struct timespec, tv_sec)); > DEFINE(TSPEC_TV_NSEC, offsetof(struct timespec, tv_nsec)); > BLANK(); > + DEFINE(COMPAT_TVAL_TV_SEC, offsetof(struct compat_timeval, tv_sec)); > + DEFINE(COMPAT_TVAL_TV_USEC, offsetof(struct compat_timeval, tv_usec)); > + DEFINE(COMPAT_TSPEC_TV_SEC, offsetof(struct compat_timespec, tv_sec)); > + DEFINE(COMPAT_TSPEC_TV_NSEC, offsetof(struct compat_timespec, tv_nsec)); > + BLANK(); Hi Bamvor, We just found this lines break build if ILP32 is disabled. I think we need to wrap them with #ifdef CONFIG_ARM64_ILP32 Yury
[toc] | [prev] | [next] | [standalone]
| From | Catalin Marinas <catalin.marinas@arm.com> |
|---|---|
| Date | 2016-05-03 11:10 +0200 |
| Message-ID | <ruEv7-5nI-3@gated-at.bofh.it> |
| In reply to | #1391302 |
On Fri, Apr 29, 2016 at 07:30:19PM +0200, Arnd Bergmann wrote: > On Friday 29 April 2016 17:01:55 Catalin Marinas wrote: > > On Wed, Apr 06, 2016 at 01:08:46AM +0300, Yury Norov wrote: > > > ILP32 VDSO exports next symbols: > > > __kernel_rt_sigreturn; > > > __kernel_gettimeofday; > > > __kernel_clock_gettime; > > > __kernel_clock_getres; > > > > [...] > > > > > +$(obj)/gettimeofday-ilp32.o: $(src)/../vdso/gettimeofday.S > > > + $(call if_changed_dep,vdso-ilp32as) > > > > Are struct timeval and timespec the same between ILP32 and LP64? For > > example, __kernel_gettimeofday() assumes TVAL_TV_SEC offset defined in > > asm-offsets.c based on the LP64 timeval. > > No, ilp32 uses the generic 32-bit data structures, which have a 32-bit > time_t. I guess that means it can work for little-endian but not > big-endian, right? I don't think it works for little-endian either. The LP64 struct timeval is 16 bytes while the ILP32 one is 8 bytes. The VDSO gettimeofday is storing 16 bytes (stp x10, x11, [x0, #TVAL_TV_SEC]) -- Catalin
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web