aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorPeter Beutner <p.beutner@gmx.net>2006-01-11 16:43:18 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-11 22:04:50 -0500
commit4724e3e86d806860c90917f9b73d4354e388b39b (patch)
treef14fb69d8fe50894107c48898f8583fdda985055 /arch
parent60917a3832547886549962ab9ee753253cf5e44c (diff)
[PATCH] x86_64: fix single step handling for 32bit processes
Be more careful with TF handling to fix some copy protection codes in wine patch originally for i386 by Linus, then ported to x86_64 by Andi Kleen see: [PATCH] x86_64: Some fixes for single step handling commit: be61bff789fe44bfb6d9282d8f7eccc860bdcfb6 But it was never applied to the ia32 emulation code which breaks some copy-protection schemes under wine when running on x86_64. Signed-off-by: Peter Beutner <p.beutner@gmx.net> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86_64/ia32/ia32_signal.c26
1 files changed, 7 insertions, 19 deletions
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 0903cc1faef2..e0a92439f634 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -353,7 +353,6 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
353 struct pt_regs *regs, unsigned int mask) 353 struct pt_regs *regs, unsigned int mask)
354{ 354{
355 int tmp, err = 0; 355 int tmp, err = 0;
356 u32 eflags;
357 356
358 tmp = 0; 357 tmp = 0;
359 __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp)); 358 __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
@@ -378,10 +377,7 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
378 err |= __put_user(current->thread.trap_no, &sc->trapno); 377 err |= __put_user(current->thread.trap_no, &sc->trapno);
379 err |= __put_user(current->thread.error_code, &sc->err); 378 err |= __put_user(current->thread.error_code, &sc->err);
380 err |= __put_user((u32)regs->rip, &sc->eip); 379 err |= __put_user((u32)regs->rip, &sc->eip);
381 eflags = regs->eflags; 380 err |= __put_user((u32)regs->eflags, &sc->eflags);
382 if (current->ptrace & PT_PTRACED)
383 eflags &= ~TF_MASK;
384 err |= __put_user((u32)eflags, &sc->eflags);
385 err |= __put_user((u32)regs->rsp, &sc->esp_at_signal); 381 err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
386 382
387 tmp = save_i387_ia32(current, fpstate, regs, 0); 383 tmp = save_i387_ia32(current, fpstate, regs, 0);
@@ -505,13 +501,9 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
505 regs->ss = __USER32_DS; 501 regs->ss = __USER32_DS;
506 502
507 set_fs(USER_DS); 503 set_fs(USER_DS);
508 if (regs->eflags & TF_MASK) { 504 regs->eflags &= ~TF_MASK;
509 if (current->ptrace & PT_PTRACED) { 505 if (test_thread_flag(TIF_SINGLESTEP))
510 ptrace_notify(SIGTRAP); 506 ptrace_notify(SIGTRAP);
511 } else {
512 regs->eflags &= ~TF_MASK;
513 }
514 }
515 507
516#if DEBUG_SIG 508#if DEBUG_SIG
517 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 509 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
@@ -605,13 +597,9 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
605 regs->ss = __USER32_DS; 597 regs->ss = __USER32_DS;
606 598
607 set_fs(USER_DS); 599 set_fs(USER_DS);
608 if (regs->eflags & TF_MASK) { 600 regs->eflags &= ~TF_MASK;
609 if (current->ptrace & PT_PTRACED) { 601 if (test_thread_flag(TIF_SINGLESTEP))
610 ptrace_notify(SIGTRAP); 602 ptrace_notify(SIGTRAP);
611 } else {
612 regs->eflags &= ~TF_MASK;
613 }
614 }
615 603
616#if DEBUG_SIG 604#if DEBUG_SIG
617 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n", 605 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",