From: Thomas Garnier <hidden> Date: 2017-03-11 00:04:58
This patch ensures a syscall does not return to user-mode with a kernel
address limit. If that happened, a process can corrupt kernel-mode
memory and elevate privileges.
For example, it would mitigation this bug:
- https://bugs.chromium.org/p/project-zero/issues/detail?id=990
If the CONFIG_BUG_ON_DATA_CORRUPTION option is enabled, an incorrect
state will result in a BUG_ON.
The CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE option is also
added so each architecture can optimize this change.
Signed-off-by: Thomas Garnier <redacted>
---
Based on next-20170308
---
arch/s390/Kconfig | 1 +
include/linux/syscalls.h | 18 +++++++++++++++++-
init/Kconfig | 7 +++++++
kernel/sys.c | 8 ++++++++
4 files changed, 33 insertions(+), 1 deletion(-)
@@ -1929,6 +1929,13 @@ config PROFILINGconfigTRACEPOINTSbool+#+# Set by each architecture that want to optimize how verify_pre_usermode_state+# is called.+#+configARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE+bool+source"arch/Kconfig"endmenu# General setup
@@ -2459,3 +2459,11 @@ COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)return0;}#endif /* CONFIG_COMPAT */++/* Called before coming back to user-mode */+asmlinkagevoidverify_pre_usermode_state(void)+{+if(CHECK_DATA_CORRUPTION(!segment_eq(get_fs(),USER_DS),+"incorrect get_fs() on user-mode return"))+set_fs(USER_DS);+}
@@ -829,17 +829,6 @@ static inline void spin_lock_prefetch(const void *x)#define KSTK_ESP(task) (task_pt_regs(task)->sp)#else-/*-*Userspaceprocesssize.47bitsminusoneguardpage.Theguard-*pageisnecessaryonIntelCPUs:ifaSYSCALLinstructionisat-*thehighestpossiblecanonicaluserspaceaddress,thenthat-*syscallwillenterthekernelwithanon-canonicalreturn-*address,andSYSRETwillexplodedangerously.Weavoidthis-*particularproblembypreventinganythingfrombeingmapped-*atthemaximumcanonicaladdress.-*/-#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)-/* This decides where the kernel will search for a free chunk of vm*spaceduringmmap's.*/
From: Thomas Garnier <hidden> Date: 2017-03-11 00:05:01
Implement specific usage of verify_pre_usermode_state for user-mode
returns for arm64.
---
Based on next-20170308
---
arch/arm64/Kconfig | 1 +
arch/arm64/kernel/entry.S | 25 +++++++++++++++++++++++++
2 files changed, 26 insertions(+)
Ugh, so you call an assembly function just to ... call another function.
Plus why is it in assembly to begin with? Is this some older code that got
written when the x86 entry code was in assembly, and never properly
converted to C?
Thanks,
Ingo
From: Thomas Garnier <hidden> Date: 2017-03-13 15:53:37
On Sat, Mar 11, 2017 at 1:42 AM, Ingo Molnar [off-list ref] wrote:
Ugh, so you call an assembly function just to ... call another function.
The verify_pre_usermode_state function is the architecture independent
checker. By default it is added on each syscall handler so calling it
here save code size.
Plus why is it in assembly to begin with? Is this some older code that got
written when the x86 entry code was in assembly, and never properly
converted to C?
I wrote the assembly to make it faster and save a call on each syscall
return. I can just call verify_pre_usermode_state if you prefer.
--
Thomas
+ * under the slow path through syscall_return_slowpath.
+ */
+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
+ call verify_pre_usermode_state
+#else
+ /*
+ * Similar to set_fs(USER_DS) in verify_pre_usermode_state without
Ugh, so you call an assembly function just to ... call another
function.
Plus why is it in assembly to begin with? Is this some older code that
got
written when the x86 entry code was in assembly, and never properly
converted to C?
Thanks,
Ingo
The code does a compare to jump around a store. It would be much cleaner and faster to simply clobber the value unconditionally. If there is a test it should be to avoid the function call, not (only) the assignment.
--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2017-03-14 00:04:36
On 03/11/17 01:42, Ingo Molnar wrote:
quoted
+ /*
+ * Check user-mode state on fast path return, the same check is done
+ * under the slow path through syscall_return_slowpath.
+ */
+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
+ call verify_pre_usermode_state
+#else
+ /*
+ * Similar to set_fs(USER_DS) in verify_pre_usermode_state without a
+ * warning.
+ */
+ movq PER_CPU_VAR(current_task), %rax
+ movq $TASK_SIZE_MAX, %rcx
+ cmp %rcx, TASK_addr_limit(%rax)
+ jz 1f
+ movq %rcx, TASK_addr_limit(%rax)
+1:
+#endif
+
How about simply doing...
movq PER_CPU_VAR(current_task), %rax
movq $TASK_SIZE_MAX, %rcx
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
cmpq %rcx, TASK_addr_limit(%rax)
jne syscall_return_slowpath
#else
movq %rcx, TASK_addr_limit(%rax)
#endif
... and let the slow path take care of BUG. This should be much faster,
even with the BUG, and is simpler to boot.
-hpa
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2017-03-14 09:40:51
On 03/13/17 17:04, H. Peter Anvin wrote:
On 03/11/17 01:42, Ingo Molnar wrote:
quoted
quoted
+ /*
+ * Check user-mode state on fast path return, the same check is done
+ * under the slow path through syscall_return_slowpath.
+ */
+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
+ call verify_pre_usermode_state
+#else
+ /*
+ * Similar to set_fs(USER_DS) in verify_pre_usermode_state without a
+ * warning.
+ */
+ movq PER_CPU_VAR(current_task), %rax
+ movq $TASK_SIZE_MAX, %rcx
+ cmp %rcx, TASK_addr_limit(%rax)
+ jz 1f
+ movq %rcx, TASK_addr_limit(%rax)
+1:
+#endif
+
How about simply doing...
movq PER_CPU_VAR(current_task), %rax
movq $TASK_SIZE_MAX, %rcx
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
cmpq %rcx, TASK_addr_limit(%rax)
jne syscall_return_slowpath
#else
movq %rcx, TASK_addr_limit(%rax)
#endif
... and let the slow path take care of BUG. This should be much faster,
even with the BUG, and is simpler to boot.
In fact, we could even to the cmpq/jne unconditionally. I'm guessing
the occasional branch mispredict will be offset by occasionally touching
a clean cacheline in the case of an unconditional store.
Since this is something that should never happen, performance doesn't
matter.
-hpa
From: Thomas Garnier <hidden> Date: 2017-03-14 15:17:08
On Tue, Mar 14, 2017 at 2:40 AM, H. Peter Anvin [off-list ref] wrote:
On 03/13/17 17:04, H. Peter Anvin wrote:
quoted
On 03/11/17 01:42, Ingo Molnar wrote:
quoted
quoted
+ /*
+ * Check user-mode state on fast path return, the same check is done
+ * under the slow path through syscall_return_slowpath.
+ */
+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
+ call verify_pre_usermode_state
+#else
+ /*
+ * Similar to set_fs(USER_DS) in verify_pre_usermode_state without a
+ * warning.
+ */
+ movq PER_CPU_VAR(current_task), %rax
+ movq $TASK_SIZE_MAX, %rcx
+ cmp %rcx, TASK_addr_limit(%rax)
+ jz 1f
+ movq %rcx, TASK_addr_limit(%rax)
+1:
+#endif
+
How about simply doing...
movq PER_CPU_VAR(current_task), %rax
movq $TASK_SIZE_MAX, %rcx
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
cmpq %rcx, TASK_addr_limit(%rax)
jne syscall_return_slowpath
#else
movq %rcx, TASK_addr_limit(%rax)
#endif
... and let the slow path take care of BUG. This should be much faster,
even with the BUG, and is simpler to boot.
In fact, we could even to the cmpq/jne unconditionally. I'm guessing
the occasional branch mispredict will be offset by occasionally touching
a clean cacheline in the case of an unconditional store.
Since this is something that should never happen, performance doesn't
matter.
Ingo: Which approach do you favor? I want to keep the fast path as
fast as possible obviously.
From: Andy Lutomirski <luto@amacapital.net> Date: 2017-03-14 15:39:09
On Tue, Mar 14, 2017 at 8:17 AM, Thomas Garnier [off-list ref] wrote:
On Tue, Mar 14, 2017 at 2:40 AM, H. Peter Anvin [off-list ref] wrote:
quoted
On 03/13/17 17:04, H. Peter Anvin wrote:
quoted
On 03/11/17 01:42, Ingo Molnar wrote:
quoted
quoted
+ /*
+ * Check user-mode state on fast path return, the same check is done
+ * under the slow path through syscall_return_slowpath.
+ */
+#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
+ call verify_pre_usermode_state
+#else
+ /*
+ * Similar to set_fs(USER_DS) in verify_pre_usermode_state without a
+ * warning.
+ */
+ movq PER_CPU_VAR(current_task), %rax
+ movq $TASK_SIZE_MAX, %rcx
+ cmp %rcx, TASK_addr_limit(%rax)
+ jz 1f
+ movq %rcx, TASK_addr_limit(%rax)
+1:
+#endif
+
How about simply doing...
movq PER_CPU_VAR(current_task), %rax
movq $TASK_SIZE_MAX, %rcx
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
cmpq %rcx, TASK_addr_limit(%rax)
jne syscall_return_slowpath
#else
movq %rcx, TASK_addr_limit(%rax)
#endif
... and let the slow path take care of BUG. This should be much faster,
even with the BUG, and is simpler to boot.
In fact, we could even to the cmpq/jne unconditionally. I'm guessing
the occasional branch mispredict will be offset by occasionally touching
a clean cacheline in the case of an unconditional store.
Since this is something that should never happen, performance doesn't
matter.
Ingo: Which approach do you favor? I want to keep the fast path as
fast as possible obviously.
Even though my name isn't Ingo, Linus keeps trying to get me to be the
actual maintainer of this file. :) How about (sorry about whitespace
damage):
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
movq PER_CPU_VAR(current_task), %rax
bt $63, TASK_addr_limit(%rax)
jc syscall_return_slowpath
#endif
Now the kernel is totally unchanged if the config option is off and
it's fast and simple if the option is on.
From: Thomas Garnier <hidden> Date: 2017-03-14 16:29:28
On Tue, Mar 14, 2017 at 8:39 AM, Andy Lutomirski [off-list ref] wrote:
Even though my name isn't Ingo, Linus keeps trying to get me to be the
actual maintainer of this file. :) How about (sorry about whitespace
damage):
:D
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
movq PER_CPU_VAR(current_task), %rax
bt $63, TASK_addr_limit(%rax)
jc syscall_return_slowpath
#endif
Now the kernel is totally unchanged if the config option is off and
it's fast and simple if the option is on.
I like using bt for fast comparison.
We want to enforce the address limit by default, not only when
CONFIG_BUG_ON_DATA_CORRUPTION is enabled. I tested this one:
/* Check user-mode state on fast path return. */
movq PER_CPU_VAR(current_task), %rax
btq $63, TASK_addr_limit(%rax)
jnc 1f
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
call syscall_return_slowpath
jmp return_from_SYSCALL_64
#else
movq $TASK_SIZE_MAX, %rcx
movq %rcx, TASK_addr_limit(%rax)
#endif
1:
I saw that syscall_return_slowpath is supposed to be called not jumped
to. I could just call verify_pre_usermode_state that would be about
the same.
If we want to avoid if/def then I guess this one is the best I can think of:
/* Check user-mode state on fast path return. */
movq PER_CPU_VAR(current_task), %rax
btq $63, TASK_addr_limit(%rax)
jnc 1f
call verify_pre_usermode_state
1:
The check is fast and the call will happen only on corruption.
What do you think?
--
Thomas
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2017-03-14 16:30:34
On 03/14/17 08:39, Andy Lutomirski wrote:
quoted
Ingo: Which approach do you favor? I want to keep the fast path as
fast as possible obviously.
Even though my name isn't Ingo, Linus keeps trying to get me to be the
actual maintainer of this file. :) How about (sorry about whitespace
damage):
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
movq PER_CPU_VAR(current_task), %rax
bt $63, TASK_addr_limit(%rax)
jc syscall_return_slowpath
#endif
Now the kernel is totally unchanged if the config option is off and
it's fast and simple if the option is on.
The idea as far as I understand was that the option was about whether or
not to clobber the broken value or BUG on it, not to remove the check.
My point, though, was that we can bail out to the slow path if there is
a discrepancy and worry about BUG or not there; performance doesn't
matter one iota if this triggers regardless of the remediation.
It isn't clear that using bt would be faster, though; although it saves
an instruction that instruction can be hoisted arbitrarily and so is
extremely likely to be hidden in the pipeline. cmp (which is really a
variant of sub) is one of the basic ALU instructions that are
super-optimized on every CPU, whereas bt is substantially slower on some
implementations.
This version is also "slightly less secure" since it would make it
possible to overwrite the guard page at the end of TASK_SIZE_MAX if one
could figure out a way to put an arbitrary value into this variable, but
I doubt that matters in any way.
-hpa
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2017-03-14 16:44:56
On 03/14/17 09:29, Thomas Garnier wrote:
We want to enforce the address limit by default, not only when
CONFIG_BUG_ON_DATA_CORRUPTION is enabled. I tested this one:
/* Check user-mode state on fast path return. */
movq PER_CPU_VAR(current_task), %rax
btq $63, TASK_addr_limit(%rax)
jnc 1f
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
call syscall_return_slowpath
jmp return_from_SYSCALL_64
#else
movq $TASK_SIZE_MAX, %rcx
movq %rcx, TASK_addr_limit(%rax)
#endif
1:
I saw that syscall_return_slowpath is supposed to be called not jumped
to. I could just call verify_pre_usermode_state that would be about
the same.
I wanted to comment on that thing: why on earth isn't
verify_pre_usermode_state() an inline? Making it an out-of-line
function adds pointless extra overhead to the C code when we are talking
about a few instructions.
Second, you never do a branch-around to handle an exceptional condition
on the fast path: you jump *out of line* to handle the special
condition; a forward branch is preferred since it is slightly more
likely to be predicted not taken.
Now, I finally had a chance to actually look at the full file (I was
preoccupied yesterday), and am a bit disappointed, to say the least.
First of all, the jump target you need is only a handful of instructions
further down the code path; you need to do *exactly* that is done when
the test of _TIF_ALLWORK_MASK right above is tested! Not only that, but
you already have PER_CPU_VAR(current_task) in %r11 just ready to be
used! This was all in the three instructions immediately prior to the
code you modified...
So, all you'd need would be:
movq $TASK_SIZE_MAX, %rcx
cmpq %rcx, TASK_addr_limit(%r11)
jne 1f
We even get a short jump instruction!
(Using bt saves one more instruction, but see previous caveats about it.)
-hpa
From: Thomas Garnier <hidden> Date: 2017-03-14 16:51:55
On Tue, Mar 14, 2017 at 9:44 AM, H. Peter Anvin [off-list ref] wrote:
On 03/14/17 09:29, Thomas Garnier wrote:
quoted
We want to enforce the address limit by default, not only when
CONFIG_BUG_ON_DATA_CORRUPTION is enabled. I tested this one:
/* Check user-mode state on fast path return. */
movq PER_CPU_VAR(current_task), %rax
btq $63, TASK_addr_limit(%rax)
jnc 1f
#ifdef CONFIG_BUG_ON_DATA_CORRUPTION
call syscall_return_slowpath
jmp return_from_SYSCALL_64
#else
movq $TASK_SIZE_MAX, %rcx
movq %rcx, TASK_addr_limit(%rax)
#endif
1:
I saw that syscall_return_slowpath is supposed to be called not jumped
to. I could just call verify_pre_usermode_state that would be about
the same.
I wanted to comment on that thing: why on earth isn't
verify_pre_usermode_state() an inline? Making it an out-of-line
function adds pointless extra overhead to the C code when we are talking
about a few instructions.
Because outside of arch specific implementation it is called by each
syscall handler. it will increase the code size a lot.
Second, you never do a branch-around to handle an exceptional condition
on the fast path: you jump *out of line* to handle the special
condition; a forward branch is preferred since it is slightly more
likely to be predicted not taken.
Now, I finally had a chance to actually look at the full file (I was
preoccupied yesterday), and am a bit disappointed, to say the least.
First of all, the jump target you need is only a handful of instructions
further down the code path; you need to do *exactly* that is done when
the test of _TIF_ALLWORK_MASK right above is tested! Not only that, but
you already have PER_CPU_VAR(current_task) in %r11 just ready to be
used! This was all in the three instructions immediately prior to the
code you modified...
Correct.
So, all you'd need would be:
movq $TASK_SIZE_MAX, %rcx
cmpq %rcx, TASK_addr_limit(%r11)
jne 1f
We even get a short jump instruction!
(Using bt saves one more instruction, but see previous caveats about it.)
Okay that seems fair to me. Andy what do you think? (Given you
suggested the bt). Ingo?
Thanks for the feedback.
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2017-03-14 17:53:36
On 03/14/17 09:51, Thomas Garnier wrote:
quoted
I wanted to comment on that thing: why on earth isn't
verify_pre_usermode_state() an inline? Making it an out-of-line
function adds pointless extra overhead to the C code when we are talking
about a few instructions.
Because outside of arch specific implementation it is called by each
syscall handler. it will increase the code size a lot.
Don't assume that. On a lot of architectures a function call can be
more expensive than a simple compare and branch, because the compiler
has to assume a whole bunch of registers are lost at that point.
Either way, don't penalize the common architectures for it. Not okay.
-hpa
From: Thomas Garnier <hidden> Date: 2017-03-15 17:43:10
Thanks for the feedback. I will look into inlining by default (looking
at code size on different arch), the updated patch for x86 in the
meantime:
===========
Implement specific usage of verify_pre_usermode_state for user-mode
returns for x86.
---
Based on next-20170308
---
arch/x86/Kconfig | 1 +
arch/x86/entry/common.c | 3 +++
arch/x86/entry/entry_64.S | 8 ++++++++
arch/x86/include/asm/pgtable_64_types.h | 11 +++++++++++
arch/x86/include/asm/processor.h | 11 -----------
5 files changed, 23 insertions(+), 11 deletions(-)
@@ -829,17 +829,6 @@ static inline void spin_lock_prefetch(const void *x)#define KSTK_ESP(task) (task_pt_regs(task)->sp)#else-/*-*Userspaceprocesssize.47bitsminusoneguardpage.Theguard-*pageisnecessaryonIntelCPUs:ifaSYSCALLinstructionisat-*thehighestpossiblecanonicaluserspaceaddress,thenthat-*syscallwillenterthekernelwithanon-canonicalreturn-*address,andSYSRETwillexplodedangerously.Weavoidthis-*particularproblembypreventinganythingfrombeingmapped-*atthemaximumcanonicaladdress.-*/-#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)-/* This decides where the kernel will search for a free chunk of vm*spaceduringmmap's.*/
--
2.12.0.367.g23dc2f6d3c-goog
On Tue, Mar 14, 2017 at 10:53 AM, H. Peter Anvin <hpa@zytor.com> wrote:
> On 03/14/17 09:51, Thomas Garnier wrote:
>>>
>>> I wanted to comment on that thing: why on earth isn't
>>> verify_pre_usermode_state() an inline? Making it an out-of-line
>>> function adds pointless extra overhead to the C code when we are talking
>>> about a few instructions.
>>
>> Because outside of arch specific implementation it is called by each
>> syscall handler. it will increase the code size a lot.
>>
>
> Don't assume that. On a lot of architectures a function call can be
> more expensive than a simple compare and branch, because the compiler
> has to assume a whole bunch of registers are lost at that point.
>
> Either way, don't penalize the common architectures for it. Not okay.
>
> -hpa
>
--
Thomas
@@ -829,17 +829,6 @@ static inline void spin_lock_prefetch(const void *x)#define KSTK_ESP(task) (task_pt_regs(task)->sp)#else-/*-*Userspaceprocesssize.47bitsminusoneguardpage.Theguard-*pageisnecessaryonIntelCPUs:ifaSYSCALLinstructionisat-*thehighestpossiblecanonicaluserspaceaddress,thenthat-*syscallwillenterthekernelwithanon-canonicalreturn-*address,andSYSRETwillexplodedangerously.Weavoidthis-*particularproblembypreventinganythingfrombeingmapped-*atthemaximumcanonicaladdress.-*/-#define TASK_SIZE_MAX ((1UL << 47) - PAGE_SIZE)-/* This decides where the kernel will search for a free chunk of vm*spaceduringmmap's.*/--
2.12.0.367.g23dc2f6d3c-goog
On Tue, Mar 14, 2017 at 10:53 AM, H. Peter Anvin [off-list ref] wrote:
quoted
On 03/14/17 09:51, Thomas Garnier wrote:
quoted
quoted
I wanted to comment on that thing: why on earth isn't
verify_pre_usermode_state() an inline? Making it an out-of-line
function adds pointless extra overhead to the C code when we are talking
about a few instructions.
Because outside of arch specific implementation it is called by each
syscall handler. it will increase the code size a lot.
Don't assume that. On a lot of architectures a function call can be
more expensive than a simple compare and branch, because the compiler
has to assume a whole bunch of registers are lost at that point.
Either way, don't penalize the common architectures for it. Not okay.
-hpa
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2017-03-22 20:21:38
On 03/22/17 12:15, Thomas Garnier wrote:
On Wed, Mar 15, 2017 at 10:43 AM, Thomas Garnier [off-list ref] wrote:
quoted
Thanks for the feedback. I will look into inlining by default (looking
at code size on different arch), the updated patch for x86 in the
meantime:
I did couple checks and it doesn't seem worth it. I will send a v4
with the change below for additional feedback.
Can you specify what that means?
On x86, where there is only one caller of this, it really seems like it
ought to reduce the overhead to almost zero (since it most likely is
hidden in the pipeline.)
I would like to suggest defining it inline if
CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE is set; I really don't
care about an architecture which doesn't have it.
Note that the upcoming 5-level paging (LA57) support will make
TASK_SIZE_MAX dependent on the CPU. The best way to handle that is
probably to tag this immediate with an assembly alternative rather than
loading it from a memory variable (most likely taking a cache hit.)
-hpa
From: Thomas Garnier <hidden> Date: 2017-03-22 20:41:54
On Wed, Mar 22, 2017 at 1:21 PM, H. Peter Anvin [off-list ref] wrote:
On 03/22/17 12:15, Thomas Garnier wrote:
quoted
On Wed, Mar 15, 2017 at 10:43 AM, Thomas Garnier [off-list ref] wrote:
quoted
Thanks for the feedback. I will look into inlining by default (looking
at code size on different arch), the updated patch for x86 in the
meantime:
I did couple checks and it doesn't seem worth it. I will send a v4
with the change below for additional feedback.
Can you specify what that means?
If I set inline by default, the compiler chose not to inline it on
x86. If I force inline the size impact was actually bigger (without
the architecture specific code).
On x86, where there is only one caller of this, it really seems like it
ought to reduce the overhead to almost zero (since it most likely is
hidden in the pipeline.)
I would like to suggest defining it inline if
CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE is set; I really don't
care about an architecture which doesn't have it.
But if there is only one caller, does the compiler is not suppose to
inline the function based on options?
The assembly will call it too, so I would need an inline and a
non-inline based on the caller.
Note that the upcoming 5-level paging (LA57) support will make
TASK_SIZE_MAX dependent on the CPU. The best way to handle that is
probably to tag this immediate with an assembly alternative rather than
loading it from a memory variable (most likely taking a cache hit.)
-hpa
From: "H. Peter Anvin" <hpa@zytor.com> Date: 2017-03-22 20:49:17
On 03/22/17 13:41, Thomas Garnier wrote:
quoted
quoted
with the change below for additional feedback.
Can you specify what that means?
If I set inline by default, the compiler chose not to inline it on
x86. If I force inline the size impact was actually bigger (without
the architecture specific code).
That's utterly bizarre. Something strange is going on there. I suspect
the right thing to do is to out-of-line the error case only, but even
that seems strange. It should be something like four instructions inline.
quoted
On x86, where there is only one caller of this, it really seems like it
ought to reduce the overhead to almost zero (since it most likely is
hidden in the pipeline.)
I would like to suggest defining it inline if
CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE is set; I really don't
care about an architecture which doesn't have it.
But if there is only one caller, does the compiler is not suppose to
inline the function based on options?
If it is marked static in the same file, yes, but you have it in a
different file from what I can tell.
The assembly will call it too, so I would need an inline and a
non-inline based on the caller.
Where? I don't see that anywhere, at least for x86.
-hpa
From: Thomas Garnier <hidden> Date: 2017-03-22 21:11:12
On Wed, Mar 22, 2017 at 1:49 PM, H. Peter Anvin [off-list ref] wrote:
On 03/22/17 13:41, Thomas Garnier wrote:
quoted
quoted
quoted
with the change below for additional feedback.
Can you specify what that means?
If I set inline by default, the compiler chose not to inline it on
x86. If I force inline the size impact was actually bigger (without
the architecture specific code).
That's utterly bizarre. Something strange is going on there. I suspect
the right thing to do is to out-of-line the error case only, but even
that seems strange. It should be something like four instructions inline.
The compiler seemed to often inline other functions called by the
syscall handlers. I assume the growth was due to changes in code
optimization because the function is much larger at the end.
quoted
quoted
On x86, where there is only one caller of this, it really seems like it
ought to reduce the overhead to almost zero (since it most likely is
hidden in the pipeline.)
I would like to suggest defining it inline if
CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE is set; I really don't
care about an architecture which doesn't have it.
But if there is only one caller, does the compiler is not suppose to
inline the function based on options?
If it is marked static in the same file, yes, but you have it in a
different file from what I can tell.
If we do global optimization, it should. Having it as a static inline
make it easier on all types of builds.
quoted
The assembly will call it too, so I would need an inline and a
non-inline based on the caller.
Where? I don't see that anywhere, at least for x86.
After the latest changes on x86, yes. On arm/arm64, we call it with
the CHECK_DATA_CORRUPTION config.