Commit 04b50ac4 authored by Linus Torvalds's avatar Linus Torvalds

Make six-argument system calls work with the fast system call

trampoline.

Here's how: we re-load %ebp (arg6) in the kernel sysenter handler
from the stack, and on system call re-play we jump back in user
space to re-initialize %ebp to point to the stack pointer before
re-doing the sysenter instruction.
parent ca374dc6
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include <asm/errno.h> #include <asm/errno.h>
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/page.h>
#include "irq_vectors.h" #include "irq_vectors.h"
EBX = 0x00 EBX = 0x00
...@@ -232,7 +233,7 @@ need_resched: ...@@ -232,7 +233,7 @@ need_resched:
#endif #endif
/* Points to after the "sysenter" instruction in the vsyscall page */ /* Points to after the "sysenter" instruction in the vsyscall page */
#define SYSENTER_RETURN 0xffffe007 #define SYSENTER_RETURN 0xffffe009
# sysenter call handler stub # sysenter call handler stub
ALIGN ALIGN
...@@ -244,6 +245,18 @@ ENTRY(sysenter_entry) ...@@ -244,6 +245,18 @@ ENTRY(sysenter_entry)
pushl $(__USER_CS) pushl $(__USER_CS)
pushl $SYSENTER_RETURN pushl $SYSENTER_RETURN
/*
* Load the potential sixth argument from user stack.
* Careful about security.
*/
cmpl $__PAGE_OFFSET-3,%ebp
jae syscall_badsys
1: movl (%ebp),%ebp
.section __ex_table,"a"
.align 4
.long 1b,syscall_badsys
.previous
pushl %eax pushl %eax
SAVE_ALL SAVE_ALL
GET_THREAD_INFO(%ebx) GET_THREAD_INFO(%ebx)
......
...@@ -48,14 +48,17 @@ static int __init sysenter_setup(void) ...@@ -48,14 +48,17 @@ static int __init sysenter_setup(void)
0xc3 /* ret */ 0xc3 /* ret */
}; };
static const char sysent[] = { static const char sysent[] = {
0x55, /* push %ebp */
0x51, /* push %ecx */ 0x51, /* push %ecx */
0x52, /* push %edx */ 0x52, /* push %edx */
0x55, /* push %ebp */
0x89, 0xe5, /* movl %esp,%ebp */ 0x89, 0xe5, /* movl %esp,%ebp */
0x0f, 0x34, /* sysenter */ 0x0f, 0x34, /* sysenter */
/* System call restart point is here! (SYSENTER_RETURN - 2) */
0xeb, 0xfa, /* jmp to "movl %esp,%ebp" */
/* System call normal return point is here! (SYSENTER_RETURN in entry.S) */
0x5d, /* pop %ebp */
0x5a, /* pop %edx */ 0x5a, /* pop %edx */
0x59, /* pop %ecx */ 0x59, /* pop %ecx */
0x5d, /* pop %ebp */
0xc3 /* ret */ 0xc3 /* ret */
}; };
unsigned long page = get_zeroed_page(GFP_ATOMIC); unsigned long page = get_zeroed_page(GFP_ATOMIC);
......
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