[PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-18 Thread Joerg Roedel
From: Joerg Roedel 

We want x86_tss.sp0 point to the entry stack later to use
it as a trampoline stack for other kernel entry points
besides SYSENTER.

So store the task stack pointer in x86_tss.sp1, which is
otherwise unused by the hardware, as Linux doesn't make use
of Ring 1.

Signed-off-by: Joerg Roedel 
---
 arch/x86/kernel/asm-offsets_32.c | 9 +++--
 arch/x86/kernel/process_32.c | 2 ++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index 15b3f45..82826f2 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -46,9 +46,14 @@ void foo(void)
OFFSET(saved_context_gdt_desc, saved_context, gdt_desc);
BLANK();
 
-   /* Offset from the entry stack to task stack stored in TSS */
+   /*
+* Offset from the entry stack to task stack stored in TSS. Kernel entry
+* happens on the per-cpu entry-stack, and the asm code switches to the
+* task-stack pointer stored in x86_tss.sp1, which is a copy of
+* task->thread.sp0 where entry code can find it.
+*/
DEFINE(TSS_entry2task_stack,
-  offsetof(struct cpu_entry_area, tss.x86_tss.sp0) -
+  offsetof(struct cpu_entry_area, tss.x86_tss.sp1) -
   offsetofend(struct cpu_entry_area, entry_stack_page.stack));
 
 #ifdef CONFIG_STACKPROTECTOR
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 0ae659d..ec62cc7 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -290,6 +290,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct 
*next_p)
this_cpu_write(cpu_current_top_of_stack,
   (unsigned long)task_stack_page(next_p) +
   THREAD_SIZE);
+   /* SYSENTER reads the task-stack from tss.sp1 */
+   this_cpu_write(cpu_tss_rw.x86_tss.sp1, next_p->thread.sp0);
 
/*
 * Restore %gs if needed (which is common)
-- 
2.7.4



Re: [PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-17 Thread Andy Lutomirski
On Tue, Jul 17, 2018 at 12:05 AM, Joerg Roedel  wrote:
> On Fri, Jul 13, 2018 at 04:17:40PM -0700, Andy Lutomirski wrote:
>> I re-read it again.  How about keeping TSS_entry_stack but making it
>> be the offset from the TSS to the entry stack.  Then do the arithmetic
>> in asm.
>
> Hmm, I think its better to keep the arithmetic in the C file for better
> readability. How about renaming it to TSS_entry2task_stack?

That's okay with me.

>
>
> Regards,
>
> Joerg


Re: [PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-17 Thread Joerg Roedel
On Fri, Jul 13, 2018 at 04:17:40PM -0700, Andy Lutomirski wrote:
> I re-read it again.  How about keeping TSS_entry_stack but making it
> be the offset from the TSS to the entry stack.  Then do the arithmetic
> in asm.

Hmm, I think its better to keep the arithmetic in the C file for better
readability. How about renaming it to TSS_entry2task_stack?


Regards,

Joerg


Re: [PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-13 Thread Andy Lutomirski
On Fri, Jul 13, 2018 at 10:19 AM, Andy Lutomirski  wrote:
> On Fri, Jul 13, 2018 at 2:48 AM, Joerg Roedel  wrote:
>> On Thu, Jul 12, 2018 at 01:49:13PM -0700, Andy Lutomirski wrote:
>>> > On Jul 11, 2018, at 4:29 AM, Joerg Roedel  wrote:
>>> >/* Offset from the sysenter stack to tss.sp0 */
>>> > -DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
>>> > tss.x86_tss.sp0) -
>>> > +DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
>>> > tss.x86_tss.sp1) -
>>> >   offsetofend(struct cpu_entry_area, entry_stack_page.stack));
>>> >
>>>
>>> The code reads differently. Did you perhaps mean TSS_task_stack?
>>
>> Well, the offset name came from TSS_sysenter_sp0, which was the offset
>> from the sysenter_sp0 (==sysenter-stack) to the task stack in TSS, now
>> sysenter_sp0 became entry_stack, because its used for all entry points
>> and not only sysenter. So with the old convention the naming makes still
>> sense, no?
>>
>
> Trying to parse it certainly makes my brain hurt a bit.  This is the
> offset from the entry stack to sp1, where sp1 is the location of the
> pointer to the task stack.
>
> Maybe all the arithmetic could go in entry_32.S and the asm-offset
> name could just be TSS_sp1, just like on 64-bit?
>

I re-read it again.  How about keeping TSS_entry_stack but making it
be the offset from the TSS to the entry stack.  Then do the arithmetic
in asm.


