Commit 60400677 authored by Thomas Gleixner's avatar Thomas Gleixner

x86/entry/32: Provide macro to emit IDT entry stubs

32 and 64 bit have unnecessary different ways to populate the exception
entry code. Provide a idtentry macro which allows to consolidate all of
that.
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
Reviewed-by: default avatarAlexandre Chartre <alexandre.chartre@oracle.com>
Acked-by: default avatarAndy Lutomirski <luto@kernel.org>
Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
Link: https://lkml.kernel.org/r/20200505134904.166735365@linutronix.de


parent 424c7d0a
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include <asm/asm.h> #include <asm/asm.h>
#include <asm/smap.h> #include <asm/smap.h>
#include <asm/frame.h> #include <asm/frame.h>
#include <asm/trapnr.h>
#include <asm/nospec-branch.h> #include <asm/nospec-branch.h>
#include "calling.h" #include "calling.h"
...@@ -726,6 +727,31 @@ ...@@ -726,6 +727,31 @@
.Lend_\@: .Lend_\@:
.endm .endm
/**
* idtentry - Macro to generate entry stubs for simple IDT entries
* @vector: Vector number
* @asmsym: ASM symbol for the entry point
* @cfunc: C function to be called
* @has_error_code: Hardware pushed error code on stack
* @sane: Compatibility flag with 64bit
*/
.macro idtentry vector asmsym cfunc has_error_code:req sane=0
SYM_CODE_START(\asmsym)
ASM_CLAC
cld
.if \has_error_code == 0
pushl $0 /* Clear the error code */
.endif
/* Push the C-function address into the GS slot */
pushl $\cfunc
/* Invoke the common exception entry */
jmp handle_exception
SYM_CODE_END(\asmsym)
.endm
/* /*
* %eax: prev task * %eax: prev task
* %edx: next task * %edx: next task
...@@ -1517,6 +1543,48 @@ SYM_CODE_START_LOCAL_NOALIGN(common_exception) ...@@ -1517,6 +1543,48 @@ SYM_CODE_START_LOCAL_NOALIGN(common_exception)
jmp ret_from_exception jmp ret_from_exception
SYM_CODE_END(common_exception) SYM_CODE_END(common_exception)
SYM_CODE_START_LOCAL_NOALIGN(handle_exception)
/* the function address is in %gs's slot on the stack */
SAVE_ALL switch_stacks=1 skip_gs=1 unwind_espfix=1
ENCODE_FRAME_POINTER
/* fixup %gs */
GS_TO_REG %ecx
movl PT_GS(%esp), %edi # get the function address
REG_TO_PTGS %ecx
SET_KERNEL_GS %ecx
/* fixup orig %eax */
movl PT_ORIG_EAX(%esp), %edx # get the error code
movl $-1, PT_ORIG_EAX(%esp) # no syscall to restart
movl %esp, %eax # pt_regs pointer
CALL_NOSPEC edi
#ifdef CONFIG_VM86
movl PT_EFLAGS(%esp), %eax # mix EFLAGS and CS
movb PT_CS(%esp), %al
andl $(X86_EFLAGS_VM | SEGMENT_RPL_MASK), %eax
#else
/*
* We can be coming here from child spawned by kernel_thread().
*/
movl PT_CS(%esp), %eax
andl $SEGMENT_RPL_MASK, %eax
#endif
cmpl $USER_RPL, %eax # returning to v8086 or userspace ?
jnb ret_to_user
PARANOID_EXIT_TO_KERNEL_MODE
BUG_IF_WRONG_CR3
RESTORE_REGS 4
jmp .Lirq_return
ret_to_user:
movl %esp, %eax
jmp restore_all_switch_stack
SYM_CODE_END(handle_exception)
SYM_CODE_START(debug) SYM_CODE_START(debug)
/* /*
* Entry from sysenter is now handled in common_exception * Entry from sysenter is now handled in common_exception
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment