* [RFC PATCH v3 1/6] x86/entry/64: move PUSH_AND_CLEAR_REGS from interrupt macro to helper function
2018-02-20 21:01 [RFC PATCH v3 0/6] x86/entry/64: interrupt entry size reduction Dominik Brodowski
@ 2018-02-20 21:01 ` Dominik Brodowski
2018-02-20 22:25 ` Linus Torvalds
` (2 more replies)
2018-02-20 21:01 ` [RFC PATCH v3 2/6] x86/entry/64: move ENTER_IRQ_STACK from interrupt macro to interrupt_entry Dominik Brodowski
` (4 subsequent siblings)
5 siblings, 3 replies; 23+ messages in thread
From: Dominik Brodowski @ 2018-02-20 21:01 UTC (permalink / raw)
To: linux-kernel, mingo, x86, brgerst, luto, jpoimboe
Cc: torvalds, ak, tglx, dan.j.williams
The PUSH_AND_CLEAR_REGS macro is able to insert the GP registers
"above" the original return address. This allows us to move a sizeable
part of the interrupt entry macro to an interrupt entry helper function:
text data bss dec hex filename
21088 0 0 21088 5260 entry_64.o-orig
18006 0 0 18006 4656 entry_64.o
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
arch/x86/entry/entry_64.S | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 7a53879ec689..b0ae0c3e3815 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -525,6 +525,14 @@ END(irq_entries_start)
*
* Entry runs with interrupts off.
*/
+ENTRY(interrupt_entry)
+ UNWIND_HINT_FUNC
+
+ PUSH_AND_CLEAR_REGS save_ret=1
+ ENCODE_FRAME_POINTER 8
+
+ ret
+END(interrupt_entry)
/* 0(%rsp): ~(interrupt number) */
.macro interrupt func
@@ -536,8 +544,7 @@ END(irq_entries_start)
call switch_to_thread_stack
1:
- PUSH_AND_CLEAR_REGS
- ENCODE_FRAME_POINTER
+ call interrupt_entry
testb $3, CS(%rsp)
jz 1f
--
2.16.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [RFC PATCH v3 1/6] x86/entry/64: move PUSH_AND_CLEAR_REGS from interrupt macro to helper function
2018-02-20 21:01 ` [RFC PATCH v3 1/6] x86/entry/64: move PUSH_AND_CLEAR_REGS from interrupt macro to helper function Dominik Brodowski
@ 2018-02-20 22:25 ` Linus Torvalds
2018-02-21 2:42 ` [PATCH] x86/entry/64: Simplify ENCODE_FRAME_POINTER Josh Poimboeuf
2018-02-21 10:45 ` [tip:x86/pti] x86/entry/64: Move PUSH_AND_CLEAR_REGS from interrupt macro to helper function tip-bot for Dominik Brodowski
2018-02-21 16:58 ` tip-bot for Dominik Brodowski
2 siblings, 1 reply; 23+ messages in thread
From: Linus Torvalds @ 2018-02-20 22:25 UTC (permalink / raw)
To: Dominik Brodowski, Josh Poimboeuf
Cc: Linux Kernel Mailing List, Ingo Molnar, the arch/x86 maintainers,
Brian Gerst, Andrew Lutomirski, Andi Kleen, Thomas Gleixner,
Dan Williams
On Tue, Feb 20, 2018 at 1:01 PM, Dominik Brodowski
<linux@dominikbrodowski.net> wrote:
> +ENTRY(interrupt_entry)
> + UNWIND_HINT_FUNC
> +
> + PUSH_AND_CLEAR_REGS save_ret=1
> + ENCODE_FRAME_POINTER 8
> +
> + ret
> +END(interrupt_entry)
There's nothing wrong with this patch, but it does expose what a nasty
hack our "ENCODE_FRAME_POINTER" thing is.
It generates (when there is an offset, like this):
leaq \ptregs_offset(%rsp), %rbp
orq $0x1, %rbp
and I would _really_ hope that the stack pointer is always aligned on
interrupt entry, so I don't see why it's not just
leaq 1+\ptregs_offset(%rsp), %rbp
instead.
I dunno. Let's ask Josh what the reason for the separate "or" was.
But this is an independent issue of this patch, really.
Linus
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH] x86/entry/64: Simplify ENCODE_FRAME_POINTER
2018-02-20 22:25 ` Linus Torvalds
@ 2018-02-21 2:42 ` Josh Poimboeuf
2018-02-21 10:50 ` [tip:x86/pti] " tip-bot for Josh Poimboeuf
2018-02-21 17:03 ` tip-bot for Josh Poimboeuf
0 siblings, 2 replies; 23+ messages in thread
From: Josh Poimboeuf @ 2018-02-21 2:42 UTC (permalink / raw)
To: Linus Torvalds
Cc: Dominik Brodowski, Linux Kernel Mailing List, Ingo Molnar,
the arch/x86 maintainers, Brian Gerst, Andrew Lutomirski,
Andi Kleen, Thomas Gleixner, Dan Williams
On Tue, Feb 20, 2018 at 02:25:03PM -0800, Linus Torvalds wrote:
> On Tue, Feb 20, 2018 at 1:01 PM, Dominik Brodowski
> <linux@dominikbrodowski.net> wrote:
> > +ENTRY(interrupt_entry)
> > + UNWIND_HINT_FUNC
> > +
> > + PUSH_AND_CLEAR_REGS save_ret=1
> > + ENCODE_FRAME_POINTER 8
> > +
> > + ret
> > +END(interrupt_entry)
>
> There's nothing wrong with this patch, but it does expose what a nasty
> hack our "ENCODE_FRAME_POINTER" thing is.
>
> It generates (when there is an offset, like this):
>
> leaq \ptregs_offset(%rsp), %rbp
> orq $0x1, %rbp
>
> and I would _really_ hope that the stack pointer is always aligned on
> interrupt entry, so I don't see why it's not just
>
> leaq 1+\ptregs_offset(%rsp), %rbp
>
> instead.
>
> I dunno. Let's ask Josh what the reason for the separate "or" was.
>
> But this is an independent issue of this patch, really.
Indeed, how about this?
----
From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] x86/entry/64: Simplify ENCODE_FRAME_POINTER
On 64-bit, the stack pointer is always aligned on interrupt, so instead
of setting the LSB of the pt_regs address, we can just add 1 to it.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
arch/x86/entry/calling.h | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index dce7092ab24a..400cea8bbf4b 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -172,12 +172,7 @@ For 32-bit we have the following conventions - kernel is built with
*/
.macro ENCODE_FRAME_POINTER ptregs_offset=0
#ifdef CONFIG_FRAME_POINTER
- .if \ptregs_offset
- leaq \ptregs_offset(%rsp), %rbp
- .else
- mov %rsp, %rbp
- .endif
- orq $0x1, %rbp
+ leaq 1+\ptregs_offset(%rsp), %rbp
#endif
.endm
--
2.14.3
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Simplify ENCODE_FRAME_POINTER
2018-02-21 2:42 ` [PATCH] x86/entry/64: Simplify ENCODE_FRAME_POINTER Josh Poimboeuf
@ 2018-02-21 10:50 ` tip-bot for Josh Poimboeuf
2018-02-21 17:03 ` tip-bot for Josh Poimboeuf
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Josh Poimboeuf @ 2018-02-21 10:50 UTC (permalink / raw)
To: linux-tip-commits
Cc: luto, tglx, brgerst, linux, peterz, jpoimboe, linux-kernel, hpa,
torvalds, dan.j.williams, mingo
Commit-ID: fa509cf0f52628bb646f85fa12b16231060053e6
Gitweb: https://git.kernel.org/tip/fa509cf0f52628bb646f85fa12b16231060053e6
Author: Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Tue, 20 Feb 2018 20:42:14 -0600
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 10:13:59 +0100
x86/entry/64: Simplify ENCODE_FRAME_POINTER
On 64-bit, the stack pointer is always aligned on interrupt, so instead
of setting the LSB of the pt_regs address, we can just add 1 to it.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrew Lutomirski <luto@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20180221024214.lhl5jfgw33c4vz3m@treble
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/calling.h | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 5d10b7a..be63330 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -181,12 +181,7 @@ For 32-bit we have the following conventions - kernel is built with
*/
.macro ENCODE_FRAME_POINTER ptregs_offset=0
#ifdef CONFIG_FRAME_POINTER
- .if \ptregs_offset
- leaq \ptregs_offset(%rsp), %rbp
- .else
- mov %rsp, %rbp
- .endif
- orq $0x1, %rbp
+ leaq 1+\ptregs_offset(%rsp), %rbp
#endif
.endm
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Simplify ENCODE_FRAME_POINTER
2018-02-21 2:42 ` [PATCH] x86/entry/64: Simplify ENCODE_FRAME_POINTER Josh Poimboeuf
2018-02-21 10:50 ` [tip:x86/pti] " tip-bot for Josh Poimboeuf
@ 2018-02-21 17:03 ` tip-bot for Josh Poimboeuf
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Josh Poimboeuf @ 2018-02-21 17:03 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, mingo, tglx, luto, torvalds, brgerst, jpoimboe,
linux, dan.j.williams, hpa, peterz
Commit-ID: 0ca7d5baa1787e5f2a7abd6bfca3303b1bbb48ac
Gitweb: https://git.kernel.org/tip/0ca7d5baa1787e5f2a7abd6bfca3303b1bbb48ac
Author: Josh Poimboeuf <jpoimboe@redhat.com>
AuthorDate: Tue, 20 Feb 2018 20:42:14 -0600
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 16:54:07 +0100
x86/entry/64: Simplify ENCODE_FRAME_POINTER
On 64-bit, the stack pointer is always aligned on interrupt, so instead
of setting the LSB of the pt_regs address, we can just add 1 to it.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Andrew Lutomirski <luto@kernel.org>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dan Williams <dan.j.williams@intel.com>
Cc: Dominik Brodowski <linux@dominikbrodowski.net>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/20180221024214.lhl5jfgw33c4vz3m@treble
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/calling.h | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
index 5d10b7a..be63330 100644
--- a/arch/x86/entry/calling.h
+++ b/arch/x86/entry/calling.h
@@ -181,12 +181,7 @@ For 32-bit we have the following conventions - kernel is built with
*/
.macro ENCODE_FRAME_POINTER ptregs_offset=0
#ifdef CONFIG_FRAME_POINTER
- .if \ptregs_offset
- leaq \ptregs_offset(%rsp), %rbp
- .else
- mov %rsp, %rbp
- .endif
- orq $0x1, %rbp
+ leaq 1+\ptregs_offset(%rsp), %rbp
#endif
.endm
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move PUSH_AND_CLEAR_REGS from interrupt macro to helper function
2018-02-20 21:01 ` [RFC PATCH v3 1/6] x86/entry/64: move PUSH_AND_CLEAR_REGS from interrupt macro to helper function Dominik Brodowski
2018-02-20 22:25 ` Linus Torvalds
@ 2018-02-21 10:45 ` tip-bot for Dominik Brodowski
2018-02-21 16:58 ` tip-bot for Dominik Brodowski
2 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 10:45 UTC (permalink / raw)
To: linux-tip-commits
Cc: mingo, brgerst, tglx, luto, bp, linux-kernel, dwmw2, torvalds,
dvlasenk, hpa, peterz, linux, jpoimboe
Commit-ID: 6014809adf04188c4bce4a5d231f13a602203c95
Gitweb: https://git.kernel.org/tip/6014809adf04188c4bce4a5d231f13a602203c95
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:08 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 10:04:46 +0100
x86/entry/64: Move PUSH_AND_CLEAR_REGS from interrupt macro to helper function
The PUSH_AND_CLEAR_REGS macro is able to insert the GP registers
"above" the original return address. This allows us to move a sizeable
part of the interrupt entry macro to an interrupt entry helper function:
text data bss dec hex filename
21088 0 0 21088 5260 entry_64.o-orig
18006 0 0 18006 4656 entry_64.o
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-2-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 7a53879..b0ae0c3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -525,6 +525,14 @@ END(irq_entries_start)
*
* Entry runs with interrupts off.
*/
+ENTRY(interrupt_entry)
+ UNWIND_HINT_FUNC
+
+ PUSH_AND_CLEAR_REGS save_ret=1
+ ENCODE_FRAME_POINTER 8
+
+ ret
+END(interrupt_entry)
/* 0(%rsp): ~(interrupt number) */
.macro interrupt func
@@ -536,8 +544,7 @@ END(irq_entries_start)
call switch_to_thread_stack
1:
- PUSH_AND_CLEAR_REGS
- ENCODE_FRAME_POINTER
+ call interrupt_entry
testb $3, CS(%rsp)
jz 1f
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move PUSH_AND_CLEAR_REGS from interrupt macro to helper function
2018-02-20 21:01 ` [RFC PATCH v3 1/6] x86/entry/64: move PUSH_AND_CLEAR_REGS from interrupt macro to helper function Dominik Brodowski
2018-02-20 22:25 ` Linus Torvalds
2018-02-21 10:45 ` [tip:x86/pti] x86/entry/64: Move PUSH_AND_CLEAR_REGS from interrupt macro to helper function tip-bot for Dominik Brodowski
@ 2018-02-21 16:58 ` tip-bot for Dominik Brodowski
2 siblings, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 16:58 UTC (permalink / raw)
To: linux-tip-commits
Cc: jpoimboe, linux-kernel, linux, mingo, bp, luto, tglx, peterz,
dvlasenk, hpa, dwmw2, brgerst, torvalds
Commit-ID: 0e34d226342c27c4f96138b211547d423e4be8a1
Gitweb: https://git.kernel.org/tip/0e34d226342c27c4f96138b211547d423e4be8a1
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:08 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 16:54:03 +0100
x86/entry/64: Move PUSH_AND_CLEAR_REGS from interrupt macro to helper function
The PUSH_AND_CLEAR_REGS macro is able to insert the GP registers
"above" the original return address. This allows us to move a sizeable
part of the interrupt entry macro to an interrupt entry helper function:
text data bss dec hex filename
21088 0 0 21088 5260 entry_64.o-orig
18006 0 0 18006 4656 entry_64.o
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-2-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 7a53879..b0ae0c3 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -525,6 +525,14 @@ END(irq_entries_start)
*
* Entry runs with interrupts off.
*/
+ENTRY(interrupt_entry)
+ UNWIND_HINT_FUNC
+
+ PUSH_AND_CLEAR_REGS save_ret=1
+ ENCODE_FRAME_POINTER 8
+
+ ret
+END(interrupt_entry)
/* 0(%rsp): ~(interrupt number) */
.macro interrupt func
@@ -536,8 +544,7 @@ END(irq_entries_start)
call switch_to_thread_stack
1:
- PUSH_AND_CLEAR_REGS
- ENCODE_FRAME_POINTER
+ call interrupt_entry
testb $3, CS(%rsp)
jz 1f
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [RFC PATCH v3 2/6] x86/entry/64: move ENTER_IRQ_STACK from interrupt macro to interrupt_entry
2018-02-20 21:01 [RFC PATCH v3 0/6] x86/entry/64: interrupt entry size reduction Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 1/6] x86/entry/64: move PUSH_AND_CLEAR_REGS from interrupt macro to helper function Dominik Brodowski
@ 2018-02-20 21:01 ` Dominik Brodowski
2018-02-21 10:46 ` [tip:x86/pti] x86/entry/64: Move " tip-bot for Dominik Brodowski
2018-02-21 16:59 ` tip-bot for Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 3/6] x86/entry/64: move switch_to_thread_stack " Dominik Brodowski
` (3 subsequent siblings)
5 siblings, 2 replies; 23+ messages in thread
From: Dominik Brodowski @ 2018-02-20 21:01 UTC (permalink / raw)
To: linux-kernel, mingo, x86, brgerst, luto, jpoimboe
Cc: torvalds, ak, tglx, dan.j.williams
Moving the switch to IRQ stack from the interrupt macro to the helper
function requires some trickery: All ENTER_IRQ_STACK really cares about
is where the "original" stack -- meaning the GP registers etc. -- is
stored. Therefore, we need to offset the stored RSP value by 8 whenever
ENTER_IRQ_STACK is called from within a function. In such cases, and
after switching to the IRQ stack, we need to push the "original" return
address (i.e. the return address from the call to the interrupt entry
function) to the IRQ stack.
This trickery allows us to carve another .85k from the text size (it
would be more except for the additional unwind hints):
text data bss dec hex filename
18006 0 0 18006 4656 entry_64.o-orig
17158 0 0 17158 4306 entry_64.o
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
arch/x86/entry/entry_64.S | 56 ++++++++++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 18 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index b0ae0c3e3815..7a6ae19962ec 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -448,9 +448,19 @@ END(irq_entries_start)
*
* The invariant is that, if irq_count != -1, then the IRQ stack is in use.
*/
-.macro ENTER_IRQ_STACK regs=1 old_rsp
+.macro ENTER_IRQ_STACK regs=1 old_rsp save_ret=0
DEBUG_ENTRY_ASSERT_IRQS_OFF
+
+ .if \save_ret
+ /*
+ * If save_ret is set, the original stack contains one additional
+ * entry -- the return address. Therefore, move the address one
+ * entry below %rsp to \old_rsp.
+ */
+ leaq 8(%rsp), \old_rsp
+ .else
movq %rsp, \old_rsp
+ .endif
.if \regs
UNWIND_HINT_REGS base=\old_rsp
@@ -496,6 +506,15 @@ END(irq_entries_start)
.if \regs
UNWIND_HINT_REGS indirect=1
.endif
+
+ .if \save_ret
+ /*
+ * Push the return address to the stack. This return address can
+ * be found at the "real" original RSP, which was offset by 8 at
+ * the beginning of this macro.
+ */
+ pushq -8(\old_rsp)
+ .endif
.endm
/*
@@ -531,22 +550,7 @@ ENTRY(interrupt_entry)
PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8
- ret
-END(interrupt_entry)
-
-/* 0(%rsp): ~(interrupt number) */
- .macro interrupt func
- cld
-
- testb $3, CS-ORIG_RAX(%rsp)
- jz 1f
- SWAPGS
- call switch_to_thread_stack
-1:
-
- call interrupt_entry
-
- testb $3, CS(%rsp)
+ testb $3, CS+8(%rsp)
jz 1f
/*
@@ -564,10 +568,26 @@ END(interrupt_entry)
CALL_enter_from_user_mode
1:
- ENTER_IRQ_STACK old_rsp=%rdi
+ ENTER_IRQ_STACK old_rsp=%rdi save_ret=1
/* We entered an interrupt context - irqs are off: */
TRACE_IRQS_OFF
+ ret
+END(interrupt_entry)
+
+/* 0(%rsp): ~(interrupt number) */
+ .macro interrupt func
+ cld
+
+ testb $3, CS-ORIG_RAX(%rsp)
+ jz 1f
+ SWAPGS
+ call switch_to_thread_stack
+1:
+
+ call interrupt_entry
+
+ UNWIND_HINT_REGS indirect=1
call \func /* rdi points to pt_regs */
.endm
--
2.16.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move ENTER_IRQ_STACK from interrupt macro to interrupt_entry
2018-02-20 21:01 ` [RFC PATCH v3 2/6] x86/entry/64: move ENTER_IRQ_STACK from interrupt macro to interrupt_entry Dominik Brodowski
@ 2018-02-21 10:46 ` tip-bot for Dominik Brodowski
2018-02-21 16:59 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 10:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: dwmw2, tglx, hpa, torvalds, brgerst, bp, dvlasenk, mingo,
linux-kernel, peterz, linux, luto, jpoimboe
Commit-ID: 484689299ece526dd75088946c2307c3a74d9d67
Gitweb: https://git.kernel.org/tip/484689299ece526dd75088946c2307c3a74d9d67
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:09 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 10:04:46 +0100
x86/entry/64: Move ENTER_IRQ_STACK from interrupt macro to interrupt_entry
Moving the switch to IRQ stack from the interrupt macro to the helper
function requires some trickery: All ENTER_IRQ_STACK really cares about
is where the "original" stack -- meaning the GP registers etc. -- is
stored. Therefore, we need to offset the stored RSP value by 8 whenever
ENTER_IRQ_STACK is called from within a function. In such cases, and
after switching to the IRQ stack, we need to push the "original" return
address (i.e. the return address from the call to the interrupt entry
function) to the IRQ stack.
This trickery allows us to carve another .85k from the text size (it
would be more except for the additional unwind hints):
text data bss dec hex filename
18006 0 0 18006 4656 entry_64.o-orig
17158 0 0 17158 4306 entry_64.o
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-3-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 56 ++++++++++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 18 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index b0ae0c3..7a6ae19 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -448,9 +448,19 @@ END(irq_entries_start)
*
* The invariant is that, if irq_count != -1, then the IRQ stack is in use.
*/
-.macro ENTER_IRQ_STACK regs=1 old_rsp
+.macro ENTER_IRQ_STACK regs=1 old_rsp save_ret=0
DEBUG_ENTRY_ASSERT_IRQS_OFF
+
+ .if \save_ret
+ /*
+ * If save_ret is set, the original stack contains one additional
+ * entry -- the return address. Therefore, move the address one
+ * entry below %rsp to \old_rsp.
+ */
+ leaq 8(%rsp), \old_rsp
+ .else
movq %rsp, \old_rsp
+ .endif
.if \regs
UNWIND_HINT_REGS base=\old_rsp
@@ -496,6 +506,15 @@ END(irq_entries_start)
.if \regs
UNWIND_HINT_REGS indirect=1
.endif
+
+ .if \save_ret
+ /*
+ * Push the return address to the stack. This return address can
+ * be found at the "real" original RSP, which was offset by 8 at
+ * the beginning of this macro.
+ */
+ pushq -8(\old_rsp)
+ .endif
.endm
/*
@@ -531,22 +550,7 @@ ENTRY(interrupt_entry)
PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8
- ret
-END(interrupt_entry)
-
-/* 0(%rsp): ~(interrupt number) */
- .macro interrupt func
- cld
-
- testb $3, CS-ORIG_RAX(%rsp)
- jz 1f
- SWAPGS
- call switch_to_thread_stack
-1:
-
- call interrupt_entry
-
- testb $3, CS(%rsp)
+ testb $3, CS+8(%rsp)
jz 1f
/*
@@ -564,10 +568,26 @@ END(interrupt_entry)
CALL_enter_from_user_mode
1:
- ENTER_IRQ_STACK old_rsp=%rdi
+ ENTER_IRQ_STACK old_rsp=%rdi save_ret=1
/* We entered an interrupt context - irqs are off: */
TRACE_IRQS_OFF
+ ret
+END(interrupt_entry)
+
+/* 0(%rsp): ~(interrupt number) */
+ .macro interrupt func
+ cld
+
+ testb $3, CS-ORIG_RAX(%rsp)
+ jz 1f
+ SWAPGS
+ call switch_to_thread_stack
+1:
+
+ call interrupt_entry
+
+ UNWIND_HINT_REGS indirect=1
call \func /* rdi points to pt_regs */
.endm
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move ENTER_IRQ_STACK from interrupt macro to interrupt_entry
2018-02-20 21:01 ` [RFC PATCH v3 2/6] x86/entry/64: move ENTER_IRQ_STACK from interrupt macro to interrupt_entry Dominik Brodowski
2018-02-21 10:46 ` [tip:x86/pti] x86/entry/64: Move " tip-bot for Dominik Brodowski
@ 2018-02-21 16:59 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 16:59 UTC (permalink / raw)
To: linux-tip-commits
Cc: luto, hpa, peterz, dwmw2, linux, tglx, brgerst, torvalds,
linux-kernel, bp, jpoimboe, mingo, dvlasenk
Commit-ID: 2ba6474104a1132c4af9f6dc42c6bfe3ca71f8c7
Gitweb: https://git.kernel.org/tip/2ba6474104a1132c4af9f6dc42c6bfe3ca71f8c7
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:09 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 16:54:03 +0100
x86/entry/64: Move ENTER_IRQ_STACK from interrupt macro to interrupt_entry
Moving the switch to IRQ stack from the interrupt macro to the helper
function requires some trickery: All ENTER_IRQ_STACK really cares about
is where the "original" stack -- meaning the GP registers etc. -- is
stored. Therefore, we need to offset the stored RSP value by 8 whenever
ENTER_IRQ_STACK is called from within a function. In such cases, and
after switching to the IRQ stack, we need to push the "original" return
address (i.e. the return address from the call to the interrupt entry
function) to the IRQ stack.
This trickery allows us to carve another .85k from the text size (it
would be more except for the additional unwind hints):
text data bss dec hex filename
18006 0 0 18006 4656 entry_64.o-orig
17158 0 0 17158 4306 entry_64.o
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-3-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 56 ++++++++++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 18 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index b0ae0c3..7a6ae19 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -448,9 +448,19 @@ END(irq_entries_start)
*
* The invariant is that, if irq_count != -1, then the IRQ stack is in use.
*/
-.macro ENTER_IRQ_STACK regs=1 old_rsp
+.macro ENTER_IRQ_STACK regs=1 old_rsp save_ret=0
DEBUG_ENTRY_ASSERT_IRQS_OFF
+
+ .if \save_ret
+ /*
+ * If save_ret is set, the original stack contains one additional
+ * entry -- the return address. Therefore, move the address one
+ * entry below %rsp to \old_rsp.
+ */
+ leaq 8(%rsp), \old_rsp
+ .else
movq %rsp, \old_rsp
+ .endif
.if \regs
UNWIND_HINT_REGS base=\old_rsp
@@ -496,6 +506,15 @@ END(irq_entries_start)
.if \regs
UNWIND_HINT_REGS indirect=1
.endif
+
+ .if \save_ret
+ /*
+ * Push the return address to the stack. This return address can
+ * be found at the "real" original RSP, which was offset by 8 at
+ * the beginning of this macro.
+ */
+ pushq -8(\old_rsp)
+ .endif
.endm
/*
@@ -531,22 +550,7 @@ ENTRY(interrupt_entry)
PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8
- ret
-END(interrupt_entry)
-
-/* 0(%rsp): ~(interrupt number) */
- .macro interrupt func
- cld
-
- testb $3, CS-ORIG_RAX(%rsp)
- jz 1f
- SWAPGS
- call switch_to_thread_stack
-1:
-
- call interrupt_entry
-
- testb $3, CS(%rsp)
+ testb $3, CS+8(%rsp)
jz 1f
/*
@@ -564,10 +568,26 @@ END(interrupt_entry)
CALL_enter_from_user_mode
1:
- ENTER_IRQ_STACK old_rsp=%rdi
+ ENTER_IRQ_STACK old_rsp=%rdi save_ret=1
/* We entered an interrupt context - irqs are off: */
TRACE_IRQS_OFF
+ ret
+END(interrupt_entry)
+
+/* 0(%rsp): ~(interrupt number) */
+ .macro interrupt func
+ cld
+
+ testb $3, CS-ORIG_RAX(%rsp)
+ jz 1f
+ SWAPGS
+ call switch_to_thread_stack
+1:
+
+ call interrupt_entry
+
+ UNWIND_HINT_REGS indirect=1
call \func /* rdi points to pt_regs */
.endm
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [RFC PATCH v3 3/6] x86/entry/64: move switch_to_thread_stack to interrupt_entry
2018-02-20 21:01 [RFC PATCH v3 0/6] x86/entry/64: interrupt entry size reduction Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 1/6] x86/entry/64: move PUSH_AND_CLEAR_REGS from interrupt macro to helper function Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 2/6] x86/entry/64: move ENTER_IRQ_STACK from interrupt macro to interrupt_entry Dominik Brodowski
@ 2018-02-20 21:01 ` Dominik Brodowski
2018-02-21 10:46 ` [tip:x86/pti] x86/entry/64: Move the switch_to_thread_stack() call to interrupt_entry() tip-bot for Dominik Brodowski
2018-02-21 16:59 ` tip-bot for Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 4/6] x86/entry/64: remove interrupt macro Dominik Brodowski
` (2 subsequent siblings)
5 siblings, 2 replies; 23+ messages in thread
From: Dominik Brodowski @ 2018-02-20 21:01 UTC (permalink / raw)
To: linux-kernel, mingo, x86, brgerst, luto, jpoimboe
Cc: torvalds, ak, tglx, dan.j.williams
We can also move the CLD, SWAPGS, and the switch_to_thread_stack to the
interrupt_entry helper function. As we do not want call depths of two,
convert switch_to_thread_stack to a macro.
However, switch_to_thread_stack has another user in entry_64_compat.S,
which currently expects it to be a function. To keep the code changes
in this patch minimal, create a wrapper function.
The switch to a macro means that there is some binary code duplication
if CONFIG_IA32_EMULATION is enabled. Therefore, the size reduction
differs whether CONFIG_IA32_EMULATION is enabled or not:
CONFIG_IA32_EMULATION=y (-0.13k):
text data bss dec hex filename
17158 0 0 17158 4306 entry_64.o-orig
17028 0 0 17028 4284 entry_64.o
CONFIG_IA32_EMULATION=n (-0.27k):
text data bss dec hex filename
17158 0 0 17158 4306 entry_64.o-orig
16882 0 0 16882 41f2 entry_64.o
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
arch/x86/entry/entry_64.S | 66 ++++++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 29 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 7a6ae19962ec..b45d76649eff 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -537,6 +537,31 @@ END(irq_entries_start)
decl PER_CPU_VAR(irq_count)
.endm
+/*
+ * Switch to the thread stack. This is called with the IRET frame and
+ * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
+ * space has not been allocated for them.)
+ */
+.macro DO_SWITCH_TO_THREAD_STACK
+ pushq %rdi
+ /* Need to switch before accessing the thread stack. */
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+ movq %rsp, %rdi
+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+ UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
+
+ pushq 7*8(%rdi) /* regs->ss */
+ pushq 6*8(%rdi) /* regs->rsp */
+ pushq 5*8(%rdi) /* regs->eflags */
+ pushq 4*8(%rdi) /* regs->cs */
+ pushq 3*8(%rdi) /* regs->ip */
+ pushq 2*8(%rdi) /* regs->orig_ax */
+ pushq 8(%rdi) /* return address */
+ UNWIND_HINT_FUNC
+
+ movq (%rdi), %rdi
+.endm
+
/*
* Interrupt entry/exit.
*
@@ -544,8 +569,16 @@ END(irq_entries_start)
*
* Entry runs with interrupts off.
*/
+/* 8(%rsp): ~(interrupt number) */
ENTRY(interrupt_entry)
UNWIND_HINT_FUNC
+ cld
+
+ testb $3, CS-ORIG_RAX+8(%rsp)
+ jz 1f
+ SWAPGS
+ DO_SWITCH_TO_THREAD_STACK
+1:
PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8
@@ -577,14 +610,6 @@ END(interrupt_entry)
/* 0(%rsp): ~(interrupt number) */
.macro interrupt func
- cld
-
- testb $3, CS-ORIG_RAX(%rsp)
- jz 1f
- SWAPGS
- call switch_to_thread_stack
-1:
-
call interrupt_entry
UNWIND_HINT_REGS indirect=1
@@ -858,33 +883,16 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
*/
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
-/*
- * Switch to the thread stack. This is called with the IRET frame and
- * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
- * space has not been allocated for them.)
- */
+#if defined(CONFIG_IA32_EMULATION)
+/* entry_64_compat.S::entry_INT80_compat expects this to be an ASM function */
ENTRY(switch_to_thread_stack)
UNWIND_HINT_FUNC
- pushq %rdi
- /* Need to switch before accessing the thread stack. */
- SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
- movq %rsp, %rdi
- movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
-
- pushq 7*8(%rdi) /* regs->ss */
- pushq 6*8(%rdi) /* regs->rsp */
- pushq 5*8(%rdi) /* regs->eflags */
- pushq 4*8(%rdi) /* regs->cs */
- pushq 3*8(%rdi) /* regs->ip */
- pushq 2*8(%rdi) /* regs->orig_ax */
- pushq 8(%rdi) /* return address */
- UNWIND_HINT_FUNC
+ DO_SWITCH_TO_THREAD_STACK
- movq (%rdi), %rdi
ret
END(switch_to_thread_stack)
+#endif
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
ENTRY(\sym)
--
2.16.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move the switch_to_thread_stack() call to interrupt_entry()
2018-02-20 21:01 ` [RFC PATCH v3 3/6] x86/entry/64: move switch_to_thread_stack " Dominik Brodowski
@ 2018-02-21 10:46 ` tip-bot for Dominik Brodowski
2018-02-21 16:59 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 10:46 UTC (permalink / raw)
To: linux-tip-commits
Cc: bp, dwmw2, dvlasenk, brgerst, hpa, torvalds, peterz,
linux-kernel, tglx, luto, linux, mingo, jpoimboe
Commit-ID: 359cc2d9e0a810808a90adda3e612e2fef49f2cd
Gitweb: https://git.kernel.org/tip/359cc2d9e0a810808a90adda3e612e2fef49f2cd
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:10 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 10:04:47 +0100
x86/entry/64: Move the switch_to_thread_stack() call to interrupt_entry()
We can also move the CLD, SWAPGS, and the switch_to_thread_stack() call
to the interrupt_entry() helper function. As we do not want call depths
of two, convert switch_to_thread_stack() to a macro.
However, switch_to_thread_stack() has another user in entry_64_compat.S,
which currently expects it to be a function. To keep the code changes
in this patch minimal, create a wrapper function.
The switch to a macro means that there is some binary code duplication
if CONFIG_IA32_EMULATION=y is enabled. Therefore, the size reduction
differs whether CONFIG_IA32_EMULATION is enabled or not:
CONFIG_IA32_EMULATION=y (-0.13k):
text data bss dec hex filename
17158 0 0 17158 4306 entry_64.o-orig
17028 0 0 17028 4284 entry_64.o
CONFIG_IA32_EMULATION=n (-0.27k):
text data bss dec hex filename
17158 0 0 17158 4306 entry_64.o-orig
16882 0 0 16882 41f2 entry_64.o
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-4-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 66 ++++++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 29 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 7a6ae19..b45d766 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -538,14 +538,47 @@ END(irq_entries_start)
.endm
/*
+ * Switch to the thread stack. This is called with the IRET frame and
+ * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
+ * space has not been allocated for them.)
+ */
+.macro DO_SWITCH_TO_THREAD_STACK
+ pushq %rdi
+ /* Need to switch before accessing the thread stack. */
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+ movq %rsp, %rdi
+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+ UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
+
+ pushq 7*8(%rdi) /* regs->ss */
+ pushq 6*8(%rdi) /* regs->rsp */
+ pushq 5*8(%rdi) /* regs->eflags */
+ pushq 4*8(%rdi) /* regs->cs */
+ pushq 3*8(%rdi) /* regs->ip */
+ pushq 2*8(%rdi) /* regs->orig_ax */
+ pushq 8(%rdi) /* return address */
+ UNWIND_HINT_FUNC
+
+ movq (%rdi), %rdi
+.endm
+
+/*
* Interrupt entry/exit.
*
* Interrupt entry points save only callee clobbered registers in fast path.
*
* Entry runs with interrupts off.
*/
+/* 8(%rsp): ~(interrupt number) */
ENTRY(interrupt_entry)
UNWIND_HINT_FUNC
+ cld
+
+ testb $3, CS-ORIG_RAX+8(%rsp)
+ jz 1f
+ SWAPGS
+ DO_SWITCH_TO_THREAD_STACK
+1:
PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8
@@ -577,14 +610,6 @@ END(interrupt_entry)
/* 0(%rsp): ~(interrupt number) */
.macro interrupt func
- cld
-
- testb $3, CS-ORIG_RAX(%rsp)
- jz 1f
- SWAPGS
- call switch_to_thread_stack
-1:
-
call interrupt_entry
UNWIND_HINT_REGS indirect=1
@@ -858,33 +883,16 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
*/
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
-/*
- * Switch to the thread stack. This is called with the IRET frame and
- * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
- * space has not been allocated for them.)
- */
+#if defined(CONFIG_IA32_EMULATION)
+/* entry_64_compat.S::entry_INT80_compat expects this to be an ASM function */
ENTRY(switch_to_thread_stack)
UNWIND_HINT_FUNC
- pushq %rdi
- /* Need to switch before accessing the thread stack. */
- SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
- movq %rsp, %rdi
- movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
-
- pushq 7*8(%rdi) /* regs->ss */
- pushq 6*8(%rdi) /* regs->rsp */
- pushq 5*8(%rdi) /* regs->eflags */
- pushq 4*8(%rdi) /* regs->cs */
- pushq 3*8(%rdi) /* regs->ip */
- pushq 2*8(%rdi) /* regs->orig_ax */
- pushq 8(%rdi) /* return address */
- UNWIND_HINT_FUNC
+ DO_SWITCH_TO_THREAD_STACK
- movq (%rdi), %rdi
ret
END(switch_to_thread_stack)
+#endif
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
ENTRY(\sym)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move the switch_to_thread_stack() call to interrupt_entry()
2018-02-20 21:01 ` [RFC PATCH v3 3/6] x86/entry/64: move switch_to_thread_stack " Dominik Brodowski
2018-02-21 10:46 ` [tip:x86/pti] x86/entry/64: Move the switch_to_thread_stack() call to interrupt_entry() tip-bot for Dominik Brodowski
@ 2018-02-21 16:59 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 16:59 UTC (permalink / raw)
To: linux-tip-commits
Cc: hpa, linux-kernel, torvalds, mingo, dwmw2, brgerst, tglx, luto,
jpoimboe, linux, peterz, dvlasenk, bp
Commit-ID: 90a6acc4e7ebafa8672a7a1a5b23fbad3dd04130
Gitweb: https://git.kernel.org/tip/90a6acc4e7ebafa8672a7a1a5b23fbad3dd04130
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:10 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 16:54:04 +0100
x86/entry/64: Move the switch_to_thread_stack() call to interrupt_entry()
We can also move the CLD, SWAPGS, and the switch_to_thread_stack() call
to the interrupt_entry() helper function. As we do not want call depths
of two, convert switch_to_thread_stack() to a macro.
However, switch_to_thread_stack() has another user in entry_64_compat.S,
which currently expects it to be a function. To keep the code changes
in this patch minimal, create a wrapper function.
The switch to a macro means that there is some binary code duplication
if CONFIG_IA32_EMULATION=y is enabled. Therefore, the size reduction
differs whether CONFIG_IA32_EMULATION is enabled or not:
CONFIG_IA32_EMULATION=y (-0.13k):
text data bss dec hex filename
17158 0 0 17158 4306 entry_64.o-orig
17028 0 0 17028 4284 entry_64.o
CONFIG_IA32_EMULATION=n (-0.27k):
text data bss dec hex filename
17158 0 0 17158 4306 entry_64.o-orig
16882 0 0 16882 41f2 entry_64.o
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-4-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 66 ++++++++++++++++++++++++++---------------------
1 file changed, 37 insertions(+), 29 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 7a6ae19..b45d766 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -538,14 +538,47 @@ END(irq_entries_start)
.endm
/*
+ * Switch to the thread stack. This is called with the IRET frame and
+ * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
+ * space has not been allocated for them.)
+ */
+.macro DO_SWITCH_TO_THREAD_STACK
+ pushq %rdi
+ /* Need to switch before accessing the thread stack. */
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+ movq %rsp, %rdi
+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+ UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
+
+ pushq 7*8(%rdi) /* regs->ss */
+ pushq 6*8(%rdi) /* regs->rsp */
+ pushq 5*8(%rdi) /* regs->eflags */
+ pushq 4*8(%rdi) /* regs->cs */
+ pushq 3*8(%rdi) /* regs->ip */
+ pushq 2*8(%rdi) /* regs->orig_ax */
+ pushq 8(%rdi) /* return address */
+ UNWIND_HINT_FUNC
+
+ movq (%rdi), %rdi
+.endm
+
+/*
* Interrupt entry/exit.
*
* Interrupt entry points save only callee clobbered registers in fast path.
*
* Entry runs with interrupts off.
*/
+/* 8(%rsp): ~(interrupt number) */
ENTRY(interrupt_entry)
UNWIND_HINT_FUNC
+ cld
+
+ testb $3, CS-ORIG_RAX+8(%rsp)
+ jz 1f
+ SWAPGS
+ DO_SWITCH_TO_THREAD_STACK
+1:
PUSH_AND_CLEAR_REGS save_ret=1
ENCODE_FRAME_POINTER 8
@@ -577,14 +610,6 @@ END(interrupt_entry)
/* 0(%rsp): ~(interrupt number) */
.macro interrupt func
- cld
-
- testb $3, CS-ORIG_RAX(%rsp)
- jz 1f
- SWAPGS
- call switch_to_thread_stack
-1:
-
call interrupt_entry
UNWIND_HINT_REGS indirect=1
@@ -858,33 +883,16 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
*/
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
-/*
- * Switch to the thread stack. This is called with the IRET frame and
- * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
- * space has not been allocated for them.)
- */
+#if defined(CONFIG_IA32_EMULATION)
+/* entry_64_compat.S::entry_INT80_compat expects this to be an ASM function */
ENTRY(switch_to_thread_stack)
UNWIND_HINT_FUNC
- pushq %rdi
- /* Need to switch before accessing the thread stack. */
- SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
- movq %rsp, %rdi
- movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
-
- pushq 7*8(%rdi) /* regs->ss */
- pushq 6*8(%rdi) /* regs->rsp */
- pushq 5*8(%rdi) /* regs->eflags */
- pushq 4*8(%rdi) /* regs->cs */
- pushq 3*8(%rdi) /* regs->ip */
- pushq 2*8(%rdi) /* regs->orig_ax */
- pushq 8(%rdi) /* return address */
- UNWIND_HINT_FUNC
+ DO_SWITCH_TO_THREAD_STACK
- movq (%rdi), %rdi
ret
END(switch_to_thread_stack)
+#endif
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
ENTRY(\sym)
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [RFC PATCH v3 4/6] x86/entry/64: remove interrupt macro
2018-02-20 21:01 [RFC PATCH v3 0/6] x86/entry/64: interrupt entry size reduction Dominik Brodowski
` (2 preceding siblings ...)
2018-02-20 21:01 ` [RFC PATCH v3 3/6] x86/entry/64: move switch_to_thread_stack " Dominik Brodowski
@ 2018-02-20 21:01 ` Dominik Brodowski
2018-02-21 10:47 ` [tip:x86/pti] x86/entry/64: Remove 'interrupt' macro tip-bot for Dominik Brodowski
2018-02-21 17:00 ` tip-bot for Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 5/6] x86/entry/64: move ASM_CLAC to interrupt_entry Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 6/6] x86/entry/64: open-code switch_to_thread_stack Dominik Brodowski
5 siblings, 2 replies; 23+ messages in thread
From: Dominik Brodowski @ 2018-02-20 21:01 UTC (permalink / raw)
To: linux-kernel, mingo, x86, brgerst, luto, jpoimboe
Cc: torvalds, ak, tglx, dan.j.williams
It is now trivial to call interrupt_entry and then the actual worker.
Therefore, remove the interrupt macro.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
arch/x86/entry/entry_64.S | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index b45d76649eff..8ea03cf94a2d 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -608,14 +608,6 @@ ENTRY(interrupt_entry)
ret
END(interrupt_entry)
-/* 0(%rsp): ~(interrupt number) */
- .macro interrupt func
- call interrupt_entry
-
- UNWIND_HINT_REGS indirect=1
- call \func /* rdi points to pt_regs */
- .endm
-
/*
* The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt.
@@ -624,7 +616,9 @@ END(interrupt_entry)
common_interrupt:
ASM_CLAC
addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */
- interrupt do_IRQ
+ call interrupt_entry
+ UNWIND_HINT_REGS indirect=1
+ call do_IRQ /* rdi points to pt_regs */
/* 0(%rsp): old RSP */
ret_from_intr:
DISABLE_INTERRUPTS(CLBR_ANY)
@@ -820,7 +814,9 @@ ENTRY(\sym)
ASM_CLAC
pushq $~(\num)
.Lcommon_\sym:
- interrupt \do_sym
+ call interrupt_entry
+ UNWIND_HINT_REGS indirect=1
+ call \do_sym /* rdi points to pt_regs */
jmp ret_from_intr
END(\sym)
.endm
--
2.16.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Remove 'interrupt' macro
2018-02-20 21:01 ` [RFC PATCH v3 4/6] x86/entry/64: remove interrupt macro Dominik Brodowski
@ 2018-02-21 10:47 ` tip-bot for Dominik Brodowski
2018-02-21 17:00 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 10:47 UTC (permalink / raw)
To: linux-tip-commits
Cc: linux-kernel, linux, mingo, dwmw2, jpoimboe, brgerst, hpa, bp,
luto, dvlasenk, torvalds, tglx, peterz
Commit-ID: 9aaa78dee43a61febabddeab44ea9da90dd05ba8
Gitweb: https://git.kernel.org/tip/9aaa78dee43a61febabddeab44ea9da90dd05ba8
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:11 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 10:04:47 +0100
x86/entry/64: Remove 'interrupt' macro
It is now trivial to call interrupt_entry() and then the actual worker.
Therefore, remove the interrupt macro and open code it all.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-5-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index b45d766..8ea03cf 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -608,14 +608,6 @@ ENTRY(interrupt_entry)
ret
END(interrupt_entry)
-/* 0(%rsp): ~(interrupt number) */
- .macro interrupt func
- call interrupt_entry
-
- UNWIND_HINT_REGS indirect=1
- call \func /* rdi points to pt_regs */
- .endm
-
/*
* The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt.
@@ -624,7 +616,9 @@ END(interrupt_entry)
common_interrupt:
ASM_CLAC
addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */
- interrupt do_IRQ
+ call interrupt_entry
+ UNWIND_HINT_REGS indirect=1
+ call do_IRQ /* rdi points to pt_regs */
/* 0(%rsp): old RSP */
ret_from_intr:
DISABLE_INTERRUPTS(CLBR_ANY)
@@ -820,7 +814,9 @@ ENTRY(\sym)
ASM_CLAC
pushq $~(\num)
.Lcommon_\sym:
- interrupt \do_sym
+ call interrupt_entry
+ UNWIND_HINT_REGS indirect=1
+ call \do_sym /* rdi points to pt_regs */
jmp ret_from_intr
END(\sym)
.endm
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Remove 'interrupt' macro
2018-02-20 21:01 ` [RFC PATCH v3 4/6] x86/entry/64: remove interrupt macro Dominik Brodowski
2018-02-21 10:47 ` [tip:x86/pti] x86/entry/64: Remove 'interrupt' macro tip-bot for Dominik Brodowski
@ 2018-02-21 17:00 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 17:00 UTC (permalink / raw)
To: linux-tip-commits
Cc: mingo, hpa, tglx, bp, peterz, dwmw2, jpoimboe, luto, linux,
torvalds, linux-kernel, dvlasenk, brgerst
Commit-ID: 3aa99fc3e708b9cd9b4cfe2df0b7a66cf293e3cf
Gitweb: https://git.kernel.org/tip/3aa99fc3e708b9cd9b4cfe2df0b7a66cf293e3cf
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:11 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 16:54:04 +0100
x86/entry/64: Remove 'interrupt' macro
It is now trivial to call interrupt_entry() and then the actual worker.
Therefore, remove the interrupt macro and open code it all.
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-5-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 16 ++++++----------
1 file changed, 6 insertions(+), 10 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index b45d766..8ea03cf 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -608,14 +608,6 @@ ENTRY(interrupt_entry)
ret
END(interrupt_entry)
-/* 0(%rsp): ~(interrupt number) */
- .macro interrupt func
- call interrupt_entry
-
- UNWIND_HINT_REGS indirect=1
- call \func /* rdi points to pt_regs */
- .endm
-
/*
* The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt.
@@ -624,7 +616,9 @@ END(interrupt_entry)
common_interrupt:
ASM_CLAC
addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */
- interrupt do_IRQ
+ call interrupt_entry
+ UNWIND_HINT_REGS indirect=1
+ call do_IRQ /* rdi points to pt_regs */
/* 0(%rsp): old RSP */
ret_from_intr:
DISABLE_INTERRUPTS(CLBR_ANY)
@@ -820,7 +814,9 @@ ENTRY(\sym)
ASM_CLAC
pushq $~(\num)
.Lcommon_\sym:
- interrupt \do_sym
+ call interrupt_entry
+ UNWIND_HINT_REGS indirect=1
+ call \do_sym /* rdi points to pt_regs */
jmp ret_from_intr
END(\sym)
.endm
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [RFC PATCH v3 5/6] x86/entry/64: move ASM_CLAC to interrupt_entry
2018-02-20 21:01 [RFC PATCH v3 0/6] x86/entry/64: interrupt entry size reduction Dominik Brodowski
` (3 preceding siblings ...)
2018-02-20 21:01 ` [RFC PATCH v3 4/6] x86/entry/64: remove interrupt macro Dominik Brodowski
@ 2018-02-20 21:01 ` Dominik Brodowski
2018-02-21 10:47 ` [tip:x86/pti] x86/entry/64: Move ASM_CLAC to interrupt_entry() tip-bot for Dominik Brodowski
2018-02-21 17:00 ` tip-bot for Dominik Brodowski
2018-02-20 21:01 ` [RFC PATCH v3 6/6] x86/entry/64: open-code switch_to_thread_stack Dominik Brodowski
5 siblings, 2 replies; 23+ messages in thread
From: Dominik Brodowski @ 2018-02-20 21:01 UTC (permalink / raw)
To: linux-kernel, mingo, x86, brgerst, luto, jpoimboe
Cc: torvalds, ak, tglx, dan.j.williams
Moving ASM_CLAC to interrupt_entry means two instructions (addq / pushq
and call interrupt_entry) are not covered by it. However, it offers a
noticeable size reduction (-.2k):
text data bss dec hex filename
16882 0 0 16882 41f2 entry_64.o-orig
16623 0 0 16623 40ef entry_64.o
Suggested-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
arch/x86/entry/entry_64.S | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 8ea03cf94a2d..42a4b652469d 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -572,6 +572,7 @@ END(irq_entries_start)
/* 8(%rsp): ~(interrupt number) */
ENTRY(interrupt_entry)
UNWIND_HINT_FUNC
+ ASM_CLAC
cld
testb $3, CS-ORIG_RAX+8(%rsp)
@@ -614,7 +615,6 @@ END(interrupt_entry)
*/
.p2align CONFIG_X86_L1_CACHE_SHIFT
common_interrupt:
- ASM_CLAC
addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */
call interrupt_entry
UNWIND_HINT_REGS indirect=1
@@ -811,7 +811,6 @@ END(common_interrupt)
.macro apicinterrupt3 num sym do_sym
ENTRY(\sym)
UNWIND_HINT_IRET_REGS
- ASM_CLAC
pushq $~(\num)
.Lcommon_\sym:
call interrupt_entry
--
2.16.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move ASM_CLAC to interrupt_entry()
2018-02-20 21:01 ` [RFC PATCH v3 5/6] x86/entry/64: move ASM_CLAC to interrupt_entry Dominik Brodowski
@ 2018-02-21 10:47 ` tip-bot for Dominik Brodowski
2018-02-21 17:00 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 10:47 UTC (permalink / raw)
To: linux-tip-commits
Cc: luto, brgerst, hpa, linux-kernel, bp, peterz, linux, dwmw2,
torvalds, dvlasenk, mingo, tglx, jpoimboe
Commit-ID: a2bb5db1193effd900216a62a6d03d177c26ab02
Gitweb: https://git.kernel.org/tip/a2bb5db1193effd900216a62a6d03d177c26ab02
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:12 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 10:04:47 +0100
x86/entry/64: Move ASM_CLAC to interrupt_entry()
Moving ASM_CLAC to interrupt_entry means two instructions (addq / pushq
and call interrupt_entry) are not covered by it. However, it offers a
noticeable size reduction (-.2k):
text data bss dec hex filename
16882 0 0 16882 41f2 entry_64.o-orig
16623 0 0 16623 40ef entry_64.o
Suggested-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-6-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 8ea03cf..42a4b65 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -572,6 +572,7 @@ END(irq_entries_start)
/* 8(%rsp): ~(interrupt number) */
ENTRY(interrupt_entry)
UNWIND_HINT_FUNC
+ ASM_CLAC
cld
testb $3, CS-ORIG_RAX+8(%rsp)
@@ -614,7 +615,6 @@ END(interrupt_entry)
*/
.p2align CONFIG_X86_L1_CACHE_SHIFT
common_interrupt:
- ASM_CLAC
addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */
call interrupt_entry
UNWIND_HINT_REGS indirect=1
@@ -811,7 +811,6 @@ END(common_interrupt)
.macro apicinterrupt3 num sym do_sym
ENTRY(\sym)
UNWIND_HINT_IRET_REGS
- ASM_CLAC
pushq $~(\num)
.Lcommon_\sym:
call interrupt_entry
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Move ASM_CLAC to interrupt_entry()
2018-02-20 21:01 ` [RFC PATCH v3 5/6] x86/entry/64: move ASM_CLAC to interrupt_entry Dominik Brodowski
2018-02-21 10:47 ` [tip:x86/pti] x86/entry/64: Move ASM_CLAC to interrupt_entry() tip-bot for Dominik Brodowski
@ 2018-02-21 17:00 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 17:00 UTC (permalink / raw)
To: linux-tip-commits
Cc: bp, tglx, luto, jpoimboe, brgerst, peterz, linux, linux-kernel,
mingo, dvlasenk, torvalds, dwmw2, hpa
Commit-ID: b2855d8d2de0fa15c1ff30c69ed7756b00c48b22
Gitweb: https://git.kernel.org/tip/b2855d8d2de0fa15c1ff30c69ed7756b00c48b22
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:12 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 16:54:05 +0100
x86/entry/64: Move ASM_CLAC to interrupt_entry()
Moving ASM_CLAC to interrupt_entry means two instructions (addq / pushq
and call interrupt_entry) are not covered by it. However, it offers a
noticeable size reduction (-.2k):
text data bss dec hex filename
16882 0 0 16882 41f2 entry_64.o-orig
16623 0 0 16623 40ef entry_64.o
Suggested-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-6-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 8ea03cf..42a4b65 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -572,6 +572,7 @@ END(irq_entries_start)
/* 8(%rsp): ~(interrupt number) */
ENTRY(interrupt_entry)
UNWIND_HINT_FUNC
+ ASM_CLAC
cld
testb $3, CS-ORIG_RAX+8(%rsp)
@@ -614,7 +615,6 @@ END(interrupt_entry)
*/
.p2align CONFIG_X86_L1_CACHE_SHIFT
common_interrupt:
- ASM_CLAC
addq $-0x80, (%rsp) /* Adjust vector to [-256, -1] range */
call interrupt_entry
UNWIND_HINT_REGS indirect=1
@@ -811,7 +811,6 @@ END(common_interrupt)
.macro apicinterrupt3 num sym do_sym
ENTRY(\sym)
UNWIND_HINT_IRET_REGS
- ASM_CLAC
pushq $~(\num)
.Lcommon_\sym:
call interrupt_entry
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [RFC PATCH v3 6/6] x86/entry/64: open-code switch_to_thread_stack
2018-02-20 21:01 [RFC PATCH v3 0/6] x86/entry/64: interrupt entry size reduction Dominik Brodowski
` (4 preceding siblings ...)
2018-02-20 21:01 ` [RFC PATCH v3 5/6] x86/entry/64: move ASM_CLAC to interrupt_entry Dominik Brodowski
@ 2018-02-20 21:01 ` Dominik Brodowski
2018-02-21 10:48 ` [tip:x86/pti] x86/entry/64: Open-code switch_to_thread_stack() tip-bot for Dominik Brodowski
2018-02-21 17:01 ` tip-bot for Dominik Brodowski
5 siblings, 2 replies; 23+ messages in thread
From: Dominik Brodowski @ 2018-02-20 21:01 UTC (permalink / raw)
To: linux-kernel, mingo, x86, brgerst, luto, jpoimboe
Cc: torvalds, ak, tglx, dan.j.williams
Open-code the two instances which used switch_to_thread_stack. This
allows us to remove the wrapper around DO_SWITCH_TO_THREAD_STACK.
While at it, update the UNWIND hint to reflect where the IRET frame is,
and update the commentary to reflect what we are actually doing here.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
---
arch/x86/entry/entry_64.S | 76 +++++++++++++++++++++-------------------
arch/x86/entry/entry_64_compat.S | 17 +++++++--
2 files changed, 55 insertions(+), 38 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 42a4b652469d..d5c7f18f79ac 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -538,17 +538,48 @@ END(irq_entries_start)
.endm
/*
- * Switch to the thread stack. This is called with the IRET frame and
- * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
- * space has not been allocated for them.)
+ * Interrupt entry helper function.
+ *
+ * Entry runs with interrupts off. Stack layout at entry:
+ * +----------------------------------------------------+
+ * | regs->ss |
+ * | regs->rsp |
+ * | regs->eflags |
+ * | regs->cs |
+ * | regs->ip |
+ * +----------------------------------------------------+
+ * | regs->orig_ax = ~(interrupt number) |
+ * +----------------------------------------------------+
+ * | return address |
+ * +----------------------------------------------------+
*/
-.macro DO_SWITCH_TO_THREAD_STACK
+ENTRY(interrupt_entry)
+ UNWIND_HINT_FUNC
+ ASM_CLAC
+ cld
+
+ testb $3, CS-ORIG_RAX+8(%rsp)
+ jz 1f
+ SWAPGS
+
+ /*
+ * Switch to the thread stack. The IRET frame and orig_ax are
+ * on the stack, as well as the return address. RDI..R12 are
+ * not (yet) on the stack and space has not (yet) been
+ * allocated for them.
+ */
pushq %rdi
+
/* Need to switch before accessing the thread stack. */
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
movq %rsp, %rdi
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
+
+ /*
+ * We have RDI, return address, and orig_ax on the stack on
+ * top of the IRET frame. That means offset=24
+ */
+ UNWIND_HINT_IRET_REGS base=%rdi offset=24
pushq 7*8(%rdi) /* regs->ss */
pushq 6*8(%rdi) /* regs->rsp */
@@ -560,25 +591,6 @@ END(irq_entries_start)
UNWIND_HINT_FUNC
movq (%rdi), %rdi
-.endm
-
-/*
- * Interrupt entry/exit.
- *
- * Interrupt entry points save only callee clobbered registers in fast path.
- *
- * Entry runs with interrupts off.
- */
-/* 8(%rsp): ~(interrupt number) */
-ENTRY(interrupt_entry)
- UNWIND_HINT_FUNC
- ASM_CLAC
- cld
-
- testb $3, CS-ORIG_RAX+8(%rsp)
- jz 1f
- SWAPGS
- DO_SWITCH_TO_THREAD_STACK
1:
PUSH_AND_CLEAR_REGS save_ret=1
@@ -592,7 +604,7 @@ ENTRY(interrupt_entry)
*
* We need to tell lockdep that IRQs are off. We can't do this until
* we fix gsbase, and we should do it before enter_from_user_mode
- * (which can take locks). Since TRACE_IRQS_OFF idempotent,
+ * (which can take locks). Since TRACE_IRQS_OFF is idempotent,
* the simplest way to handle it is to just call it twice if
* we enter from user mode. There's no reason to optimize this since
* TRACE_IRQS_OFF is a no-op if lockdep is off.
@@ -609,6 +621,9 @@ ENTRY(interrupt_entry)
ret
END(interrupt_entry)
+
+/* Interrupt entry/exit. */
+
/*
* The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt.
@@ -878,17 +893,6 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
*/
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
-#if defined(CONFIG_IA32_EMULATION)
-/* entry_64_compat.S::entry_INT80_compat expects this to be an ASM function */
-ENTRY(switch_to_thread_stack)
- UNWIND_HINT_FUNC
-
- DO_SWITCH_TO_THREAD_STACK
-
- ret
-END(switch_to_thread_stack)
-#endif
-
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
ENTRY(\sym)
UNWIND_HINT_IRET_REGS offset=\has_error_code*8
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 364ea4a207be..e811dd9c5e99 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -347,10 +347,23 @@ ENTRY(entry_INT80_compat)
*/
movl %eax, %eax
+ /* switch to thread stack expects orig_ax and rdi to be pushed */
pushq %rax /* pt_regs->orig_ax */
+ pushq %rdi /* pt_regs->di */
+
+ /* Need to switch before accessing the thread stack. */
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+ movq %rsp, %rdi
+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+
+ pushq 6*8(%rdi) /* regs->ss */
+ pushq 5*8(%rdi) /* regs->rsp */
+ pushq 4*8(%rdi) /* regs->eflags */
+ pushq 3*8(%rdi) /* regs->cs */
+ pushq 2*8(%rdi) /* regs->ip */
+ pushq 1*8(%rdi) /* regs->orig_ax */
- /* switch to thread stack expects orig_ax to be pushed */
- call switch_to_thread_stack
+ movq (%rdi), %rdi /* restore %rdi */
pushq %rdi /* pt_regs->di */
pushq %rsi /* pt_regs->si */
--
2.16.2
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Open-code switch_to_thread_stack()
2018-02-20 21:01 ` [RFC PATCH v3 6/6] x86/entry/64: open-code switch_to_thread_stack Dominik Brodowski
@ 2018-02-21 10:48 ` tip-bot for Dominik Brodowski
2018-02-21 17:01 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 10:48 UTC (permalink / raw)
To: linux-tip-commits
Cc: luto, linux, mingo, bp, linux-kernel, jpoimboe, hpa, tglx, dwmw2,
torvalds, brgerst, peterz, dvlasenk
Commit-ID: 179efbb14ced86ce0ec6495b85fa971aa3466be3
Gitweb: https://git.kernel.org/tip/179efbb14ced86ce0ec6495b85fa971aa3466be3
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:13 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 10:04:47 +0100
x86/entry/64: Open-code switch_to_thread_stack()
Open-code the two instances which called switch_to_thread_stack(). This
allows us to remove the wrapper around DO_SWITCH_TO_THREAD_STACK.
While at it, update the UNWIND hint to reflect where the IRET frame is,
and update the commentary to reflect what we are actually doing here.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-7-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 76 +++++++++++++++++++++-------------------
arch/x86/entry/entry_64_compat.S | 17 +++++++--
2 files changed, 55 insertions(+), 38 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 42a4b65..d5c7f18 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -538,17 +538,48 @@ END(irq_entries_start)
.endm
/*
- * Switch to the thread stack. This is called with the IRET frame and
- * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
- * space has not been allocated for them.)
+ * Interrupt entry helper function.
+ *
+ * Entry runs with interrupts off. Stack layout at entry:
+ * +----------------------------------------------------+
+ * | regs->ss |
+ * | regs->rsp |
+ * | regs->eflags |
+ * | regs->cs |
+ * | regs->ip |
+ * +----------------------------------------------------+
+ * | regs->orig_ax = ~(interrupt number) |
+ * +----------------------------------------------------+
+ * | return address |
+ * +----------------------------------------------------+
*/
-.macro DO_SWITCH_TO_THREAD_STACK
+ENTRY(interrupt_entry)
+ UNWIND_HINT_FUNC
+ ASM_CLAC
+ cld
+
+ testb $3, CS-ORIG_RAX+8(%rsp)
+ jz 1f
+ SWAPGS
+
+ /*
+ * Switch to the thread stack. The IRET frame and orig_ax are
+ * on the stack, as well as the return address. RDI..R12 are
+ * not (yet) on the stack and space has not (yet) been
+ * allocated for them.
+ */
pushq %rdi
+
/* Need to switch before accessing the thread stack. */
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
movq %rsp, %rdi
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
+
+ /*
+ * We have RDI, return address, and orig_ax on the stack on
+ * top of the IRET frame. That means offset=24
+ */
+ UNWIND_HINT_IRET_REGS base=%rdi offset=24
pushq 7*8(%rdi) /* regs->ss */
pushq 6*8(%rdi) /* regs->rsp */
@@ -560,25 +591,6 @@ END(irq_entries_start)
UNWIND_HINT_FUNC
movq (%rdi), %rdi
-.endm
-
-/*
- * Interrupt entry/exit.
- *
- * Interrupt entry points save only callee clobbered registers in fast path.
- *
- * Entry runs with interrupts off.
- */
-/* 8(%rsp): ~(interrupt number) */
-ENTRY(interrupt_entry)
- UNWIND_HINT_FUNC
- ASM_CLAC
- cld
-
- testb $3, CS-ORIG_RAX+8(%rsp)
- jz 1f
- SWAPGS
- DO_SWITCH_TO_THREAD_STACK
1:
PUSH_AND_CLEAR_REGS save_ret=1
@@ -592,7 +604,7 @@ ENTRY(interrupt_entry)
*
* We need to tell lockdep that IRQs are off. We can't do this until
* we fix gsbase, and we should do it before enter_from_user_mode
- * (which can take locks). Since TRACE_IRQS_OFF idempotent,
+ * (which can take locks). Since TRACE_IRQS_OFF is idempotent,
* the simplest way to handle it is to just call it twice if
* we enter from user mode. There's no reason to optimize this since
* TRACE_IRQS_OFF is a no-op if lockdep is off.
@@ -609,6 +621,9 @@ ENTRY(interrupt_entry)
ret
END(interrupt_entry)
+
+/* Interrupt entry/exit. */
+
/*
* The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt.
@@ -878,17 +893,6 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
*/
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
-#if defined(CONFIG_IA32_EMULATION)
-/* entry_64_compat.S::entry_INT80_compat expects this to be an ASM function */
-ENTRY(switch_to_thread_stack)
- UNWIND_HINT_FUNC
-
- DO_SWITCH_TO_THREAD_STACK
-
- ret
-END(switch_to_thread_stack)
-#endif
-
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
ENTRY(\sym)
UNWIND_HINT_IRET_REGS offset=\has_error_code*8
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 364ea4a..e811dd9 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -347,10 +347,23 @@ ENTRY(entry_INT80_compat)
*/
movl %eax, %eax
+ /* switch to thread stack expects orig_ax and rdi to be pushed */
pushq %rax /* pt_regs->orig_ax */
+ pushq %rdi /* pt_regs->di */
+
+ /* Need to switch before accessing the thread stack. */
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+ movq %rsp, %rdi
+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+
+ pushq 6*8(%rdi) /* regs->ss */
+ pushq 5*8(%rdi) /* regs->rsp */
+ pushq 4*8(%rdi) /* regs->eflags */
+ pushq 3*8(%rdi) /* regs->cs */
+ pushq 2*8(%rdi) /* regs->ip */
+ pushq 1*8(%rdi) /* regs->orig_ax */
- /* switch to thread stack expects orig_ax to be pushed */
- call switch_to_thread_stack
+ movq (%rdi), %rdi /* restore %rdi */
pushq %rdi /* pt_regs->di */
pushq %rsi /* pt_regs->si */
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [tip:x86/pti] x86/entry/64: Open-code switch_to_thread_stack()
2018-02-20 21:01 ` [RFC PATCH v3 6/6] x86/entry/64: open-code switch_to_thread_stack Dominik Brodowski
2018-02-21 10:48 ` [tip:x86/pti] x86/entry/64: Open-code switch_to_thread_stack() tip-bot for Dominik Brodowski
@ 2018-02-21 17:01 ` tip-bot for Dominik Brodowski
1 sibling, 0 replies; 23+ messages in thread
From: tip-bot for Dominik Brodowski @ 2018-02-21 17:01 UTC (permalink / raw)
To: linux-tip-commits
Cc: bp, hpa, mingo, jpoimboe, torvalds, dwmw2, brgerst, linux-kernel,
peterz, dvlasenk, linux, tglx, luto
Commit-ID: f3d415ea46968ae1f9cbb9e201601d7207ce74c7
Gitweb: https://git.kernel.org/tip/f3d415ea46968ae1f9cbb9e201601d7207ce74c7
Author: Dominik Brodowski <linux@dominikbrodowski.net>
AuthorDate: Tue, 20 Feb 2018 22:01:13 +0100
Committer: Ingo Molnar <mingo@kernel.org>
CommitDate: Wed, 21 Feb 2018 16:54:05 +0100
x86/entry/64: Open-code switch_to_thread_stack()
Open-code the two instances which called switch_to_thread_stack(). This
allows us to remove the wrapper around DO_SWITCH_TO_THREAD_STACK.
While at it, update the UNWIND hint to reflect where the IRET frame is,
and update the commentary to reflect what we are actually doing here.
Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: dan.j.williams@intel.com
Link: http://lkml.kernel.org/r/20180220210113.6725-7-linux@dominikbrodowski.net
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
arch/x86/entry/entry_64.S | 76 +++++++++++++++++++++-------------------
arch/x86/entry/entry_64_compat.S | 17 +++++++--
2 files changed, 55 insertions(+), 38 deletions(-)
diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
index 42a4b65..d5c7f18 100644
--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -538,17 +538,48 @@ END(irq_entries_start)
.endm
/*
- * Switch to the thread stack. This is called with the IRET frame and
- * orig_ax on the stack. (That is, RDI..R12 are not on the stack and
- * space has not been allocated for them.)
+ * Interrupt entry helper function.
+ *
+ * Entry runs with interrupts off. Stack layout at entry:
+ * +----------------------------------------------------+
+ * | regs->ss |
+ * | regs->rsp |
+ * | regs->eflags |
+ * | regs->cs |
+ * | regs->ip |
+ * +----------------------------------------------------+
+ * | regs->orig_ax = ~(interrupt number) |
+ * +----------------------------------------------------+
+ * | return address |
+ * +----------------------------------------------------+
*/
-.macro DO_SWITCH_TO_THREAD_STACK
+ENTRY(interrupt_entry)
+ UNWIND_HINT_FUNC
+ ASM_CLAC
+ cld
+
+ testb $3, CS-ORIG_RAX+8(%rsp)
+ jz 1f
+ SWAPGS
+
+ /*
+ * Switch to the thread stack. The IRET frame and orig_ax are
+ * on the stack, as well as the return address. RDI..R12 are
+ * not (yet) on the stack and space has not (yet) been
+ * allocated for them.
+ */
pushq %rdi
+
/* Need to switch before accessing the thread stack. */
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
movq %rsp, %rdi
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
- UNWIND_HINT sp_offset=16 sp_reg=ORC_REG_DI
+
+ /*
+ * We have RDI, return address, and orig_ax on the stack on
+ * top of the IRET frame. That means offset=24
+ */
+ UNWIND_HINT_IRET_REGS base=%rdi offset=24
pushq 7*8(%rdi) /* regs->ss */
pushq 6*8(%rdi) /* regs->rsp */
@@ -560,25 +591,6 @@ END(irq_entries_start)
UNWIND_HINT_FUNC
movq (%rdi), %rdi
-.endm
-
-/*
- * Interrupt entry/exit.
- *
- * Interrupt entry points save only callee clobbered registers in fast path.
- *
- * Entry runs with interrupts off.
- */
-/* 8(%rsp): ~(interrupt number) */
-ENTRY(interrupt_entry)
- UNWIND_HINT_FUNC
- ASM_CLAC
- cld
-
- testb $3, CS-ORIG_RAX+8(%rsp)
- jz 1f
- SWAPGS
- DO_SWITCH_TO_THREAD_STACK
1:
PUSH_AND_CLEAR_REGS save_ret=1
@@ -592,7 +604,7 @@ ENTRY(interrupt_entry)
*
* We need to tell lockdep that IRQs are off. We can't do this until
* we fix gsbase, and we should do it before enter_from_user_mode
- * (which can take locks). Since TRACE_IRQS_OFF idempotent,
+ * (which can take locks). Since TRACE_IRQS_OFF is idempotent,
* the simplest way to handle it is to just call it twice if
* we enter from user mode. There's no reason to optimize this since
* TRACE_IRQS_OFF is a no-op if lockdep is off.
@@ -609,6 +621,9 @@ ENTRY(interrupt_entry)
ret
END(interrupt_entry)
+
+/* Interrupt entry/exit. */
+
/*
* The interrupt stubs push (~vector+0x80) onto the stack and
* then jump to common_interrupt.
@@ -878,17 +893,6 @@ apicinterrupt IRQ_WORK_VECTOR irq_work_interrupt smp_irq_work_interrupt
*/
#define CPU_TSS_IST(x) PER_CPU_VAR(cpu_tss_rw) + (TSS_ist + ((x) - 1) * 8)
-#if defined(CONFIG_IA32_EMULATION)
-/* entry_64_compat.S::entry_INT80_compat expects this to be an ASM function */
-ENTRY(switch_to_thread_stack)
- UNWIND_HINT_FUNC
-
- DO_SWITCH_TO_THREAD_STACK
-
- ret
-END(switch_to_thread_stack)
-#endif
-
.macro idtentry sym do_sym has_error_code:req paranoid=0 shift_ist=-1
ENTRY(\sym)
UNWIND_HINT_IRET_REGS offset=\has_error_code*8
diff --git a/arch/x86/entry/entry_64_compat.S b/arch/x86/entry/entry_64_compat.S
index 364ea4a..e811dd9 100644
--- a/arch/x86/entry/entry_64_compat.S
+++ b/arch/x86/entry/entry_64_compat.S
@@ -347,10 +347,23 @@ ENTRY(entry_INT80_compat)
*/
movl %eax, %eax
+ /* switch to thread stack expects orig_ax and rdi to be pushed */
pushq %rax /* pt_regs->orig_ax */
+ pushq %rdi /* pt_regs->di */
+
+ /* Need to switch before accessing the thread stack. */
+ SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
+ movq %rsp, %rdi
+ movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
+
+ pushq 6*8(%rdi) /* regs->ss */
+ pushq 5*8(%rdi) /* regs->rsp */
+ pushq 4*8(%rdi) /* regs->eflags */
+ pushq 3*8(%rdi) /* regs->cs */
+ pushq 2*8(%rdi) /* regs->ip */
+ pushq 1*8(%rdi) /* regs->orig_ax */
- /* switch to thread stack expects orig_ax to be pushed */
- call switch_to_thread_stack
+ movq (%rdi), %rdi /* restore %rdi */
pushq %rdi /* pt_regs->di */
pushq %rsi /* pt_regs->si */
^ permalink raw reply related [flat|nested] 23+ messages in thread