Subject: SunOS emul fix for 040s
To: None <port-m68k@NetBSD.ORG>
From: Niklas Hallqvist <niklas@cvs.openbsd.org>
List: port-m68k
Date: 11/28/1995 14:19:52
As Sun didn't know about the 040's split I/D cache when writing their ld.so
some cache purging is missing there for correct functionality of SunOS
emulation in NetBSD. In order to fix this, we can either make our ld.so handle
SunOS dynamic binaries, or make writeable executable pages uncached for
SunOS processes. This patch does the latter for the amiga. Other ports
can do similarily...
Niklas
Index: arch/amiga/amiga/pmap.c
===================================================================
RCS file: /cvs/src/sys/arch/amiga/amiga/pmap.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -c -b -r1.2 -r1.3
*** pmap.c 1995/11/13 03:53:32 1.2
--- pmap.c 1995/11/28 20:47:34 1.3
***************
*** 1390,1398 ****
* AMIGA pages in a MACH page.
*/
#ifdef M68040
! if (mmutype == MMU_68040 && pmap == pmap_kernel() && va >= AMIGA_UPTBASE &&
! va < (AMIGA_UPTBASE + AMIGA_UPTMAXSIZE))
cacheable = FALSE; /* don't cache user page tables */
#endif
npte = (pa & PG_FRAME) | pte_prot(pmap, prot) | PG_V;
npte |= (*(int *)pte & (PG_M|PG_U));
--- 1390,1404 ----
* AMIGA pages in a MACH page.
*/
#ifdef M68040
! if (mmutype == MMU_68040 && pmap == pmap_kernel() &&
! va >= AMIGA_UPTBASE && va < (AMIGA_UPTBASE + AMIGA_UPTMAXSIZE))
cacheable = FALSE; /* don't cache user page tables */
+
+ /* Don't cache if process can't take it, like SunOS ones. */
+ if (mmutype == MMU_68040 && pmap != pmap_kernel() &&
+ (curproc->p_md.md_flags & MDP_UNCACHE_WX) &&
+ (prot & VM_PROT_EXECUTE) && (prot & VM_PROT_WRITE))
+ checkpv = cacheable = FALSE;
#endif
npte = (pa & PG_FRAME) | pte_prot(pmap, prot) | PG_V;
npte |= (*(int *)pte & (PG_M|PG_U));
Index: arch/amiga/include/proc.h
===================================================================
RCS file: /cvs/src/sys/arch/amiga/include/proc.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -b -r1.1.1.1 -r1.2
*** proc.h 1995/10/18 08:50:04 1.1.1.1
--- proc.h 1995/11/28 20:48:49 1.2
***************
*** 50,53 ****
--- 50,55 ----
#define MDP_STACKADJ 0x0002 /* frame SP adjusted, might have to
undo when system call returns
ERESTART. */
+ #define MDP_UNCACHE_WX 0x0004 /* The process might modify code, so
+ don't cache writeable executable pages. */
#endif /* !_MACHINE_PROC_H_ */
Index: arch/m68k/m68k/sunos_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/m68k/m68k/sunos_machdep.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -b -r1.1.1.1 -r1.2
*** sunos_machdep.c 1995/10/18 08:51:01 1.1.1.1
--- sunos_machdep.c 1995/11/28 20:44:54 1.2
***************
*** 86,91 ****
--- 86,107 ----
struct sunos_sigcontext sf_sc; /* I don't know if that's what
comes here */
};
+
+ /*
+ * SunOS' ld.so does self-modifying code without knowing about the 040's
+ * cache purging needs. So we need to uncache writeable executable pages.
+ */
+ void
+ sunos_setregs(p, pack, stack, retval)
+ register struct proc *p;
+ struct exec_package *pack;
+ u_long stack;
+ register_t *retval;
+ {
+ setregs(p, pack, stack, retval);
+ p->p_md.md_flags |= MDP_UNCACHE_WX;
+ }
+
/*
* much simpler sendsig() for SunOS processes, as SunOS does the whole
* context-saving in usermode. For now, no hardware information (ie.
Index: compat/sunos/sunos_exec.c
===================================================================
RCS file: /cvs/src/sys/compat/sunos/sunos_exec.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -b -r1.1.1.1 -r1.2
*** sunos_exec.c 1995/10/18 08:52:21 1.1.1.1
--- sunos_exec.c 1995/11/28 20:43:08 1.2
***************
*** 68,73 ****
--- 68,77 ----
extern char *sunos_syscallnames[];
#endif
extern void sunos_sendsig __P((sig_t, int, int, u_long));
+ #ifdef m68k
+ extern void sunos_setregs __P((struct proc *, struct exec_package *, u_long,
+ register_t *));
+ #endif
extern char sigcode[], esigcode[];
const char sunos_emul_path[] = "/emul/sunos";
***************
*** 89,95 ****
--- 93,103 ----
#endif
0,
copyargs,
+ #ifdef m68k
+ sunos_setregs,
+ #else
setregs,
+ #endif
sigcode,
esigcode,
};