Re: [PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-13 Thread Andy Lutomirski
On Fri, Jul 13, 2018 at 2:48 AM, Joerg Roedel  wrote:
> On Thu, Jul 12, 2018 at 01:49:13PM -0700, Andy Lutomirski wrote:
>> > On Jul 11, 2018, at 4:29 AM, Joerg Roedel  wrote:
>> >/* Offset from the sysenter stack to tss.sp0 */
>> > -DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
>> > tss.x86_tss.sp0) -
>> > +DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
>> > tss.x86_tss.sp1) -
>> >   offsetofend(struct cpu_entry_area, entry_stack_page.stack));
>> >
>>
>> The code reads differently. Did you perhaps mean TSS_task_stack?
>
> Well, the offset name came from TSS_sysenter_sp0, which was the offset
> from the sysenter_sp0 (==sysenter-stack) to the task stack in TSS, now
> sysenter_sp0 became entry_stack, because its used for all entry points
> and not only sysenter. So with the old convention the naming makes still
> sense, no?
>

Trying to parse it certainly makes my brain hurt a bit.  This is the
offset from the entry stack to sp1, where sp1 is the location of the
pointer to the task stack.

Maybe all the arithmetic could go in entry_32.S and the asm-offset
name could just be TSS_sp1, just like on 64-bit?

--Andy


Re: [PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-13 Thread Joerg Roedel
On Thu, Jul 12, 2018 at 01:49:13PM -0700, Andy Lutomirski wrote:
> > On Jul 11, 2018, at 4:29 AM, Joerg Roedel  wrote:
> >/* Offset from the sysenter stack to tss.sp0 */
> > -DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
> > tss.x86_tss.sp0) -
> > +DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
> > tss.x86_tss.sp1) -
> >   offsetofend(struct cpu_entry_area, entry_stack_page.stack));
> > 
> 
> The code reads differently. Did you perhaps mean TSS_task_stack?

Well, the offset name came from TSS_sysenter_sp0, which was the offset
from the sysenter_sp0 (==sysenter-stack) to the task stack in TSS, now
sysenter_sp0 became entry_stack, because its used for all entry points
and not only sysenter. So with the old convention the naming makes still
sense, no?

> Also, the “top of task stack” is a bit weird on 32-bit due to vm86.
> Can you document *exactly* what goes in sp1?

Will do, thanks for your feedback!


Joerg


Re: [PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-12 Thread Andy Lutomirski



> On Jul 11, 2018, at 4:29 AM, Joerg Roedel  wrote:
> 
> From: Joerg Roedel 
> We want x86_tss.sp0 point to the entry stack later to use
> it as a trampoline stack for other kernel entry points
> besides SYSENTER.

Makes sense: sp0 will be the entry stack. But:

> 
> 
>/* Offset from the sysenter stack to tss.sp0 */
> -DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, tss.x86_tss.sp0) 
> -
> +DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, tss.x86_tss.sp1) 
> -
>   offsetofend(struct cpu_entry_area, entry_stack_page.stack));
> 

The code reads differently. Did you perhaps mean TSS_task_stack?

Also, the “top of task stack” is a bit weird on 32-bit due to vm86. Can you 
document *exactly* what goes in sp1?



[PATCH 03/39] x86/entry/32: Load task stack from x86_tss.sp1 in SYSENTER handler

2018-07-11 Thread Joerg Roedel
From: Joerg Roedel 

We want x86_tss.sp0 point to the entry stack later to use
it as a trampoline stack for other kernel entry points
besides SYSENTER.

So store the task stack pointer in x86_tss.sp1, which is
otherwise unused by the hardware, as Linux doesn't make use
of Ring 1.

Signed-off-by: Joerg Roedel 
---
 arch/x86/kernel/asm-offsets_32.c | 2 +-
 arch/x86/kernel/process_32.c | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/asm-offsets_32.c b/arch/x86/kernel/asm-offsets_32.c
index ab2d949..36d77d3 100644
--- a/arch/x86/kernel/asm-offsets_32.c
+++ b/arch/x86/kernel/asm-offsets_32.c
@@ -47,7 +47,7 @@ void foo(void)
BLANK();
 
/* Offset from the sysenter stack to tss.sp0 */
-   DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
tss.x86_tss.sp0) -
+   DEFINE(TSS_entry_stack, offsetof(struct cpu_entry_area, 
tss.x86_tss.sp1) -
   offsetofend(struct cpu_entry_area, entry_stack_page.stack));
 
 #ifdef CONFIG_STACKPROTECTOR
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 0ae659d..ec62cc7 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -290,6 +290,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct 
*next_p)
this_cpu_write(cpu_current_top_of_stack,
   (unsigned long)task_stack_page(next_p) +
   THREAD_SIZE);
+   /* SYSENTER reads the task-stack from tss.sp1 */
+   this_cpu_write(cpu_tss_rw.x86_tss.sp1, next_p->thread.sp0);
 
/*
 * Restore %gs if needed (which is common)
-- 
2.7.4