diff --git a/sys/arch/sh3/sh3/exception.c b/sys/arch/sh3/sh3/exception.c index d1e757345f51..c52fe38ed38a 100644 --- a/sys/arch/sh3/sh3/exception.c +++ b/sys/arch/sh3/sh3/exception.c @@ -1,4 +1,4 @@ -/* $NetBSD: exception.c,v 1.40 2007/08/27 00:22:20 uwe Exp $ */ +/* $NetBSD: exception.c,v 1.41 2007/09/24 01:17:15 uwe Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved. @@ -79,7 +79,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: exception.c,v 1.40 2007/08/27 00:22:20 uwe Exp $"); +__KERNEL_RCSID(0, "$NetBSD: exception.c,v 1.41 2007/09/24 01:17:15 uwe Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -432,12 +432,6 @@ ast(struct lwp *l, struct trapframe *tf) { if (KERNELMODE(tf->tf_ssr)) { - extern char _lock_cas_ras_start[]; - extern char _lock_cas_ras_end[]; - - if ((uintptr_t)tf->tf_spc > (uintptr_t)_lock_cas_ras_start - && (uintptr_t)tf->tf_spc < (uintptr_t)_lock_cas_ras_end) - tf->tf_spc = (uintptr_t)_lock_cas_ras_start; return; } diff --git a/sys/arch/sh3/sh3/exception_vector.S b/sys/arch/sh3/sh3/exception_vector.S index 54a9eff51727..d10ef10199da 100644 --- a/sys/arch/sh3/sh3/exception_vector.S +++ b/sys/arch/sh3/sh3/exception_vector.S @@ -1,4 +1,4 @@ -/* $NetBSD: exception_vector.S,v 1.30 2007/08/20 01:05:23 uwe Exp $ */ +/* $NetBSD: exception_vector.S,v 1.31 2007/09/24 01:17:15 uwe Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -53,7 +53,7 @@ #define _ALIGN_TEXT .align 5 #include -__KERNEL_RCSID(0, "$NetBSD: exception_vector.S,v 1.30 2007/08/20 01:05:23 uwe Exp $") +__KERNEL_RCSID(0, "$NetBSD: exception_vector.S,v 1.31 2007/09/24 01:17:15 uwe Exp $") /* @@ -467,12 +467,34 @@ NENTRY(sh_vector_interrupt) mov.l .Li_intc_intr, r0 jsr @r0 /* intc_intr(ssr, spc, ssp) */ nop + + mov.l @(TF_SSR, r14), r2 + mov.l .Li_PSL_MD, r1 + tst r1, r2 ! tf->tf_ssr & PSL_MD == 0 ? + bt .Li_return_to_user + + !! Check for interrupted kernel RAS when returning to kernel + mov.l @(TF_SPC, r14), r2 + mov.l .Li_ras_start, r3 + cmp/hi r3, r2 ! spc > _lock_cas_ras_start ? + bf .Li_return_from_interrupt + + mov.l .Li_ras_end, r1 + cmp/hs r1, r2 ! spc >= _lock_cas_ras_end ? + bt .Li_return_from_interrupt + + bra .Li_return_from_interrupt + mov.l r3, @(TF_SPC, r14) ! spc = _lock_cas_ras_start + +.Li_return_to_user: /* Check for ASTs on exit to user mode. */ mov.l .Li_curlwp, r0 mov.l @r0, r4 /* 1st arg */ mov.l .Li_ast, r0 jsr @r0 mov r14, r5 /* 2nd arg */ + +.Li_return_from_interrupt: __EXCEPTION_RETURN .align 5 @@ -480,6 +502,10 @@ NENTRY(sh_vector_interrupt) .Li_intc_intr: .long _C_LABEL(intc_intr) .Li_ast: .long _C_LABEL(ast) .Li_uvmexp_intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS +.Li_PSL_MD: .long 0x40000000 /* PSL_MD */ +.Li_ras_start: .long _C_LABEL(_lock_cas_ras_start) +.Li_ras_end: .long _C_LABEL(_lock_cas_ras_end) + /* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */ VECTOR_END_MARKER(sh_vector_interrupt_end) diff --git a/sys/arch/sh3/sh3/lock_stubs.S b/sys/arch/sh3/sh3/lock_stubs.S index b0c1ccf3c4d3..f532ddac5732 100644 --- a/sys/arch/sh3/sh3/lock_stubs.S +++ b/sys/arch/sh3/sh3/lock_stubs.S @@ -1,4 +1,4 @@ -/* $NetBSD: lock_stubs.S,v 1.8 2007/03/14 06:42:46 uwe Exp $ */ +/* $NetBSD: lock_stubs.S,v 1.9 2007/09/24 01:17:15 uwe Exp $ */ /* * Copyright (c) 2007 Valeriy E. Ushakov @@ -45,7 +45,7 @@ * Atomic compare-and-swap for kernel use. SuperH machines are * uniprocessor, so we need to be atomic only w.r.t. interrupts. * Implement this as (the only in-kernel) RAS, with restart check - * done in ast() on return from interrupt. + * done on return from interrupt. * * Mutex stubs below depend on this function: * r4 - preserved, passed along to mutex_vector_{enter,exit}