* [Adeos-main] [PATCH] x86: Always call fixup_if after event dispatching
@ 2009-02-20 14:33 Jan Kiszka
2009-02-23 12:04 ` Philippe Gerum
0 siblings, 1 reply; 2+ messages in thread
From: Jan Kiszka @ 2009-02-20 14:33 UTC (permalink / raw)
To: Philippe Gerum; +Cc: adeos-main
As we may switch the Linux context as a result of calling
__ipipe_dispatch_event and, thus, may leave it with a different root
domain state independent of the return code, we have to call __fixup_if
unconditionally. Moreover, we should also always check for pending VIRQs
on return.
Signed-off-by: Jan Kiszka <jan.kiszka@domain.hid>
---
arch/x86/kernel/ipipe.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
Index: b/arch/x86/kernel/ipipe.c
===================================================================
--- a/arch/x86/kernel/ipipe.c
+++ b/arch/x86/kernel/ipipe.c
@@ -540,6 +540,7 @@ asmlinkage void __ipipe_unstall_iret_roo
asmlinkage int __ipipe_syscall_root(struct pt_regs regs)
{
unsigned long flags;
+ int dont_pass;
__fixup_if(®s);
@@ -551,8 +552,9 @@ asmlinkage int __ipipe_syscall_root(stru
tail work has to be performed (for handling signals etc). */
if (__ipipe_syscall_watched_p(current, regs.orig_ax) &&
- __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
- __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,®s) > 0) {
+ __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) {
+ dont_pass = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,®s);
+
/* We might enter here over a non-root domain and exit
* over the root one as a result of the syscall
* (i.e. by recycling the register set of the current
@@ -568,9 +570,10 @@ asmlinkage int __ipipe_syscall_root(stru
if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
__ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
local_irq_restore_hw(flags);
- return -1;
- }
- return 1;
+ if (dont_pass)
+ return -1;
+ } else if (dont_pass)
+ return 1;
}
return 0;
@@ -610,6 +613,7 @@ asmlinkage int __ipipe_preempt_schedule_
asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
{
unsigned long flags;
+ int pass;
__fixup_if(regs);
@@ -621,8 +625,9 @@ asmlinkage int __ipipe_syscall_root(stru
tail work has to be performed (for handling signals etc). */
if (__ipipe_syscall_watched_p(current, regs->orig_ax) &&
- __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
- __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs) > 0) {
+ __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) {
+ pass = !__ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);
+
/* We might enter here over a non-root domain and exit
* over the root one as a result of the syscall
* (i.e. by recycling the register set of the current
@@ -632,6 +637,9 @@ asmlinkage int __ipipe_syscall_root(stru
* stall bit on exit. */
__fixup_if(regs);
+ if (pass)
+ return 0;
+
if (ipipe_root_domain_p && !in_atomic()) {
/* Sync pending VIRQs before _TIF_NEED_RESCHED is tested. */
local_irq_save_hw(flags);
@@ -648,7 +656,7 @@ asmlinkage int __ipipe_syscall_root(stru
return 1;
}
- return 0;
+ return 0;
}
#endif /* !CONFIG_X86_32 */
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [Adeos-main] [PATCH] x86: Always call fixup_if after event dispatching
2009-02-20 14:33 [Adeos-main] [PATCH] x86: Always call fixup_if after event dispatching Jan Kiszka
@ 2009-02-23 12:04 ` Philippe Gerum
0 siblings, 0 replies; 2+ messages in thread
From: Philippe Gerum @ 2009-02-23 12:04 UTC (permalink / raw)
To: Jan Kiszka; +Cc: adeos-main
Jan Kiszka wrote:
> As we may switch the Linux context as a result of calling
> __ipipe_dispatch_event and, thus, may leave it with a different root
> domain state independent of the return code, we have to call __fixup_if
> unconditionally. Moreover, we should also always check for pending VIRQs
> on return.
>
> Signed-off-by: Jan Kiszka <jan.kiszka@domain.hid>
>
> ---
> arch/x86/kernel/ipipe.c | 24 ++++++++++++++++--------
> 1 file changed, 16 insertions(+), 8 deletions(-)
>
> Index: b/arch/x86/kernel/ipipe.c
> ===================================================================
> --- a/arch/x86/kernel/ipipe.c
> +++ b/arch/x86/kernel/ipipe.c
> @@ -540,6 +540,7 @@ asmlinkage void __ipipe_unstall_iret_roo
> asmlinkage int __ipipe_syscall_root(struct pt_regs regs)
> {
> unsigned long flags;
> + int dont_pass;
>
> __fixup_if(®s);
>
> @@ -551,8 +552,9 @@ asmlinkage int __ipipe_syscall_root(stru
> tail work has to be performed (for handling signals etc). */
>
> if (__ipipe_syscall_watched_p(current, regs.orig_ax) &&
> - __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
> - __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,®s) > 0) {
> + __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) {
> + dont_pass = __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL,®s);
> +
> /* We might enter here over a non-root domain and exit
> * over the root one as a result of the syscall
> * (i.e. by recycling the register set of the current
> @@ -568,9 +570,10 @@ asmlinkage int __ipipe_syscall_root(stru
> if ((ipipe_root_cpudom_var(irqpend_himask) & IPIPE_IRQMASK_VIRT) != 0)
> __ipipe_sync_pipeline(IPIPE_IRQMASK_VIRT);
> local_irq_restore_hw(flags);
> - return -1;
> - }
> - return 1;
> + if (dont_pass)
> + return -1;
> + } else if (dont_pass)
> + return 1;
> }
>
> return 0;
> @@ -610,6 +613,7 @@ asmlinkage int __ipipe_preempt_schedule_
> asmlinkage int __ipipe_syscall_root(struct pt_regs *regs)
> {
> unsigned long flags;
> + int pass;
>
> __fixup_if(regs);
>
This needs fixing; a thread relaxing to secondary mode to run a regular Linux
syscall would trigger the issue as well.
> @@ -621,8 +625,9 @@ asmlinkage int __ipipe_syscall_root(stru
> tail work has to be performed (for handling signals etc). */
>
> if (__ipipe_syscall_watched_p(current, regs->orig_ax) &&
> - __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL) &&
> - __ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs) > 0) {
> + __ipipe_event_monitored_p(IPIPE_EVENT_SYSCALL)) {
> + pass = !__ipipe_dispatch_event(IPIPE_EVENT_SYSCALL, regs);
> +
> /* We might enter here over a non-root domain and exit
> * over the root one as a result of the syscall
> * (i.e. by recycling the register set of the current
> @@ -632,6 +637,9 @@ asmlinkage int __ipipe_syscall_root(stru
> * stall bit on exit. */
> __fixup_if(regs);
>
> + if (pass)
> + return 0;
> +
> if (ipipe_root_domain_p && !in_atomic()) {
We may remove the in_atomic() check. This is legacy code that does not serve any
purpose in recent kernels.
> /* Sync pending VIRQs before _TIF_NEED_RESCHED is tested. */
> local_irq_save_hw(flags);
> @@ -648,7 +656,7 @@ asmlinkage int __ipipe_syscall_root(stru
> return 1;
> }
>
> - return 0;
> + return 0;
> }
>
> #endif /* !CONFIG_X86_32 */
>
--
Philippe.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2009-02-23 12:04 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-20 14:33 [Adeos-main] [PATCH] x86: Always call fixup_if after event dispatching Jan Kiszka
2009-02-23 12:04 ` Philippe Gerum
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.