summaryrefslogtreecommitdiffstats
path: root/sys/ia64
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2002-03-29 16:35:26 +0000
committerjake <jake@FreeBSD.org>2002-03-29 16:35:26 +0000
commit8f9ce8398dc5c2f244495c3d0f279c47f0c2d58d (patch)
treee9eef5126c7bc7935260d949155e4f3eb728510f /sys/ia64
parent1787e9ff8d12fd561c9345471ac9c345fa9251dd (diff)
downloadFreeBSD-src-8f9ce8398dc5c2f244495c3d0f279c47f0c2d58d.zip
FreeBSD-src-8f9ce8398dc5c2f244495c3d0f279c47f0c2d58d.tar.gz
Remove abuse of intr_disable/restore in MI code by moving the loop in ast()
back into the calling MD code. The MD code must ensure no races between checking the astpening flag and returning to usermode. Submitted by: peter (ia64 bits) Tested on: alpha (peter, jeff), i386, ia64 (peter), sparc64
Diffstat (limited to 'sys/ia64')
-rw-r--r--sys/ia64/ia64/exception.S34
-rw-r--r--sys/ia64/ia64/exception.s34
-rw-r--r--sys/ia64/ia64/genassym.c6
3 files changed, 68 insertions, 6 deletions
diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S
index 780dc3c..fabff37 100644
--- a/sys/ia64/ia64/exception.S
+++ b/sys/ia64/ia64/exception.S
@@ -822,10 +822,38 @@ ENTRY(exception_restore, 0)
extr.u r16=rIPSR,32,2 // extract ipsr.cpl
;;
cmp.eq p1,p2=r0,r16 // test for return to kernel mode
+(p1) br.cond.dpnt 2f // skip ast checking for returns to kernel
+3:
+ add r3=PC_CURTHREAD,r13 // &curthread
;;
-(p2) add out0=16,sp // trapframe argument to ast()
-(p2) br.call.dptk.many rp=ast // note: p1, p2 preserved
-
+ ld8 r3=[r3] // curthread
+ add r2=(KEF_ASTPENDING|KEF_NEEDRESCHED),r0
+ ;;
+ add r3=TD_KSE,r3 // &curthread->td_kse
+ mov r15=psr // save interrupt enable status
+ ;;
+ ld8 r3=[r3] // curkse
+ ;;
+ add r3=KE_FLAGS,r3 // &curkse->ke_flags
+ rsm psr.i // disable interrupts
+ ;;
+ ld4 r14=[r3] // fetch curkse->ke_flags
+ ;;
+ and r14=r2,r14 // flags & (KEF_ASTPENDING|KEF_NEEDRESCHED)
+ ;;
+ cmp4.eq p6,p7=r0,r14 // == 0 ?
+(p6) br.cond.dptk 2f
+ ;;
+ mov psr.l=r15 // restore interrups
+ ;;
+ srlz.d
+ ;;
+ add out0=16,sp // trapframe argument to ast()
+ br.call.sptk.many rp=ast // note: p1, p2 preserved
+ ;;
+ br 3b
+ ;;
+2:
rsm psr.ic|psr.dt|psr.i // disable interrupt collection and vm
add r3=16,sp;
;;
diff --git a/sys/ia64/ia64/exception.s b/sys/ia64/ia64/exception.s
index 780dc3c..fabff37 100644
--- a/sys/ia64/ia64/exception.s
+++ b/sys/ia64/ia64/exception.s
@@ -822,10 +822,38 @@ ENTRY(exception_restore, 0)
extr.u r16=rIPSR,32,2 // extract ipsr.cpl
;;
cmp.eq p1,p2=r0,r16 // test for return to kernel mode
+(p1) br.cond.dpnt 2f // skip ast checking for returns to kernel
+3:
+ add r3=PC_CURTHREAD,r13 // &curthread
;;
-(p2) add out0=16,sp // trapframe argument to ast()
-(p2) br.call.dptk.many rp=ast // note: p1, p2 preserved
-
+ ld8 r3=[r3] // curthread
+ add r2=(KEF_ASTPENDING|KEF_NEEDRESCHED),r0
+ ;;
+ add r3=TD_KSE,r3 // &curthread->td_kse
+ mov r15=psr // save interrupt enable status
+ ;;
+ ld8 r3=[r3] // curkse
+ ;;
+ add r3=KE_FLAGS,r3 // &curkse->ke_flags
+ rsm psr.i // disable interrupts
+ ;;
+ ld4 r14=[r3] // fetch curkse->ke_flags
+ ;;
+ and r14=r2,r14 // flags & (KEF_ASTPENDING|KEF_NEEDRESCHED)
+ ;;
+ cmp4.eq p6,p7=r0,r14 // == 0 ?
+(p6) br.cond.dptk 2f
+ ;;
+ mov psr.l=r15 // restore interrups
+ ;;
+ srlz.d
+ ;;
+ add out0=16,sp // trapframe argument to ast()
+ br.call.sptk.many rp=ast // note: p1, p2 preserved
+ ;;
+ br 3b
+ ;;
+2:
rsm psr.ic|psr.dt|psr.i // disable interrupt collection and vm
add r3=16,sp;
;;
diff --git a/sys/ia64/ia64/genassym.c b/sys/ia64/ia64/genassym.c
index 99e74c6..8dbc394 100644
--- a/sys/ia64/ia64/genassym.c
+++ b/sys/ia64/ia64/genassym.c
@@ -76,9 +76,15 @@ ASSYM(MTX_UNOWNED, MTX_UNOWNED);
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
+ASSYM(TD_KSE, offsetof(struct thread, td_kse));
ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack));
ASSYM(TD_MD_FLAGS, offsetof(struct thread, td_md.md_flags));
+ASSYM(KE_FLAGS, offsetof(struct kse, ke_flags));
+
+ASSYM(KEF_ASTPENDING, KEF_ASTPENDING);
+ASSYM(KEF_NEEDRESCHED, KEF_NEEDRESCHED);
+
ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
ASSYM(FRAME_SYSCALL, FRAME_SYSCALL);
OpenPOWER on IntegriCloud