Do RAS check in sh_vector_interrupt, don't abuse ast() for that.
This commit is contained in:
parent
74c326b877
commit
609dd932e5
@ -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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc. All rights reserved.
|
||||||
@ -79,7 +79,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__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_ddb.h"
|
||||||
#include "opt_kgdb.h"
|
#include "opt_kgdb.h"
|
||||||
@ -432,12 +432,6 @@ ast(struct lwp *l, struct trapframe *tf)
|
|||||||
{
|
{
|
||||||
|
|
||||||
if (KERNELMODE(tf->tf_ssr)) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* Copyright (c) 2002 The NetBSD Foundation, Inc.
|
||||||
@ -53,7 +53,7 @@
|
|||||||
#define _ALIGN_TEXT .align 5
|
#define _ALIGN_TEXT .align 5
|
||||||
#include <sh3/asm.h>
|
#include <sh3/asm.h>
|
||||||
|
|
||||||
__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
|
mov.l .Li_intc_intr, r0
|
||||||
jsr @r0 /* intc_intr(ssr, spc, ssp) */
|
jsr @r0 /* intc_intr(ssr, spc, ssp) */
|
||||||
nop
|
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. */
|
/* Check for ASTs on exit to user mode. */
|
||||||
mov.l .Li_curlwp, r0
|
mov.l .Li_curlwp, r0
|
||||||
mov.l @r0, r4 /* 1st arg */
|
mov.l @r0, r4 /* 1st arg */
|
||||||
mov.l .Li_ast, r0
|
mov.l .Li_ast, r0
|
||||||
jsr @r0
|
jsr @r0
|
||||||
mov r14, r5 /* 2nd arg */
|
mov r14, r5 /* 2nd arg */
|
||||||
|
|
||||||
|
.Li_return_from_interrupt:
|
||||||
__EXCEPTION_RETURN
|
__EXCEPTION_RETURN
|
||||||
|
|
||||||
.align 5
|
.align 5
|
||||||
@ -480,6 +502,10 @@ NENTRY(sh_vector_interrupt)
|
|||||||
.Li_intc_intr: .long _C_LABEL(intc_intr)
|
.Li_intc_intr: .long _C_LABEL(intc_intr)
|
||||||
.Li_ast: .long _C_LABEL(ast)
|
.Li_ast: .long _C_LABEL(ast)
|
||||||
.Li_uvmexp_intrs: .long _C_LABEL(uvmexp) + UVMEXP_INTRS
|
.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]; */
|
/* LINTSTUB: Var: char sh_vector_interrupt_end[1]; */
|
||||||
VECTOR_END_MARKER(sh_vector_interrupt_end)
|
VECTOR_END_MARKER(sh_vector_interrupt_end)
|
||||||
|
@ -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
|
* Copyright (c) 2007 Valeriy E. Ushakov
|
||||||
@ -45,7 +45,7 @@
|
|||||||
* Atomic compare-and-swap for kernel use. SuperH machines are
|
* Atomic compare-and-swap for kernel use. SuperH machines are
|
||||||
* uniprocessor, so we need to be atomic only w.r.t. interrupts.
|
* uniprocessor, so we need to be atomic only w.r.t. interrupts.
|
||||||
* Implement this as (the only in-kernel) RAS, with restart check
|
* 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:
|
* Mutex stubs below depend on this function:
|
||||||
* r4 - preserved, passed along to mutex_vector_{enter,exit}
|
* r4 - preserved, passed along to mutex_vector_{enter,exit}
|
||||||
|
Loading…
Reference in New Issue
Block a user