From ca381c2e5ad330b45fdbf891e5e81d5ec2e4af95 Mon Sep 17 00:00:00 2001 From: marcel Date: Sat, 24 May 2003 22:53:10 +0000 Subject: [PATCH] Fix a source of instability specific to an EPC userland. We return to userland with interrupts disabled until we restore PSR. However, it has been observed that interrupts do actually happen before they are enabled again. This is a bit surprising and I don't know yet what's going on exactly. Nevertheless, the code was not crafted carefully enough to allow interrupts to happen and we could clobber the kernel stack of another thread when interrupts did happen. This is what happens: we restore the (memory) stack pointer (sp) and the register stack base prior to restoring ar.k6 and ar.k7. This is not a problem if interrupts don't happen between setting sp/ar.bspstore and ar.k6/ar.k7. Alas, interrupts can happen. Since sp/ar.bspstore already point to the userland stacks, we need to switch to the kernel stack in interrupt. However, ar.k6 and ar.k7 have not been set, which means that we were switching to some unrelated kstack and happily clobbered the trapframe present there if the thread to which the kstack belonged was in kernel mode or otherwise we could have our trapframe clobbered if that other thread enters the kernel. Nasty either way. We now carefully restore ar.k6 prior to restoring ar.bspstore and likewise for ar.k7 and sp. All we need is the guarantee that an interrupt does not clobber ar.k6 or ar.k7 before we're back in userland. That has been achieved by restoring ar.k6/ar.k7 unconditionally (see exception.s) While here, remove the disabling of interrupts on EPC entry. It was added as a way to "resolve" the crashes until it was understood what was going on. I think I achieved the latter, so we can remove the patch. Note that setting up a trapframe with interrupts enabled has it's own share of corner cases, but it's better to properly fixed those than to keep a mostly wrong patch around because we're afraid to remove it... Approved by: re@ (blanket) --- sys/ia64/ia64/syscall.S | 11 ++++------- sys/ia64/ia64/syscall.s | 11 ++++------- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/sys/ia64/ia64/syscall.S b/sys/ia64/ia64/syscall.S index 1ad2856006c6..5aacd79e5bb6 100644 --- a/sys/ia64/ia64/syscall.S +++ b/sys/ia64/ia64/syscall.S @@ -242,9 +242,6 @@ ENTRY(epc_syscall, 8) .prologue .unwabi @svr4, 'E' .save rp, r0 - - rsm psr.i - ;; { .mmi mov r16=ar.rsc mov ar.rsc=0 @@ -380,7 +377,7 @@ ENTRY(epc_syscall, 8) ;; } { .mlx - ssm psr.dfh|psr.ac|psr.i + ssm psr.dfh|psr.ac movl gp=__gp ;; } @@ -473,20 +470,20 @@ epc_syscall_return: } { .mmi loadrs - mov r14=ar.k5 + mov ar.k7=r31 mov sp=r16 ;; } { .mmi mov r30=ar.bspstore ;; - mov ar.bspstore=r21 + mov r14=ar.k5 dep r30=0,r30,0,9 ;; } { .mmi mov ar.k6=r30 - mov ar.k7=r31 + mov ar.bspstore=r21 mov r13=r23 ;; } diff --git a/sys/ia64/ia64/syscall.s b/sys/ia64/ia64/syscall.s index 1ad2856006c6..5aacd79e5bb6 100644 --- a/sys/ia64/ia64/syscall.s +++ b/sys/ia64/ia64/syscall.s @@ -242,9 +242,6 @@ ENTRY(epc_syscall, 8) .prologue .unwabi @svr4, 'E' .save rp, r0 - - rsm psr.i - ;; { .mmi mov r16=ar.rsc mov ar.rsc=0 @@ -380,7 +377,7 @@ ENTRY(epc_syscall, 8) ;; } { .mlx - ssm psr.dfh|psr.ac|psr.i + ssm psr.dfh|psr.ac movl gp=__gp ;; } @@ -473,20 +470,20 @@ epc_syscall_return: } { .mmi loadrs - mov r14=ar.k5 + mov ar.k7=r31 mov sp=r16 ;; } { .mmi mov r30=ar.bspstore ;; - mov ar.bspstore=r21 + mov r14=ar.k5 dep r30=0,r30,0,9 ;; } { .mmi mov ar.k6=r30 - mov ar.k7=r31 + mov ar.bspstore=r21 mov r13=r23 ;; }