Skip to content

Commit a798f09

Browse files
amlutoIngo Molnar
authored andcommitted
x86/entry/32: Change INT80 to be an interrupt gate
We want all of the syscall entries to run with interrupts off so that we can efficiently run context tracking before enabling interrupts. This will regress int $0x80 performance on 32-bit kernels by a couple of cycles. This shouldn't matter much -- int $0x80 is not a fast path. This effectively reverts: 657c1ee ("x86/entry/32: Fix entry_INT80_32() to expect interrupts to be on") ... and fixes the same issue differently. Signed-off-by: Andy Lutomirski <luto@kernel.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@redhat.com> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/59b4f90c9ebfccd8c937305dbbbca680bc74b905.1457558566.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
1 parent fda57b2 commit a798f09

File tree

4 files changed

+9
-18
lines changed

4 files changed

+9
-18
lines changed

arch/x86/entry/common.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -371,14 +371,7 @@ __visible void do_syscall_64(struct pt_regs *regs)
371371
* in workloads that use it, and it's usually called from
372372
* do_fast_syscall_32, so forcibly inline it to improve performance.
373373
*/
374-
#ifdef CONFIG_X86_32
375-
/* 32-bit kernels use a trap gate for INT80, and the asm code calls here. */
376-
__visible
377-
#else
378-
/* 64-bit kernels use do_syscall_32_irqs_off() instead. */
379-
static
380-
#endif
381-
__always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
374+
static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
382375
{
383376
struct thread_info *ti = pt_regs_to_thread_info(regs);
384377
unsigned int nr = (unsigned int)regs->orig_ax;
@@ -413,14 +406,12 @@ __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
413406
syscall_return_slowpath(regs);
414407
}
415408

416-
#ifdef CONFIG_X86_64
417-
/* Handles INT80 on 64-bit kernels */
418-
__visible void do_syscall_32_irqs_off(struct pt_regs *regs)
409+
/* Handles int $0x80 */
410+
__visible void do_int80_syscall_32(struct pt_regs *regs)
419411
{
420412
local_irq_enable();
421413
do_syscall_32_irqs_on(regs);
422414
}
423-
#endif
424415

425416
/* Returns 0 to return using IRET or 1 to return using SYSEXIT/SYSRETL. */
426417
__visible long do_fast_syscall_32(struct pt_regs *regs)

arch/x86/entry/entry_32.S

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -463,13 +463,13 @@ ENTRY(entry_INT80_32)
463463
SAVE_ALL pt_regs_ax=$-ENOSYS /* save rest */
464464

465465
/*
466-
* User mode is traced as though IRQs are on. Unlike the 64-bit
467-
* case, INT80 is a trap gate on 32-bit kernels, so interrupts
468-
* are already on (unless user code is messing around with iopl).
466+
* User mode is traced as though IRQs are on, and the interrupt gate
467+
* turned them off.
469468
*/
469+
TRACE_IRQS_OFF
470470

471471
movl %esp, %eax
472-
call do_syscall_32_irqs_on
472+
call do_int80_syscall_32
473473
.Lsyscall_32_done:
474474

475475
restore_all:

arch/x86/entry/entry_64_compat.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ ENTRY(entry_INT80_compat)
336336
TRACE_IRQS_OFF
337337

338338
movq %rsp, %rdi
339-
call do_syscall_32_irqs_off
339+
call do_int80_syscall_32
340340
.Lsyscall_32_done:
341341

342342
/* Go back to user mode. */

arch/x86/kernel/traps.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -912,7 +912,7 @@ void __init trap_init(void)
912912
#endif
913913

914914
#ifdef CONFIG_X86_32
915-
set_system_trap_gate(IA32_SYSCALL_VECTOR, entry_INT80_32);
915+
set_system_intr_gate(IA32_SYSCALL_VECTOR, entry_INT80_32);
916916
set_bit(IA32_SYSCALL_VECTOR, used_vectors);
917917
#endif
918918

0 commit comments

Comments
 (0)