Skip to content

Commit ff16701

Browse files
committed
x86/process: Consolidate and simplify switch_to_xtra() code
Move the conditional invocation of __switch_to_xtra() into an inline function so the logic can be shared between 32 and 64 bit. Remove the handthrough of the TSS pointer and retrieve the pointer directly in the bitmap handling function. Use this_cpu_ptr() instead of the per_cpu() indirection. This is a preparatory change so integration of conditional indirect branch speculation optimization happens only in one place. Signed-off-by: Thomas Gleixner <[email protected]> Reviewed-by: Ingo Molnar <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Jiri Kosina <[email protected]> Cc: Tom Lendacky <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Andrea Arcangeli <[email protected]> Cc: David Woodhouse <[email protected]> Cc: Tim Chen <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Casey Schaufler <[email protected]> Cc: Asit Mallick <[email protected]> Cc: Arjan van de Ven <[email protected]> Cc: Jon Masters <[email protected]> Cc: Waiman Long <[email protected]> Cc: Greg KH <[email protected]> Cc: Dave Stewart <[email protected]> Cc: Kees Cook <[email protected]> Cc: [email protected] Link: https://lkml.kernel.org/r/[email protected]
1 parent 5bfbe3a commit ff16701

File tree

5 files changed

+37
-22
lines changed

5 files changed

+37
-22
lines changed

arch/x86/include/asm/switch_to.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ struct task_struct *__switch_to_asm(struct task_struct *prev,
1111

1212
__visible struct task_struct *__switch_to(struct task_struct *prev,
1313
struct task_struct *next);
14-
struct tss_struct;
15-
void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
16-
struct tss_struct *tss);
1714

1815
/* This runs runs on the previous thread's stack. */
1916
static inline void prepare_switch_to(struct task_struct *next)

arch/x86/kernel/process.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
#include <asm/prctl.h>
4141
#include <asm/spec-ctrl.h>
4242

43+
#include "process.h"
44+
4345
/*
4446
* per-CPU TSS segments. Threads are completely 'soft' on Linux,
4547
* no more per-task TSS's. The TSS size is kept cacheline-aligned
@@ -252,11 +254,12 @@ void arch_setup_new_exec(void)
252254
enable_cpuid();
253255
}
254256

255-
static inline void switch_to_bitmap(struct tss_struct *tss,
256-
struct thread_struct *prev,
257+
static inline void switch_to_bitmap(struct thread_struct *prev,
257258
struct thread_struct *next,
258259
unsigned long tifp, unsigned long tifn)
259260
{
261+
struct tss_struct *tss = this_cpu_ptr(&cpu_tss_rw);
262+
260263
if (tifn & _TIF_IO_BITMAP) {
261264
/*
262265
* Copy the relevant range of the IO bitmap.
@@ -448,8 +451,7 @@ void speculation_ctrl_update(unsigned long tif)
448451
preempt_enable();
449452
}
450453

451-
void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
452-
struct tss_struct *tss)
454+
void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p)
453455
{
454456
struct thread_struct *prev, *next;
455457
unsigned long tifp, tifn;
@@ -459,7 +461,7 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
459461

460462
tifn = READ_ONCE(task_thread_info(next_p)->flags);
461463
tifp = READ_ONCE(task_thread_info(prev_p)->flags);
462-
switch_to_bitmap(tss, prev, next, tifp, tifn);
464+
switch_to_bitmap(prev, next, tifp, tifn);
463465

464466
propagate_user_return_notify(prev_p, next_p);
465467

arch/x86/kernel/process.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
//
3+
// Code shared between 32 and 64 bit
4+
5+
void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p);
6+
7+
/*
8+
* This needs to be inline to optimize for the common case where no extra
9+
* work needs to be done.
10+
*/
11+
static inline void switch_to_extra(struct task_struct *prev,
12+
struct task_struct *next)
13+
{
14+
unsigned long next_tif = task_thread_info(next)->flags;
15+
unsigned long prev_tif = task_thread_info(prev)->flags;
16+
17+
/*
18+
* __switch_to_xtra() handles debug registers, i/o bitmaps,
19+
* speculation mitigations etc.
20+
*/
21+
if (unlikely(next_tif & _TIF_WORK_CTXSW_NEXT ||
22+
prev_tif & _TIF_WORK_CTXSW_PREV))
23+
__switch_to_xtra(prev, next);
24+
}

arch/x86/kernel/process_32.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@
5959
#include <asm/intel_rdt_sched.h>
6060
#include <asm/proto.h>
6161

62+
#include "process.h"
63+
6264
void __show_regs(struct pt_regs *regs, enum show_regs_mode mode)
6365
{
6466
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
@@ -232,7 +234,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
232234
struct fpu *prev_fpu = &prev->fpu;
233235
struct fpu *next_fpu = &next->fpu;
234236
int cpu = smp_processor_id();
235-
struct tss_struct *tss = &per_cpu(cpu_tss_rw, cpu);
236237

237238
/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
238239

@@ -264,12 +265,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
264265
if (get_kernel_rpl() && unlikely(prev->iopl != next->iopl))
265266
set_iopl_mask(next->iopl);
266267

267-
/*
268-
* Now maybe handle debug registers and/or IO bitmaps
269-
*/
270-
if (unlikely(task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV ||
271-
task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))
272-
__switch_to_xtra(prev_p, next_p, tss);
268+
switch_to_extra(prev_p, next_p);
273269

274270
/*
275271
* Leave lazy mode, flushing any hypercalls made here.

arch/x86/kernel/process_64.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
#include <asm/unistd_32_ia32.h>
6161
#endif
6262

63+
#include "process.h"
64+
6365
/* Prints also some state that isn't saved in the pt_regs */
6466
void __show_regs(struct pt_regs *regs, enum show_regs_mode mode)
6567
{
@@ -553,7 +555,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
553555
struct fpu *prev_fpu = &prev->fpu;
554556
struct fpu *next_fpu = &next->fpu;
555557
int cpu = smp_processor_id();
556-
struct tss_struct *tss = &per_cpu(cpu_tss_rw, cpu);
557558

558559
WARN_ON_ONCE(IS_ENABLED(CONFIG_DEBUG_ENTRY) &&
559560
this_cpu_read(irq_count) != -1);
@@ -617,12 +618,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
617618
/* Reload sp0. */
618619
update_task_stack(next_p);
619620

620-
/*
621-
* Now maybe reload the debug registers and handle I/O bitmaps
622-
*/
623-
if (unlikely(task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT ||
624-
task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
625-
__switch_to_xtra(prev_p, next_p, tss);
621+
switch_to_extra(prev_p, next_p);
626622

627623
#ifdef CONFIG_XEN_PV
628624
/*

0 commit comments

Comments
 (0)