aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/entry.S
diff options
context:
space:
mode:
authorAleksey Gorelov <Aleksey_Gorelov@Phoenix.com>2006-06-27 05:53:48 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-27 20:32:38 -0400
commit4031ff388138b58e5cd472dccce38828bcb8c706 (patch)
treef2c88fdcdef3ec9880d23ce271f14e95f7aa1cf5 /arch/i386/kernel/entry.S
parentc723e084606ca1c81e91b80b2c0c44bde7bbc4df (diff)
[PATCH] fix broken vm86 interrupt/signal handling
Commit c3ff8ec31c1249d268cd11390649768a12bec1b9 ("[PATCH] i386: Don't miss pending signals returning to user mode after signal processing") meant that vm86 interrupt/signal handling got broken for the case when vm86 is called from kernel space. In this scenario, if signal is pending because of vm86 interrupt, do_notify_resume/do_signal exits immediately due to user_mode() check, without processing any signals. Thus, resume_userspace handler is spinning in a tight loop with signal pending and TIF_SIGPENDING is set. Previously everything worked Ok. No in-tree usage of vm86() from kernel space exists, but I've heard about a number of projects out there which use vm86 calls from kernel, one of them being this, for instance: http://dev.gentoo.org/~spock/projects/vesafb-tng/ The following patch fixes the issue. Signed-off-by: Aleksey Gorelov <aleksey_gorelov@phoenix.com> Cc: Atsushi Nemoto <anemo@mba.ocn.ne.jp> Cc: Roland McGrath <roland@redhat.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/entry.S')
-rw-r--r--arch/i386/kernel/entry.S11
1 files changed, 9 insertions, 2 deletions
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 8713e0248a0b..e8d2630fd19a 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -83,6 +83,12 @@ VM_MASK = 0x00020000
83#define resume_kernel restore_nocheck 83#define resume_kernel restore_nocheck
84#endif 84#endif
85 85
86#ifdef CONFIG_VM86
87#define resume_userspace_sig check_userspace
88#else
89#define resume_userspace_sig resume_userspace
90#endif
91
86#define SAVE_ALL \ 92#define SAVE_ALL \
87 cld; \ 93 cld; \
88 pushl %es; \ 94 pushl %es; \
@@ -211,6 +217,7 @@ ret_from_exception:
211 preempt_stop 217 preempt_stop
212ret_from_intr: 218ret_from_intr:
213 GET_THREAD_INFO(%ebp) 219 GET_THREAD_INFO(%ebp)
220check_userspace:
214 movl EFLAGS(%esp), %eax # mix EFLAGS and CS 221 movl EFLAGS(%esp), %eax # mix EFLAGS and CS
215 movb CS(%esp), %al 222 movb CS(%esp), %al
216 testl $(VM_MASK | 3), %eax 223 testl $(VM_MASK | 3), %eax
@@ -415,7 +422,7 @@ work_notifysig: # deal with pending signals and
415 # vm86-space 422 # vm86-space
416 xorl %edx, %edx 423 xorl %edx, %edx
417 call do_notify_resume 424 call do_notify_resume
418 jmp resume_userspace 425 jmp resume_userspace_sig
419 426
420 ALIGN 427 ALIGN
421work_notifysig_v86: 428work_notifysig_v86:
@@ -428,7 +435,7 @@ work_notifysig_v86:
428 movl %eax, %esp 435 movl %eax, %esp
429 xorl %edx, %edx 436 xorl %edx, %edx
430 call do_notify_resume 437 call do_notify_resume
431 jmp resume_userspace 438 jmp resume_userspace_sig
432#endif 439#endif
433 440
434 # perform syscall exit tracing 441 # perform syscall exit tracing