* [PATCH 2.4.31 6/9] gcc4: fix x86_64 sys_iopl() bug
@ 2005-06-12 11:20 Mikael Pettersson
2005-06-12 13:29 ` Andi Kleen
0 siblings, 1 reply; 4+ messages in thread
From: Mikael Pettersson @ 2005-06-12 11:20 UTC (permalink / raw)
To: marcelo.tosatti; +Cc: ak, linux-kernel
On x86_64 sys_iopl() becomes a no-op when compiled with gcc4.
This breaks the X server, causing its PCI probing to fail.
This is caused by a bug. sys_iopl() receives a struct pt_regs as
a formal parameter, and updates it expecting those updates to
remain when it returns. This is incorrect as the calling convention
rules say that a function's formal parameters are initialised
copies that disappear when the function returns.
The fix (backport from 2.6) is to pass the pt_regs by reference.
Signed-off-by: Mikael Pettersson <mikpe@csd.uu.se>
arch/x86_64/ia32/ia32entry.S | 11 ++++++++++-
arch/x86_64/kernel/entry.S | 11 ++++++++++-
arch/x86_64/kernel/ioport.c | 6 +++---
3 files changed, 23 insertions(+), 5 deletions(-)
diff -rupN linux-2.4.31/arch/x86_64/ia32/ia32entry.S linux-2.4.31.gcc4-x86_64-iopl-bug/arch/x86_64/ia32/ia32entry.S
--- linux-2.4.31/arch/x86_64/ia32/ia32entry.S 2005-01-19 18:00:53.000000000 +0100
+++ linux-2.4.31.gcc4-x86_64-iopl-bug/arch/x86_64/ia32/ia32entry.S 2005-06-12 11:46:56.000000000 +0200
@@ -113,9 +113,18 @@ quiet_ni_syscall:
PTREGSCALL stub32_fork, sys32_fork
PTREGSCALL stub32_clone, sys32_clone
PTREGSCALL stub32_vfork, sys32_vfork
- PTREGSCALL stub32_iopl, sys_iopl
PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
+ .macro PTREGSCALL3 label, func, arg
+ .globl \label
+\label:
+ leaq \func(%rip),%rax
+ leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
+ jmp ia32_ptregs_common
+ .endm
+
+ PTREGSCALL3 stub32_iopl, sys_iopl, %rsi
+
ENTRY(ia32_ptregs_common)
popq %r11
SAVE_REST
diff -rupN linux-2.4.31/arch/x86_64/kernel/entry.S linux-2.4.31.gcc4-x86_64-iopl-bug/arch/x86_64/kernel/entry.S
--- linux-2.4.31/arch/x86_64/kernel/entry.S 2003-11-29 00:28:11.000000000 +0100
+++ linux-2.4.31.gcc4-x86_64-iopl-bug/arch/x86_64/kernel/entry.S 2005-06-12 11:46:56.000000000 +0200
@@ -249,7 +249,16 @@ intret_signal_test:
PTREGSCALL stub_vfork, sys_vfork
PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend
PTREGSCALL stub_sigaltstack, sys_sigaltstack
- PTREGSCALL stub_iopl, sys_iopl
+
+ .macro PTREGSCALL3 label,func,arg
+ .globl \label
+\label:
+ leaq \func(%rip),%rax
+ leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
+ jmp ptregscall_common
+ .endm
+
+ PTREGSCALL3 stub_iopl, sys_iopl, %rsi
ENTRY(ptregscall_common)
popq %r11
diff -rupN linux-2.4.31/arch/x86_64/kernel/ioport.c linux-2.4.31.gcc4-x86_64-iopl-bug/arch/x86_64/kernel/ioport.c
--- linux-2.4.31/arch/x86_64/kernel/ioport.c 2003-11-29 00:28:11.000000000 +0100
+++ linux-2.4.31.gcc4-x86_64-iopl-bug/arch/x86_64/kernel/ioport.c 2005-06-12 11:46:56.000000000 +0200
@@ -81,9 +81,9 @@ asmlinkage long sys_ioperm(unsigned long
* code.
*/
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs regs)
+asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
{
- unsigned int old = (regs.eflags >> 12) & 3;
+ unsigned int old = (regs->eflags >> 12) & 3;
if (level > 3)
return -EINVAL;
@@ -92,6 +92,6 @@ asmlinkage long sys_iopl(unsigned int le
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
}
- regs.eflags = (regs.eflags & 0xffffffffffffcfff) | (level << 12);
+ regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
return 0;
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2.4.31 6/9] gcc4: fix x86_64 sys_iopl() bug
2005-06-12 11:20 [PATCH 2.4.31 6/9] gcc4: fix x86_64 sys_iopl() bug Mikael Pettersson
@ 2005-06-12 13:29 ` Andi Kleen
0 siblings, 0 replies; 4+ messages in thread
From: Andi Kleen @ 2005-06-12 13:29 UTC (permalink / raw)
To: Mikael Pettersson; +Cc: marcelo.tosatti, ak, linux-kernel
> @@ -113,9 +113,18 @@ quiet_ni_syscall:
> PTREGSCALL stub32_fork, sys32_fork
> PTREGSCALL stub32_clone, sys32_clone
> PTREGSCALL stub32_vfork, sys32_vfork
> - PTREGSCALL stub32_iopl, sys_iopl
> PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
>
> + .macro PTREGSCALL3 label, func, arg
PTREGSCALL3? I'm sure that is not in 2.6. How about just changing
PTREGSCALL globally?
iirc the other ptregs syscalls were safe, but I still changed them in 2.6
to use a pointer argument.
-Andi
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2.4.31 6/9] gcc4: fix x86_64 sys_iopl() bug
@ 2005-06-12 16:29 Mikael Pettersson
0 siblings, 0 replies; 4+ messages in thread
From: Mikael Pettersson @ 2005-06-12 16:29 UTC (permalink / raw)
To: ak; +Cc: linux-kernel, marcelo.tosatti
On Sun, 12 Jun 2005 15:29:43 +0200, Andi Kleen wrote:
>> @@ -113,9 +113,18 @@ quiet_ni_syscall:
>> PTREGSCALL stub32_fork, sys32_fork
>> PTREGSCALL stub32_clone, sys32_clone
>> PTREGSCALL stub32_vfork, sys32_vfork
>> - PTREGSCALL stub32_iopl, sys_iopl
>> PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
>>
>> + .macro PTREGSCALL3 label, func, arg
>
>PTREGSCALL3? I'm sure that is not in 2.6. How about just changing
>PTREGSCALL globally?
>
>iirc the other ptregs syscalls were safe, but I still changed them in 2.6
>to use a pointer argument.
This patch changes all PTREGSCALLs to follow the 2.6 convention.
Unfortunately this is a much larger patch than the one that just
fixes sys_iopl(). I've triple-checked the register numbers passed
to the PTREGSCALL macro, and things do seem to work correctly.
Signed-off-by: Mikael Pettersson <mikpe@csd.uu.se>
arch/x86_64/ia32/ia32_signal.c | 28 ++++++++++++++--------------
arch/x86_64/ia32/ia32entry.S | 23 ++++++++++++-----------
arch/x86_64/ia32/sys_ia32.c | 18 +++++++++---------
arch/x86_64/kernel/entry.S | 16 +++++++++-------
arch/x86_64/kernel/ioport.c | 6 +++---
arch/x86_64/kernel/process.c | 14 +++++++-------
arch/x86_64/kernel/signal.c | 24 ++++++++++++------------
7 files changed, 66 insertions(+), 63 deletions(-)
diff -rupN linux-2.4.31/arch/x86_64/ia32/ia32_signal.c linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/ia32/ia32_signal.c
--- linux-2.4.31/arch/x86_64/ia32/ia32_signal.c 2003-11-29 00:28:11.000000000 +0100
+++ linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/ia32/ia32_signal.c 2005-06-12 17:55:52.000000000 +0200
@@ -89,7 +89,7 @@ static int ia32_copy_siginfo_to_user(sig
}
asmlinkage long
-sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs regs)
+sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs *regs)
{
sigset_t saveset;
@@ -100,18 +100,18 @@ sys32_sigsuspend(int history0, int histo
recalc_sigpending(current);
spin_unlock_irq(¤t->sigmask_lock);
- regs.rax = -EINTR;
+ regs->rax = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(®s, &saveset))
+ if (do_signal(regs, &saveset))
return -EINTR;
}
}
asmlinkage long
sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr,
- struct pt_regs regs)
+ struct pt_regs *regs)
{
stack_t uss,uoss;
int ret;
@@ -128,7 +128,7 @@ sys32_sigaltstack(const stack_ia32_t *us
}
seg = get_fs();
set_fs(KERNEL_DS);
- ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs.rsp);
+ ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->rsp);
set_fs(seg);
if (ret >= 0 && uoss_ptr) {
if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) ||
@@ -241,9 +241,9 @@ ia32_restore_sigcontext(struct pt_regs *
return err;
}
-asmlinkage long sys32_sigreturn(struct pt_regs regs)
+asmlinkage long sys32_sigreturn(struct pt_regs *regs)
{
- struct sigframe *frame = (struct sigframe *)(regs.rsp - 8);
+ struct sigframe *frame = (struct sigframe *)(regs->rsp - 8);
sigset_t set;
unsigned int eax;
@@ -261,18 +261,18 @@ asmlinkage long sys32_sigreturn(struct p
recalc_sigpending(current);
spin_unlock_irq(¤t->sigmask_lock);
- if (ia32_restore_sigcontext(®s, &frame->sc, &eax))
+ if (ia32_restore_sigcontext(regs, &frame->sc, &eax))
goto badframe;
return eax;
badframe:
- signal_fault(®s,frame,"32bit sigreturn");
+ signal_fault(regs,frame,"32bit sigreturn");
return 0;
}
-asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
+asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
{
- struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
+ struct rt_sigframe *frame = (struct rt_sigframe *)(regs->rsp - 4);
sigset_t set;
stack_t st;
unsigned int eax;
@@ -288,7 +288,7 @@ asmlinkage long sys32_rt_sigreturn(struc
recalc_sigpending(current);
spin_unlock_irq(¤t->sigmask_lock);
- if (ia32_restore_sigcontext(®s, &frame->uc.uc_mcontext, &eax))
+ if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
goto badframe;
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
@@ -298,14 +298,14 @@ asmlinkage long sys32_rt_sigreturn(struc
{
mm_segment_t oldds = get_fs();
set_fs(KERNEL_DS);
- do_sigaltstack(&st, NULL, regs.rsp);
+ do_sigaltstack(&st, NULL, regs->rsp);
set_fs(oldds);
}
return eax;
badframe:
- signal_fault(®s,frame,"32bit rt sigreturn");
+ signal_fault(regs,frame,"32bit rt sigreturn");
return 0;
}
diff -rupN linux-2.4.31/arch/x86_64/ia32/ia32entry.S linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/ia32/ia32entry.S
--- linux-2.4.31/arch/x86_64/ia32/ia32entry.S 2005-01-19 18:00:53.000000000 +0100
+++ linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/ia32/ia32entry.S 2005-06-12 17:55:52.000000000 +0200
@@ -98,23 +98,24 @@ quiet_ni_syscall:
movl $-ENOSYS,%eax
ret
- .macro PTREGSCALL label, func
+ .macro PTREGSCALL label, func, arg
.globl \label
\label:
leaq \func(%rip),%rax
+ leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
jmp ia32_ptregs_common
.endm
- PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn
- PTREGSCALL stub32_sigreturn, sys32_sigreturn
- PTREGSCALL stub32_sigaltstack, sys32_sigaltstack
- PTREGSCALL stub32_sigsuspend, sys32_sigsuspend
- PTREGSCALL stub32_execve, sys32_execve
- PTREGSCALL stub32_fork, sys32_fork
- PTREGSCALL stub32_clone, sys32_clone
- PTREGSCALL stub32_vfork, sys32_vfork
- PTREGSCALL stub32_iopl, sys_iopl
- PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
+ PTREGSCALL stub32_rt_sigreturn, sys32_rt_sigreturn, %rdi
+ PTREGSCALL stub32_sigreturn, sys32_sigreturn, %rdi
+ PTREGSCALL stub32_sigaltstack, sys32_sigaltstack, %rdx
+ PTREGSCALL stub32_sigsuspend, sys32_sigsuspend, %rcx
+ PTREGSCALL stub32_execve, sys32_execve, %rcx
+ PTREGSCALL stub32_fork, sys32_fork, %rdi
+ PTREGSCALL stub32_clone, sys32_clone, %rdx
+ PTREGSCALL stub32_vfork, sys32_vfork, %rdi
+ PTREGSCALL stub32_iopl, sys_iopl, %rsi
+ PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend, %rdx
ENTRY(ia32_ptregs_common)
popq %r11
diff -rupN linux-2.4.31/arch/x86_64/ia32/sys_ia32.c linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/ia32/sys_ia32.c
--- linux-2.4.31/arch/x86_64/ia32/sys_ia32.c 2005-01-19 18:00:53.000000000 +0100
+++ linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/ia32/sys_ia32.c 2005-06-12 17:55:52.000000000 +0200
@@ -2222,7 +2222,7 @@ static int nargs(u32 src, char **dst)
return cnt;
}
-asmlinkage long sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs regs)
+asmlinkage long sys32_execve(char *name, u32 argv, u32 envp, struct pt_regs *regs)
{
mm_segment_t oldseg;
char **buf = NULL;
@@ -2270,7 +2270,7 @@ asmlinkage long sys32_execve(char *name,
oldseg = get_fs();
set_fs(KERNEL_DS);
- ret = do_execve(name, argv ? buf : NULL, envp ? buf+na : NULL, ®s);
+ ret = do_execve(name, argv ? buf : NULL, envp ? buf+na : NULL, regs);
set_fs(oldseg);
if (ret == 0)
@@ -2288,16 +2288,16 @@ free:
return ret;
}
-asmlinkage long sys32_fork(struct pt_regs regs)
+asmlinkage long sys32_fork(struct pt_regs *regs)
{
- return do_fork(SIGCHLD, regs.rsp, ®s, 0);
+ return do_fork(SIGCHLD, regs->rsp, regs, 0);
}
-asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs regs)
+asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, struct pt_regs *regs)
{
if (!newsp)
- newsp = regs.rsp;
- return do_fork(clone_flags, newsp, ®s, 0);
+ newsp = regs->rsp;
+ return do_fork(clone_flags, newsp, regs, 0);
}
/*
@@ -2310,9 +2310,9 @@ asmlinkage long sys32_clone(unsigned int
* do not have enough call-clobbered registers to hold all
* the information you need.
*/
-asmlinkage long sys32_vfork(struct pt_regs regs)
+asmlinkage long sys32_vfork(struct pt_regs *regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, ®s, 0);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0);
}
/*
diff -rupN linux-2.4.31/arch/x86_64/kernel/entry.S linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/entry.S
--- linux-2.4.31/arch/x86_64/kernel/entry.S 2003-11-29 00:28:11.000000000 +0100
+++ linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/entry.S 2005-06-12 17:55:52.000000000 +0200
@@ -237,19 +237,20 @@ intret_signal_test:
* Certain special system calls that need to save a complete stack frame.
*/
- .macro PTREGSCALL label,func
+ .macro PTREGSCALL label,func,arg
.globl \label
\label:
leaq \func(%rip),%rax
+ leaq -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
jmp ptregscall_common
.endm
- PTREGSCALL stub_clone, sys_clone
- PTREGSCALL stub_fork, sys_fork
- PTREGSCALL stub_vfork, sys_vfork
- PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend
- PTREGSCALL stub_sigaltstack, sys_sigaltstack
- PTREGSCALL stub_iopl, sys_iopl
+ PTREGSCALL stub_clone, sys_clone, %rdx /* not %r8 as it is in 2.6 */
+ PTREGSCALL stub_fork, sys_fork, %rdi
+ PTREGSCALL stub_vfork, sys_vfork, %rdi
+ PTREGSCALL stub_rt_sigsuspend, sys_rt_sigsuspend, %rdx
+ PTREGSCALL stub_sigaltstack, sys_sigaltstack, %rdx
+ PTREGSCALL stub_iopl, sys_iopl, %rsi
ENTRY(ptregscall_common)
popq %r11
@@ -290,6 +291,7 @@ exec_32bit:
ENTRY(stub_rt_sigreturn)
addq $8, %rsp
SAVE_REST
+ movq %rsp,%rdi
FIXUP_TOP_OF_STACK %r11
call sys_rt_sigreturn
movq %rax,RAX(%rsp) # fixme, this could be done at the higher layer
diff -rupN linux-2.4.31/arch/x86_64/kernel/ioport.c linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/ioport.c
--- linux-2.4.31/arch/x86_64/kernel/ioport.c 2003-11-29 00:28:11.000000000 +0100
+++ linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/ioport.c 2005-06-12 17:55:52.000000000 +0200
@@ -81,9 +81,9 @@ asmlinkage long sys_ioperm(unsigned long
* code.
*/
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs regs)
+asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
{
- unsigned int old = (regs.eflags >> 12) & 3;
+ unsigned int old = (regs->eflags >> 12) & 3;
if (level > 3)
return -EINVAL;
@@ -92,6 +92,6 @@ asmlinkage long sys_iopl(unsigned int le
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
}
- regs.eflags = (regs.eflags & 0xffffffffffffcfff) | (level << 12);
+ regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12);
return 0;
}
diff -rupN linux-2.4.31/arch/x86_64/kernel/process.c linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/process.c
--- linux-2.4.31/arch/x86_64/kernel/process.c 2005-06-01 18:02:21.000000000 +0200
+++ linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/process.c 2005-06-12 17:55:52.000000000 +0200
@@ -700,16 +700,16 @@ void set_personality_64bit(void)
current->thread.flags = 0;
}
-asmlinkage long sys_fork(struct pt_regs regs)
+asmlinkage long sys_fork(struct pt_regs *regs)
{
- return do_fork(SIGCHLD, regs.rsp, ®s, 0);
+ return do_fork(SIGCHLD, regs->rsp, regs, 0);
}
-asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs regs)
+asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp, struct pt_regs *regs)
{
if (!newsp)
- newsp = regs.rsp;
- return do_fork(clone_flags, newsp, ®s, 0);
+ newsp = regs->rsp;
+ return do_fork(clone_flags, newsp, regs, 0);
}
/*
@@ -722,9 +722,9 @@ asmlinkage long sys_clone(unsigned long
* do not have enough call-clobbered registers to hold all
* the information you need.
*/
-asmlinkage long sys_vfork(struct pt_regs regs)
+asmlinkage long sys_vfork(struct pt_regs *regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.rsp, ®s, 0);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0);
}
/*
diff -rupN linux-2.4.31/arch/x86_64/kernel/signal.c linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/signal.c
--- linux-2.4.31/arch/x86_64/kernel/signal.c 2005-01-19 18:00:53.000000000 +0100
+++ linux-2.4.31.gcc4-ptregscall-changes/arch/x86_64/kernel/signal.c 2005-06-12 17:55:52.000000000 +0200
@@ -82,7 +82,7 @@ int copy_siginfo_to_user(siginfo_t *to,
}
asmlinkage long
-sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs regs)
+sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, struct pt_regs *regs)
{
sigset_t saveset, newset;
@@ -101,21 +101,21 @@ sys_rt_sigsuspend(sigset_t *unewset, siz
spin_unlock_irq(¤t->sigmask_lock);
#if DEBUG_SIG
printk("rt_sigsuspend savset(%lx) newset(%lx) regs(%p) rip(%lx)\n",
- saveset, newset, ®s, regs.rip);
+ saveset, newset, regs, regs->rip);
#endif
- regs.rax = -EINTR;
+ regs->rax = -EINTR;
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(®s, &saveset))
+ if (do_signal(regs, &saveset))
return -EINTR;
}
}
asmlinkage long
-sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs regs)
+sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs)
{
- return do_sigaltstack(uss, uoss, regs.rsp);
+ return do_sigaltstack(uss, uoss, regs->rsp);
}
@@ -180,9 +180,9 @@ restore_sigcontext(struct pt_regs *regs,
}
#undef COPY
-asmlinkage long sys_rt_sigreturn(struct pt_regs regs)
+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
{
- struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 8);
+ struct rt_sigframe *frame = (struct rt_sigframe *)(regs->rsp - 8);
sigset_t set;
stack_t st;
long eax;
@@ -198,23 +198,23 @@ asmlinkage long sys_rt_sigreturn(struct
recalc_sigpending(current);
spin_unlock_irq(¤t->sigmask_lock);
- if (restore_sigcontext(®s, &frame->uc.uc_mcontext, &eax))
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
goto badframe;
#if DEBUG_SIG
- printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs.rip,regs.rsp,frame,eax);
+ printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs->rip,regs->rsp,frame,eax);
#endif
if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
- do_sigaltstack(&st, NULL, regs.rsp);
+ do_sigaltstack(&st, NULL, regs->rsp);
return eax;
badframe:
- signal_fault(®s, frame, "rt_sigreturn");
+ signal_fault(regs, frame, "rt_sigreturn");
return 0;
}
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2.4.31 6/9] gcc4: fix x86_64 sys_iopl() bug
@ 2005-06-12 14:11 Mikael Pettersson
0 siblings, 0 replies; 4+ messages in thread
From: Mikael Pettersson @ 2005-06-12 14:11 UTC (permalink / raw)
To: ak; +Cc: linux-kernel, marcelo.tosatti
Andi wrote:
> > @@ -113,9 +113,18 @@ quiet_ni_syscall:
> > PTREGSCALL stub32_fork, sys32_fork
> > PTREGSCALL stub32_clone, sys32_clone
> > PTREGSCALL stub32_vfork, sys32_vfork
> > - PTREGSCALL stub32_iopl, sys_iopl
> > PTREGSCALL stub32_rt_sigsuspend, sys_rt_sigsuspend
> >
> > + .macro PTREGSCALL3 label, func, arg
>
> PTREGSCALL3? I'm sure that is not in 2.6. How about just changing
> PTREGSCALL globally?
Well I renamed it so that I could use it _only_ for the required
syscalls, i.e. sys_iopl(). I can change all of them if you feel
that's more appropriate.
/Mikael
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2005-06-12 19:20 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-12 11:20 [PATCH 2.4.31 6/9] gcc4: fix x86_64 sys_iopl() bug Mikael Pettersson
2005-06-12 13:29 ` Andi Kleen
2005-06-12 14:11 Mikael Pettersson
2005-06-12 16:29 Mikael Pettersson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®