68030 and 68040 processors consider the read portion of a read-modify-write

transfer as a write to ensure the memory is writable before starting any
transfer.  The fault status information does not reflect this in the 'read'
status bit (i.e. it shows up as a read access), so faults with a RMW access
to non-writable memory was not getting the correct protection.  The page would
be read-only and the instruction would fault over and over.

A specific example is when a process forks, and the child process attempts
to execute a RMW access to a data page, which is read-only because it's CoP
Copy-On-Write.

When checking if the page needs to be writablek, also check the locked transfer
and treat any locked transfer as a write.

68060 already handled this correctly, since it has separate read and write
fault bits, and both are set on a RMW access and the trap code was checking
the write status bit.

Fixes PR#36848.
This commit is contained in:
mhitch 2007-09-01 21:31:55 +00:00
parent e7c76ac0ee
commit 9b0f085da1
11 changed files with 61 additions and 48 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.115 2007/06/12 03:34:45 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.116 2007/09/01 21:31:55 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@ -83,7 +83,7 @@
#include "opt_fpu_emulate.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.115 2007/06/12 03:34:45 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.116 2007/09/01 21:31:55 mhitch Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -407,9 +407,9 @@ trapmmufault(type, code, v, fp, l, sticks)
#ifdef M68060
machineid & AMIGA_68060 ? code & FSLW_RW_W :
#endif
mmutype == MMU_68040 ? (code & SSW_RW040) == 0 :
(code & (SSW_DF|SSW_RW)) == SSW_DF)
/* what about RMW? */
mmutype == MMU_68040 ? (code & (SSW_LK|SSW_RW040)) != SSW_RW040 :
((code & SSW_DF) != 0 &&
((code & SSW_RW) == 0 || (code & SSW_RM) != 0)))
ftype = VM_PROT_WRITE;
else
ftype = VM_PROT_READ;

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.91 2007/06/12 03:35:17 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.92 2007/09/01 21:31:55 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990 The Regents of the University of California.
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.91 2007/06/12 03:35:17 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.92 2007/09/01 21:31:55 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -182,7 +182,7 @@ short exframesize[] = {
#define KDFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_RW) == 0)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#else
#define KDFAULT_040(c) 0
#define WRFAULT_040(c) 0
@ -192,7 +192,8 @@ short exframesize[] = {
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT_OTH(c) 0
#define WRFAULT_OTH(c) 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.35 2007/06/12 03:34:30 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.36 2007/09/01 21:31:55 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.35 2007/06/12 03:34:30 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.36 2007/09/01 21:31:55 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -189,7 +189,7 @@ short exframesize[] = {
#define KDFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_RW) == 0)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#else
#define KDFAULT_040(c) 0
#define WRFAULT_040(c) 0
@ -199,7 +199,8 @@ short exframesize[] = {
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT_OTH(c) 0
#define WRFAULT_OTH(c) 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.131 2007/06/12 03:35:33 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.132 2007/09/01 21:31:55 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.131 2007/06/12 03:35:33 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.132 2007/09/01 21:31:55 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -179,7 +179,7 @@ short exframesize[] = {
#define KDFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_RW) == 0)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#else
#define KDFAULT_040(c) 0
#define WRFAULT_040(c) 0
@ -189,7 +189,8 @@ short exframesize[] = {
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT_OTH(c) 0
#define WRFAULT_OTH(c) 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.46 2007/06/12 03:34:30 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.47 2007/09/01 21:31:55 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -78,7 +78,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.46 2007/06/12 03:34:30 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.47 2007/09/01 21:31:55 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@ -163,11 +163,13 @@ short exframesize[] = {
((c) & SSW4_TMMASK) == SSW4_TMKD : \
((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))
#define WRFAULT(c) (mmutype == MMU_68040 ? \
((c) & SSW4_RW) == 0 : \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW : \
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
#define WRFAULT(c) (((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0)))
#endif
#ifdef DEBUG

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.128 2007/06/12 03:34:31 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.129 2007/09/01 21:31:56 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.128 2007/06/12 03:34:31 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.129 2007/09/01 21:31:56 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -165,11 +165,13 @@ short exframesize[] = {
((c) & SSW4_TMMASK) == SSW4_TMKD : \
((c) & (SSW_DF|FC_SUPERD)) == (SSW_DF|FC_SUPERD))
#define WRFAULT(c) (mmutype == MMU_68040 ? \
((c) & SSW4_RW) == 0 : \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW : \
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
#define WRFAULT(c) (((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0)))
#endif
#ifdef DEBUG

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.90 2007/06/12 03:34:31 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.91 2007/09/01 21:31:56 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.90 2007/06/12 03:34:31 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.91 2007/09/01 21:31:56 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -189,10 +189,10 @@ short exframesize[] = {
#define KDFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_RW) == 0)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#else
#define KDFAULT_040(c) (((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (((c) & SSW4_RW) == 0)
#define WRFAULT_040(c) (((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#endif
#else
#define KDFAULT_040(c) 0
@ -204,10 +204,12 @@ short exframesize[] = {
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT_OTH(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
#define WRFAULT_OTH(c) (((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0)))
#endif
#else
#define KDFAULT_OTH(c) 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.53 2007/06/12 03:37:22 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.54 2007/09/01 21:31:56 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.53 2007/06/12 03:37:22 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.54 2007/09/01 21:31:56 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -176,7 +176,7 @@ short exframesize[] = {
#define KDFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_RW) == 0)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#else
#define KDFAULT_040(c) 0
#define WRFAULT_040(c) 0
@ -186,7 +186,8 @@ short exframesize[] = {
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT_OTH(c) 0
#define WRFAULT_OTH(c) 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.67 2007/06/12 03:34:32 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.68 2007/09/01 21:31:56 mhitch Exp $ */
/*
* This file was taken from mvme68k/mvme68k/trap.c
@ -84,7 +84,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.67 2007/06/12 03:34:32 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.68 2007/09/01 21:31:56 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -192,7 +192,7 @@ short exframesize[] = {
#define KDFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_RW) == 0)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#else
#define KDFAULT_040(c) 0
#define WRFAULT_040(c) 0
@ -202,7 +202,8 @@ short exframesize[] = {
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT_OTH(c) 0
#define WRFAULT_OTH(c) 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.130 2007/06/12 03:34:33 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.131 2007/09/01 21:31:56 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -78,7 +78,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.130 2007/06/12 03:34:33 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.131 2007/09/01 21:31:56 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_execfmt.h"
@ -192,7 +192,8 @@ short exframesize[] = {
};
#define KDFAULT(c) (((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT(c) (((c) & (SSW_DF|SSW_RW)) == SSW_DF)
#define WRFAULT(c) (((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0)))
/* #define DEBUG XXX */

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.89 2007/06/12 03:34:33 mhitch Exp $ */
/* $NetBSD: trap.c,v 1.90 2007/09/01 21:31:57 mhitch Exp $ */
/*
* Copyright (c) 1982, 1986, 1990, 1993
@ -77,7 +77,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.89 2007/06/12 03:34:33 mhitch Exp $");
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.90 2007/09/01 21:31:57 mhitch Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@ -187,7 +187,7 @@ short exframesize[] = {
#define KDFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_TMMASK) == SSW4_TMKD)
#define WRFAULT_040(c) (cputype == CPU_68040 && \
((c) & SSW4_RW) == 0)
((c) & (SSW4_LK|SSW4_RW)) != SSW4_RW)
#else
#define KDFAULT_040(c) 0
#define WRFAULT_040(c) 0
@ -197,7 +197,8 @@ short exframesize[] = {
#define KDFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_FCMASK)) == (SSW_DF|FC_SUPERD))
#define WRFAULT_OTH(c) (cputype <= CPU_68030 && \
((c) & (SSW_DF|SSW_RW)) == SSW_DF)
(((c) & SSW_DF) != 0 && \
((((c) & SSW_RW) == 0) || (((c) & SSW_RM) != 0))))
#else
#define KDFAULT_OTH(c) 0
#define WRFAULT_OTH(c) 0