|
@@ -151,6 +151,16 @@ ENTRY(ia32_sysenter_target)
|
|
|
1: movl (%rbp),%ebp
|
|
|
_ASM_EXTABLE(1b,ia32_badarg)
|
|
|
ASM_CLAC
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Sysenter doesn't filter flags, so we need to clear NT
|
|
|
+ * ourselves. To save a few cycles, we can check whether
|
|
|
+ * NT was set instead of doing an unconditional popfq.
|
|
|
+ */
|
|
|
+ testl $X86_EFLAGS_NT,EFLAGS(%rsp) /* saved EFLAGS match cpu */
|
|
|
+ jnz sysenter_fix_flags
|
|
|
+sysenter_flags_fixed:
|
|
|
+
|
|
|
orl $TS_COMPAT,TI_status+THREAD_INFO(%rsp,RIP-ARGOFFSET)
|
|
|
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
|
|
|
CFI_REMEMBER_STATE
|
|
@@ -184,6 +194,8 @@ sysexit_from_sys_call:
|
|
|
TRACE_IRQS_ON
|
|
|
ENABLE_INTERRUPTS_SYSEXIT32
|
|
|
|
|
|
+ CFI_RESTORE_STATE
|
|
|
+
|
|
|
#ifdef CONFIG_AUDITSYSCALL
|
|
|
.macro auditsys_entry_common
|
|
|
movl %esi,%r9d /* 6th arg: 4th syscall arg */
|
|
@@ -226,7 +238,6 @@ sysexit_from_sys_call:
|
|
|
.endm
|
|
|
|
|
|
sysenter_auditsys:
|
|
|
- CFI_RESTORE_STATE
|
|
|
auditsys_entry_common
|
|
|
movl %ebp,%r9d /* reload 6th syscall arg */
|
|
|
jmp sysenter_dispatch
|
|
@@ -235,6 +246,11 @@ sysexit_audit:
|
|
|
auditsys_exit sysexit_from_sys_call
|
|
|
#endif
|
|
|
|
|
|
+sysenter_fix_flags:
|
|
|
+ pushq_cfi $(X86_EFLAGS_IF|X86_EFLAGS_FIXED)
|
|
|
+ popfq_cfi
|
|
|
+ jmp sysenter_flags_fixed
|
|
|
+
|
|
|
sysenter_tracesys:
|
|
|
#ifdef CONFIG_AUDITSYSCALL
|
|
|
testl $(_TIF_WORK_SYSCALL_ENTRY & ~_TIF_SYSCALL_AUDIT),TI_flags+THREAD_INFO(%rsp,RIP-ARGOFFSET)
|