From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Will Deacon <will.deacon@arm.com>, Russell King <linux@arm.linux.org.uk>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
linux-api <linux-api@vger.kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Peter Zijlstra <peterz@infradead.org>,
"Paul E . McKenney" <paulmck@linux.vnet.ibm.com>,
Boqun Feng <boqun.feng@gmail.com>, shuah <shuah@kernel.org>,
Andy Lutomirski <luto@amacapital.net>,
Dave Watson <davejwatson@fb.com>, Paul Turner <pjt@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
Andi Kleen <andi@firstfloor.org>, Chris Lameter <cl@linux.com>,
Ben Maurer <bmaurer@fb.com>, rostedt <rostedt@goodmis.org>,
Josh Triplett <josh@joshtriplett.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Michael Kerrisk <mtk.manpages@>
Subject: Re: [PATCH v2 for 5.2 08/12] rseq/selftests: arm: use udf instruction for RSEQ_SIG
Date: Sat, 8 Jun 2019 11:52:45 -0400 (EDT) [thread overview]
Message-ID: <716499178.40175.1560009165920.JavaMail.zimbra@efficios.com> (raw)
In-Reply-To: <1975020343.35751.1559844149532.JavaMail.zimbra@efficios.com>
----- On Jun 6, 2019, at 8:02 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote:
> ----- On May 3, 2019, at 3:38 PM, Mathieu Desnoyers
> mathieu.desnoyers@efficios.com wrote:
>
>> Use udf as the guard instruction for the restartable sequence abort
>> handler.
>>
>> Previously, the chosen signature was not a valid instruction, based
>> on the assumption that it could always sit in a literal pool. However,
>> there are compilation environments in which literal pools are not
>> available, for instance execute-only code. Therefore, we need to
>> choose a signature value that is also a valid instruction.
>>
>> Handle compiling with -mbig-endian on ARMv6+, which generates binaries
>> with mixed code vs data endianness (little endian code, big endian
>> data).
>>
>> Else mismatch between code endianness for the generated signatures and
>> data endianness for the RSEQ_SIG parameter passed to the rseq
>> registration will trigger application segmentation faults when the
>> kernel try to abort rseq critical sections.
>>
>> Prior to ARMv6, -mbig-endian generates big-endian code and data, so
>> endianness should not be reversed in that case.
>
> And of course it cannot be that easy. This breaks when building in
> thumb mode (-mthumb). Output from librseq arm32 build [1] (code similar
> to what is found in the rseq selftests):
>
> CC rseq.lo
> /tmp/ccu6Jw1b.s: Assembler messages:
> /tmp/ccu6Jw1b.s:297: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> /tmp/ccu6Jw1b.s:490: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> Makefile:460: recipe for target 'rseq.lo' failed
>
> This appears to be caused by a missing .arm directive in RSEQ_SIG_DATA.
> Fixing with:
>
> - asm volatile ("b 2f\n\t" \
> + asm volatile (".arm\n\t" \
> + "b 2f\n\t" \
>
> gets the build to go further, but breaks at:
>
> CC basic_percpu_ops_test.o
> /tmp/ccpHOMHZ.s: Assembler messages:
> /tmp/ccpHOMHZ.s:148: Error: misaligned branch destination
> /tmp/ccpHOMHZ.s:956: Error: misaligned branch destination
> Makefile:378: recipe for target 'basic_percpu_ops_test.o' failed
>
> I suspect it's caused by the change from:
>
> - ".word " __rseq_str(RSEQ_SIG) "\n\t" \
>
> to
>
> + ".arm\n\t" \
> + ".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
>
> which changes the mode from thumb to arm for the rest of the
> inline asm within __RSEQ_ASM_DEFINE_ABORT. Better yet, there appears
> to be no way to save the arm/thumb state and restore it afterwards.
>
> I'm really starting to wonder if we should go our of our way to try
> to get this signature to be a valid instruction on arm32. Perhaps
> we should consider going back to use ".word" on arm32 so it ensures
> it uses data endianness (which matches the parameter received by the
> sys_rseq system call), let objdump and friends print it as a literal
> pool (which it is), and just choose an instruction which has little
> chances to appear for the cases we care about between ARM32 BE, LE
> and THUMB. Perhaps a 32-bit palindrome ? Bonus points if this is a
> trap instruction in common configurations for odd-cases-debugging
> purposes.
So I'm not particularly proud of the result, but I found a rather
ugly way to figure out if we are currently in thumb mode within an
inline asm, and restore that mode: test the length of a nop
instruction with a ".if" asm statement.
Do we want to go for this kind of approach, or should we revert
back to a ".word" and accept that the rseq signature before the
abort handler will be seen as data rather than an instruction
on arm32 ?
Is there a better way to do this ?
Thanks,
Mathieu
diff --git a/include/rseq/rseq-arm.h b/include/rseq/rseq-arm.h
index 1ce9231..b6c36dd 100644
--- a/include/rseq/rseq-arm.h
+++ b/include/rseq/rseq-arm.h
@@ -43,7 +43,14 @@
({ \
int sig; \
asm volatile ("b 2f\n\t" \
+ "3:\n\t" \
+ "nop\n\t" \
+ "4:\n\t" \
+ ".arm\n\t" \
"1: .inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((4b - 3b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
"2:\n\t" \
"ldr %[sig], 1b\n\t" \
: [sig] "=r" (sig)); \
@@ -125,8 +132,14 @@ do { \
__rseq_str(table_label) ":\n\t" \
".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \
+ "333:\n\t" \
+ "nop\n\t" \
+ "444:\n\t" \
".arm\n\t" \
".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((444b - 333b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
__rseq_str(label) ":\n\t" \
teardown \
"b %l[" __rseq_str(abort_label) "]\n\t"
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
WARNING: multiple messages have this Message-ID (diff)
From: mathieu.desnoyers at efficios.com (Mathieu Desnoyers)
Subject: [PATCH v2 for 5.2 08/12] rseq/selftests: arm: use udf instruction for RSEQ_SIG
Date: Sat, 8 Jun 2019 11:52:45 -0400 (EDT) [thread overview]
Message-ID: <716499178.40175.1560009165920.JavaMail.zimbra@efficios.com> (raw)
In-Reply-To: <1975020343.35751.1559844149532.JavaMail.zimbra@efficios.com>
----- On Jun 6, 2019, at 8:02 PM, Mathieu Desnoyers mathieu.desnoyers at efficios.com wrote:
> ----- On May 3, 2019, at 3:38 PM, Mathieu Desnoyers
> mathieu.desnoyers at efficios.com wrote:
>
>> Use udf as the guard instruction for the restartable sequence abort
>> handler.
>>
>> Previously, the chosen signature was not a valid instruction, based
>> on the assumption that it could always sit in a literal pool. However,
>> there are compilation environments in which literal pools are not
>> available, for instance execute-only code. Therefore, we need to
>> choose a signature value that is also a valid instruction.
>>
>> Handle compiling with -mbig-endian on ARMv6+, which generates binaries
>> with mixed code vs data endianness (little endian code, big endian
>> data).
>>
>> Else mismatch between code endianness for the generated signatures and
>> data endianness for the RSEQ_SIG parameter passed to the rseq
>> registration will trigger application segmentation faults when the
>> kernel try to abort rseq critical sections.
>>
>> Prior to ARMv6, -mbig-endian generates big-endian code and data, so
>> endianness should not be reversed in that case.
>
> And of course it cannot be that easy. This breaks when building in
> thumb mode (-mthumb). Output from librseq arm32 build [1] (code similar
> to what is found in the rseq selftests):
>
> CC rseq.lo
> /tmp/ccu6Jw1b.s: Assembler messages:
> /tmp/ccu6Jw1b.s:297: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> /tmp/ccu6Jw1b.s:490: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> Makefile:460: recipe for target 'rseq.lo' failed
>
> This appears to be caused by a missing .arm directive in RSEQ_SIG_DATA.
> Fixing with:
>
> - asm volatile ("b 2f\n\t" \
> + asm volatile (".arm\n\t" \
> + "b 2f\n\t" \
>
> gets the build to go further, but breaks at:
>
> CC basic_percpu_ops_test.o
> /tmp/ccpHOMHZ.s: Assembler messages:
> /tmp/ccpHOMHZ.s:148: Error: misaligned branch destination
> /tmp/ccpHOMHZ.s:956: Error: misaligned branch destination
> Makefile:378: recipe for target 'basic_percpu_ops_test.o' failed
>
> I suspect it's caused by the change from:
>
> - ".word " __rseq_str(RSEQ_SIG) "\n\t" \
>
> to
>
> + ".arm\n\t" \
> + ".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
>
> which changes the mode from thumb to arm for the rest of the
> inline asm within __RSEQ_ASM_DEFINE_ABORT. Better yet, there appears
> to be no way to save the arm/thumb state and restore it afterwards.
>
> I'm really starting to wonder if we should go our of our way to try
> to get this signature to be a valid instruction on arm32. Perhaps
> we should consider going back to use ".word" on arm32 so it ensures
> it uses data endianness (which matches the parameter received by the
> sys_rseq system call), let objdump and friends print it as a literal
> pool (which it is), and just choose an instruction which has little
> chances to appear for the cases we care about between ARM32 BE, LE
> and THUMB. Perhaps a 32-bit palindrome ? Bonus points if this is a
> trap instruction in common configurations for odd-cases-debugging
> purposes.
So I'm not particularly proud of the result, but I found a rather
ugly way to figure out if we are currently in thumb mode within an
inline asm, and restore that mode: test the length of a nop
instruction with a ".if" asm statement.
Do we want to go for this kind of approach, or should we revert
back to a ".word" and accept that the rseq signature before the
abort handler will be seen as data rather than an instruction
on arm32 ?
Is there a better way to do this ?
Thanks,
Mathieu
diff --git a/include/rseq/rseq-arm.h b/include/rseq/rseq-arm.h
index 1ce9231..b6c36dd 100644
--- a/include/rseq/rseq-arm.h
+++ b/include/rseq/rseq-arm.h
@@ -43,7 +43,14 @@
({ \
int sig; \
asm volatile ("b 2f\n\t" \
+ "3:\n\t" \
+ "nop\n\t" \
+ "4:\n\t" \
+ ".arm\n\t" \
"1: .inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((4b - 3b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
"2:\n\t" \
"ldr %[sig], 1b\n\t" \
: [sig] "=r" (sig)); \
@@ -125,8 +132,14 @@ do { \
__rseq_str(table_label) ":\n\t" \
".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \
+ "333:\n\t" \
+ "nop\n\t" \
+ "444:\n\t" \
".arm\n\t" \
".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((444b - 333b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
__rseq_str(label) ":\n\t" \
teardown \
"b %l[" __rseq_str(abort_label) "]\n\t"
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
WARNING: multiple messages have this Message-ID (diff)
From: mathieu.desnoyers@efficios.com (Mathieu Desnoyers)
Subject: [PATCH v2 for 5.2 08/12] rseq/selftests: arm: use udf instruction for RSEQ_SIG
Date: Sat, 8 Jun 2019 11:52:45 -0400 (EDT) [thread overview]
Message-ID: <716499178.40175.1560009165920.JavaMail.zimbra@efficios.com> (raw)
Message-ID: <20190608155245.MpfL42_PBAG8f7DD7fCXkh1SsmKuf74ADpDWDkqNcDY@z> (raw)
In-Reply-To: <1975020343.35751.1559844149532.JavaMail.zimbra@efficios.com>
----- On Jun 6, 2019,@8:02 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote:
> ----- On May 3, 2019, at 3:38 PM, Mathieu Desnoyers
> mathieu.desnoyers@efficios.com wrote:
>
>> Use udf as the guard instruction for the restartable sequence abort
>> handler.
>>
>> Previously, the chosen signature was not a valid instruction, based
>> on the assumption that it could always sit in a literal pool. However,
>> there are compilation environments in which literal pools are not
>> available, for instance execute-only code. Therefore, we need to
>> choose a signature value that is also a valid instruction.
>>
>> Handle compiling with -mbig-endian on ARMv6+, which generates binaries
>> with mixed code vs data endianness (little endian code, big endian
>> data).
>>
>> Else mismatch between code endianness for the generated signatures and
>> data endianness for the RSEQ_SIG parameter passed to the rseq
>> registration will trigger application segmentation faults when the
>> kernel try to abort rseq critical sections.
>>
>> Prior to ARMv6, -mbig-endian generates big-endian code and data, so
>> endianness should not be reversed in that case.
>
> And of course it cannot be that easy. This breaks when building in
> thumb mode (-mthumb). Output from librseq arm32 build [1] (code similar
> to what is found in the rseq selftests):
>
> CC rseq.lo
> /tmp/ccu6Jw1b.s: Assembler messages:
> /tmp/ccu6Jw1b.s:297: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> /tmp/ccu6Jw1b.s:490: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> Makefile:460: recipe for target 'rseq.lo' failed
>
> This appears to be caused by a missing .arm directive in RSEQ_SIG_DATA.
> Fixing with:
>
> - asm volatile ("b 2f\n\t" \
> + asm volatile (".arm\n\t" \
> + "b 2f\n\t" \
>
> gets the build to go further, but breaks at:
>
> CC basic_percpu_ops_test.o
> /tmp/ccpHOMHZ.s: Assembler messages:
> /tmp/ccpHOMHZ.s:148: Error: misaligned branch destination
> /tmp/ccpHOMHZ.s:956: Error: misaligned branch destination
> Makefile:378: recipe for target 'basic_percpu_ops_test.o' failed
>
> I suspect it's caused by the change from:
>
> - ".word " __rseq_str(RSEQ_SIG) "\n\t" \
>
> to
>
> + ".arm\n\t" \
> + ".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
>
> which changes the mode from thumb to arm for the rest of the
> inline asm within __RSEQ_ASM_DEFINE_ABORT. Better yet, there appears
> to be no way to save the arm/thumb state and restore it afterwards.
>
> I'm really starting to wonder if we should go our of our way to try
> to get this signature to be a valid instruction on arm32. Perhaps
> we should consider going back to use ".word" on arm32 so it ensures
> it uses data endianness (which matches the parameter received by the
> sys_rseq system call), let objdump and friends print it as a literal
> pool (which it is), and just choose an instruction which has little
> chances to appear for the cases we care about between ARM32 BE, LE
> and THUMB. Perhaps a 32-bit palindrome ? Bonus points if this is a
> trap instruction in common configurations for odd-cases-debugging
> purposes.
So I'm not particularly proud of the result, but I found a rather
ugly way to figure out if we are currently in thumb mode within an
inline asm, and restore that mode: test the length of a nop
instruction with a ".if" asm statement.
Do we want to go for this kind of approach, or should we revert
back to a ".word" and accept that the rseq signature before the
abort handler will be seen as data rather than an instruction
on arm32 ?
Is there a better way to do this ?
Thanks,
Mathieu
diff --git a/include/rseq/rseq-arm.h b/include/rseq/rseq-arm.h
index 1ce9231..b6c36dd 100644
--- a/include/rseq/rseq-arm.h
+++ b/include/rseq/rseq-arm.h
@@ -43,7 +43,14 @@
({ \
int sig; \
asm volatile ("b 2f\n\t" \
+ "3:\n\t" \
+ "nop\n\t" \
+ "4:\n\t" \
+ ".arm\n\t" \
"1: .inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((4b - 3b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
"2:\n\t" \
"ldr %[sig], 1b\n\t" \
: [sig] "=r" (sig)); \
@@ -125,8 +132,14 @@ do { \
__rseq_str(table_label) ":\n\t" \
".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \
+ "333:\n\t" \
+ "nop\n\t" \
+ "444:\n\t" \
".arm\n\t" \
".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((444b - 333b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
__rseq_str(label) ":\n\t" \
teardown \
"b %l[" __rseq_str(abort_label) "]\n\t"
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
WARNING: multiple messages have this Message-ID (diff)
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Will Deacon <will.deacon@arm.com>, Russell King <linux@arm.linux.org.uk>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
linux-api <linux-api@vger.kernel.org>,
Thomas Gleixner <tglx@linutronix.de>,
Peter Zijlstra <peterz@infradead.org>,
"Paul E . McKenney" <paulmck@linux.vnet.ibm.com>,
Boqun Feng <boqun.feng@gmail.com>, shuah <shuah@kernel.org>,
Andy Lutomirski <luto@amacapital.net>,
Dave Watson <davejwatson@fb.com>, Paul Turner <pjt@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Ingo Molnar <mingo@redhat.com>, "H. Peter Anvin" <hpa@zytor.com>,
Andi Kleen <andi@firstfloor.org>, Chris Lameter <cl@linux.com>,
Ben Maurer <bmaurer@fb.com>, rostedt <rostedt@goodmis.org>,
Josh Triplett <josh@joshtriplett.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Michael Kerrisk <mtk.manpages@gmail.com>,
Joel Fernandes <joelaf@google.com>,
linux-kselftest <linux-kselftest@vger.kernel.org>,
linux-arm-kernel <linux-arm-kernel@lists.infradead.org>
Subject: Re: [PATCH v2 for 5.2 08/12] rseq/selftests: arm: use udf instruction for RSEQ_SIG
Date: Sat, 8 Jun 2019 11:52:45 -0400 (EDT) [thread overview]
Message-ID: <716499178.40175.1560009165920.JavaMail.zimbra@efficios.com> (raw)
Message-ID: <20190608155245.hN6Q5QNydBYlllVLKBV9Ei3UIZdC_LR7vKayREClrgY@z> (raw)
In-Reply-To: <1975020343.35751.1559844149532.JavaMail.zimbra@efficios.com>
----- On Jun 6, 2019, at 8:02 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote:
> ----- On May 3, 2019, at 3:38 PM, Mathieu Desnoyers
> mathieu.desnoyers@efficios.com wrote:
>
>> Use udf as the guard instruction for the restartable sequence abort
>> handler.
>>
>> Previously, the chosen signature was not a valid instruction, based
>> on the assumption that it could always sit in a literal pool. However,
>> there are compilation environments in which literal pools are not
>> available, for instance execute-only code. Therefore, we need to
>> choose a signature value that is also a valid instruction.
>>
>> Handle compiling with -mbig-endian on ARMv6+, which generates binaries
>> with mixed code vs data endianness (little endian code, big endian
>> data).
>>
>> Else mismatch between code endianness for the generated signatures and
>> data endianness for the RSEQ_SIG parameter passed to the rseq
>> registration will trigger application segmentation faults when the
>> kernel try to abort rseq critical sections.
>>
>> Prior to ARMv6, -mbig-endian generates big-endian code and data, so
>> endianness should not be reversed in that case.
>
> And of course it cannot be that easy. This breaks when building in
> thumb mode (-mthumb). Output from librseq arm32 build [1] (code similar
> to what is found in the rseq selftests):
>
> CC rseq.lo
> /tmp/ccu6Jw1b.s: Assembler messages:
> /tmp/ccu6Jw1b.s:297: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> /tmp/ccu6Jw1b.s:490: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> Makefile:460: recipe for target 'rseq.lo' failed
>
> This appears to be caused by a missing .arm directive in RSEQ_SIG_DATA.
> Fixing with:
>
> - asm volatile ("b 2f\n\t" \
> + asm volatile (".arm\n\t" \
> + "b 2f\n\t" \
>
> gets the build to go further, but breaks at:
>
> CC basic_percpu_ops_test.o
> /tmp/ccpHOMHZ.s: Assembler messages:
> /tmp/ccpHOMHZ.s:148: Error: misaligned branch destination
> /tmp/ccpHOMHZ.s:956: Error: misaligned branch destination
> Makefile:378: recipe for target 'basic_percpu_ops_test.o' failed
>
> I suspect it's caused by the change from:
>
> - ".word " __rseq_str(RSEQ_SIG) "\n\t" \
>
> to
>
> + ".arm\n\t" \
> + ".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
>
> which changes the mode from thumb to arm for the rest of the
> inline asm within __RSEQ_ASM_DEFINE_ABORT. Better yet, there appears
> to be no way to save the arm/thumb state and restore it afterwards.
>
> I'm really starting to wonder if we should go our of our way to try
> to get this signature to be a valid instruction on arm32. Perhaps
> we should consider going back to use ".word" on arm32 so it ensures
> it uses data endianness (which matches the parameter received by the
> sys_rseq system call), let objdump and friends print it as a literal
> pool (which it is), and just choose an instruction which has little
> chances to appear for the cases we care about between ARM32 BE, LE
> and THUMB. Perhaps a 32-bit palindrome ? Bonus points if this is a
> trap instruction in common configurations for odd-cases-debugging
> purposes.
So I'm not particularly proud of the result, but I found a rather
ugly way to figure out if we are currently in thumb mode within an
inline asm, and restore that mode: test the length of a nop
instruction with a ".if" asm statement.
Do we want to go for this kind of approach, or should we revert
back to a ".word" and accept that the rseq signature before the
abort handler will be seen as data rather than an instruction
on arm32 ?
Is there a better way to do this ?
Thanks,
Mathieu
diff --git a/include/rseq/rseq-arm.h b/include/rseq/rseq-arm.h
index 1ce9231..b6c36dd 100644
--- a/include/rseq/rseq-arm.h
+++ b/include/rseq/rseq-arm.h
@@ -43,7 +43,14 @@
({ \
int sig; \
asm volatile ("b 2f\n\t" \
+ "3:\n\t" \
+ "nop\n\t" \
+ "4:\n\t" \
+ ".arm\n\t" \
"1: .inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((4b - 3b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
"2:\n\t" \
"ldr %[sig], 1b\n\t" \
: [sig] "=r" (sig)); \
@@ -125,8 +132,14 @@ do { \
__rseq_str(table_label) ":\n\t" \
".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \
+ "333:\n\t" \
+ "nop\n\t" \
+ "444:\n\t" \
".arm\n\t" \
".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((444b - 333b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
__rseq_str(label) ":\n\t" \
teardown \
"b %l[" __rseq_str(abort_label) "]\n\t"
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
WARNING: multiple messages have this Message-ID (diff)
From: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
To: Will Deacon <will.deacon@arm.com>, Russell King <linux@arm.linux.org.uk>
Cc: Joel Fernandes <joelaf@google.com>,
Peter Zijlstra <peterz@infradead.org>,
Catalin Marinas <catalin.marinas@arm.com>,
Dave Watson <davejwatson@fb.com>,
Andi Kleen <andi@firstfloor.org>,
linux-kselftest <linux-kselftest@vger.kernel.org>,
"H. Peter Anvin" <hpa@zytor.com>, Chris Lameter <cl@linux.com>,
shuah <shuah@kernel.org>, Ingo Molnar <mingo@redhat.com>,
Michael Kerrisk <mtk.manpages@gmail.com>,
"Paul E . McKenney" <paulmck@linux.vnet.ibm.com>,
Paul Turner <pjt@google.com>, Boqun Feng <boqun.feng@gmail.com>,
Josh Triplett <josh@joshtriplett.org>,
rostedt <rostedt@goodmis.org>, Ben Maurer <bmaurer@fb.com>,
Thomas Gleixner <tglx@linutronix.de>,
linux-arm-kernel <linux-arm-kernel@lists.infradead.org>,
linux-api <linux-api@vger.kernel.org>,
linux-kernel <linux-kernel@vger.kernel.org>,
Andy Lutomirski <luto@amacapital.net>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: Re: [PATCH v2 for 5.2 08/12] rseq/selftests: arm: use udf instruction for RSEQ_SIG
Date: Sat, 8 Jun 2019 11:52:45 -0400 (EDT) [thread overview]
Message-ID: <716499178.40175.1560009165920.JavaMail.zimbra@efficios.com> (raw)
In-Reply-To: <1975020343.35751.1559844149532.JavaMail.zimbra@efficios.com>
----- On Jun 6, 2019, at 8:02 PM, Mathieu Desnoyers mathieu.desnoyers@efficios.com wrote:
> ----- On May 3, 2019, at 3:38 PM, Mathieu Desnoyers
> mathieu.desnoyers@efficios.com wrote:
>
>> Use udf as the guard instruction for the restartable sequence abort
>> handler.
>>
>> Previously, the chosen signature was not a valid instruction, based
>> on the assumption that it could always sit in a literal pool. However,
>> there are compilation environments in which literal pools are not
>> available, for instance execute-only code. Therefore, we need to
>> choose a signature value that is also a valid instruction.
>>
>> Handle compiling with -mbig-endian on ARMv6+, which generates binaries
>> with mixed code vs data endianness (little endian code, big endian
>> data).
>>
>> Else mismatch between code endianness for the generated signatures and
>> data endianness for the RSEQ_SIG parameter passed to the rseq
>> registration will trigger application segmentation faults when the
>> kernel try to abort rseq critical sections.
>>
>> Prior to ARMv6, -mbig-endian generates big-endian code and data, so
>> endianness should not be reversed in that case.
>
> And of course it cannot be that easy. This breaks when building in
> thumb mode (-mthumb). Output from librseq arm32 build [1] (code similar
> to what is found in the rseq selftests):
>
> CC rseq.lo
> /tmp/ccu6Jw1b.s: Assembler messages:
> /tmp/ccu6Jw1b.s:297: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> /tmp/ccu6Jw1b.s:490: Error: cannot determine Thumb instruction size. Use
> .inst.n/.inst.w instead
> Makefile:460: recipe for target 'rseq.lo' failed
>
> This appears to be caused by a missing .arm directive in RSEQ_SIG_DATA.
> Fixing with:
>
> - asm volatile ("b 2f\n\t" \
> + asm volatile (".arm\n\t" \
> + "b 2f\n\t" \
>
> gets the build to go further, but breaks at:
>
> CC basic_percpu_ops_test.o
> /tmp/ccpHOMHZ.s: Assembler messages:
> /tmp/ccpHOMHZ.s:148: Error: misaligned branch destination
> /tmp/ccpHOMHZ.s:956: Error: misaligned branch destination
> Makefile:378: recipe for target 'basic_percpu_ops_test.o' failed
>
> I suspect it's caused by the change from:
>
> - ".word " __rseq_str(RSEQ_SIG) "\n\t" \
>
> to
>
> + ".arm\n\t" \
> + ".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
>
> which changes the mode from thumb to arm for the rest of the
> inline asm within __RSEQ_ASM_DEFINE_ABORT. Better yet, there appears
> to be no way to save the arm/thumb state and restore it afterwards.
>
> I'm really starting to wonder if we should go our of our way to try
> to get this signature to be a valid instruction on arm32. Perhaps
> we should consider going back to use ".word" on arm32 so it ensures
> it uses data endianness (which matches the parameter received by the
> sys_rseq system call), let objdump and friends print it as a literal
> pool (which it is), and just choose an instruction which has little
> chances to appear for the cases we care about between ARM32 BE, LE
> and THUMB. Perhaps a 32-bit palindrome ? Bonus points if this is a
> trap instruction in common configurations for odd-cases-debugging
> purposes.
So I'm not particularly proud of the result, but I found a rather
ugly way to figure out if we are currently in thumb mode within an
inline asm, and restore that mode: test the length of a nop
instruction with a ".if" asm statement.
Do we want to go for this kind of approach, or should we revert
back to a ".word" and accept that the rseq signature before the
abort handler will be seen as data rather than an instruction
on arm32 ?
Is there a better way to do this ?
Thanks,
Mathieu
diff --git a/include/rseq/rseq-arm.h b/include/rseq/rseq-arm.h
index 1ce9231..b6c36dd 100644
--- a/include/rseq/rseq-arm.h
+++ b/include/rseq/rseq-arm.h
@@ -43,7 +43,14 @@
({ \
int sig; \
asm volatile ("b 2f\n\t" \
+ "3:\n\t" \
+ "nop\n\t" \
+ "4:\n\t" \
+ ".arm\n\t" \
"1: .inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((4b - 3b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
"2:\n\t" \
"ldr %[sig], 1b\n\t" \
: [sig] "=r" (sig)); \
@@ -125,8 +132,14 @@ do { \
__rseq_str(table_label) ":\n\t" \
".word " __rseq_str(version) ", " __rseq_str(flags) "\n\t" \
".word " __rseq_str(start_ip) ", 0x0, " __rseq_str(post_commit_offset) ", 0x0, " __rseq_str(abort_ip) ", 0x0\n\t" \
+ "333:\n\t" \
+ "nop\n\t" \
+ "444:\n\t" \
".arm\n\t" \
".inst " __rseq_str(RSEQ_SIG_CODE) "\n\t" \
+ ".if ((444b - 333b) == 2)\n\t" \
+ ".thumb\n\t" \
+ ".endif\n\t" \
__rseq_str(label) ":\n\t" \
teardown \
"b %l[" __rseq_str(abort_label) "]\n\t"
--
Mathieu Desnoyers
EfficiOS Inc.
http://www.efficios.com
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-06-08 15:52 UTC|newest]
Thread overview: 83+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-29 15:27 [PATCH for 5.2 00/12] Restartable Sequences selftests updates Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 01/12] rseq/selftests: x86: Work-around bogus gcc-8 optimisation Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` mathieu.desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 02/12] rseq/selftests: Add __rseq_exit_point_array section for debuggers Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` mathieu.desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 03/12] rseq/selftests: Introduce __rseq_cs_ptr_array, rename __rseq_table to __rseq_cs Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` mathieu.desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 04/12] rseq/selftests: Use __rseq_handled symbol to coexist with glibc Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 05/12] rseq/selftests: s390: use jg instruction for jumps outside of the asm Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` mathieu.desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 06/12] rseq/selftests: x86: use ud1 instruction as RSEQ_SIG opcode Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` mathieu.desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 07/12] rseq/selftests: s390: use trap4 for RSEQ_SIG Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-05-16 20:39 ` shuah
2019-05-16 20:39 ` shuah
2019-05-16 20:49 ` Mathieu Desnoyers
2019-05-16 20:49 ` Mathieu Desnoyers
2019-04-29 15:27 ` [PATCH for 5.2 08/12] rseq/selftests: arm: use udf instruction " Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` Mathieu Desnoyers
2019-04-29 15:27 ` mathieu.desnoyers
2019-05-03 19:38 ` [PATCH v2 " Mathieu Desnoyers
2019-05-03 19:38 ` Mathieu Desnoyers
2019-05-03 19:38 ` Mathieu Desnoyers
2019-05-03 19:38 ` mathieu.desnoyers
2019-06-06 18:02 ` Mathieu Desnoyers
2019-06-06 18:02 ` Mathieu Desnoyers
2019-06-06 18:02 ` Mathieu Desnoyers
2019-06-06 18:02 ` Mathieu Desnoyers
2019-06-06 18:02 ` mathieu.desnoyers
2019-06-08 15:52 ` Mathieu Desnoyers [this message]
2019-06-08 15:52 ` Mathieu Desnoyers
2019-06-08 15:52 ` Mathieu Desnoyers
2019-06-08 15:52 ` Mathieu Desnoyers
2019-06-08 15:52 ` mathieu.desnoyers
2019-04-29 15:28 ` [PATCH for 5.2 09/12] rseq/selftests: aarch64 code signature: handle big-endian environment Mathieu Desnoyers
2019-04-29 15:28 ` Mathieu Desnoyers
2019-04-29 15:28 ` Mathieu Desnoyers
2019-04-29 15:28 ` mathieu.desnoyers
2019-04-29 15:28 ` [PATCH for 5.2 10/12] rseq/selftests: powerpc code signature: generate valid instructions Mathieu Desnoyers
2019-04-29 15:28 ` Mathieu Desnoyers
2019-04-29 15:28 ` Mathieu Desnoyers
2019-04-29 15:28 ` [PATCH for 5.2 11/12] rseq/selftests: mips: use break instruction for RSEQ_SIG Mathieu Desnoyers
2019-04-29 15:28 ` Mathieu Desnoyers
2019-04-29 15:28 ` [PATCH for 5.2 12/12] rseq/selftests: add -no-integrated-as for clang Mathieu Desnoyers
2019-04-29 15:28 ` Mathieu Desnoyers
2019-04-29 15:28 ` Mathieu Desnoyers
2019-04-29 15:28 ` mathieu.desnoyers
2019-04-29 17:03 ` Nick Desaulniers
2019-04-29 17:03 ` Nick Desaulniers
2019-04-29 17:03 ` Nick Desaulniers
2019-04-29 17:03 ` ndesaulniers
2019-04-29 20:28 ` Mathieu Desnoyers
2019-04-29 20:28 ` Mathieu Desnoyers
2019-04-29 20:28 ` Mathieu Desnoyers
2019-04-29 20:28 ` mathieu.desnoyers
2019-04-29 20:30 ` Nick Desaulniers
2019-04-29 20:30 ` Nick Desaulniers
2019-04-29 20:30 ` Nick Desaulniers
2019-04-29 20:30 ` ndesaulniers
2019-05-03 18:36 ` [PATCH for 5.2 00/12] Restartable Sequences selftests updates Mathieu Desnoyers
2019-05-03 18:36 ` Mathieu Desnoyers
2019-05-03 18:53 ` shuah
2019-05-03 18:53 ` shuah
2019-05-03 19:22 ` Mathieu Desnoyers
2019-05-03 19:22 ` Mathieu Desnoyers
2019-05-03 21:46 ` Joe Perches
2019-05-03 21:46 ` Joe Perches
2019-05-03 22:59 ` shuah
2019-05-03 22:59 ` shuah
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=716499178.40175.1560009165920.JavaMail.zimbra@efficios.com \
--to=mathieu.desnoyers@efficios.com \
--cc=akpm@linux-foundation.org \
--cc=andi@firstfloor.org \
--cc=bmaurer@fb.com \
--cc=boqun.feng@gmail.com \
--cc=catalin.marinas@arm.com \
--cc=cl@linux.com \
--cc=davejwatson@fb.com \
--cc=hpa@zytor.com \
--cc=josh@joshtriplett.org \
--cc=linux-api@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@arm.linux.org.uk \
--cc=luto@amacapital.net \
--cc=mingo@redhat.com \
--cc=paulmck@linux.vnet.ibm.com \
--cc=peterz@infradead.org \
--cc=pjt@google.com \
--cc=rostedt@goodmis.org \
--cc=shuah@kernel.org \
--cc=tglx@linutronix.de \
--cc=torvalds@linux-foundation.org \
--cc=will.deacon@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.