Linux MIPS Architecture development
 help / color / mirror / Atom feed
From: Jun Sun <jsun@mvista.com>
To: Carsten Langgaard <carstenl@mips.com>, ralf@oss.sgi.com
Cc: vhouten@kpn.com, linux-mips@oss.sgi.com
Subject: Re: Illegal instruction
Date: Fri, 06 Jul 2001 15:04:43 -0700	[thread overview]
Message-ID: <3B4635FB.1ED5D222@mvista.com> (raw)
In-Reply-To: 3B4573B8.9F89022B@mips.com

[-- Attachment #1: Type: text/plain, Size: 951 bytes --]

Carsten Langgaard wrote:
> 
> Hi Karel,
> 
> I have tried the root-images tar-files: mipselroot-rh7-20010606 and
> mipsroot-rh7.
> The mipsroot-rh7 (bigendian) root image seem to work fine, but when
> I use the mipselroot-rh7-20010606 (littleendian) I get an illegal
> instruction.
> [cat:179] Illegal instruction 7c010001 at 2ac8b20c ra=00000000.
> 
> I'm using a 2.4.3 kernel.
> Anyone got an idea ?
> 
> /Carsten
> 

Is the userland compiled with MIPS I option?  I bet this is the same nasty
MIPS_ATOMIC_SET bug.

Currently, there are three fixes.  One is from Florian, which only takes care
of CPUs with ll/sc.  Another is from Maceij, which introduces a new syscall,
and some changes in glibc.  The thrid is mine, a compromising one.  It takes
care of both ll/sc case and non-llsc case, has minimum change, and practically
makes all programs happy.

Ralf, please take at least one of the fixes.  Even a not-so-good fix is better
than no fix.

Jun

[-- Attachment #2: MIPS_ATOMIC_SET-compromising-fix.010626.010626.pathc --]
[-- Type: text/plain, Size: 3935 bytes --]


This is a compromising fix for sysmips(MIPS_ATOMIC_SET, ...).  It
forces SIGSYS when the return value is a small negative value.  This
limit is OK for glibc.

Jun

diff -Nru linux/arch/mips/kernel/sysmips.c.orig linux/arch/mips/kernel/sysmips.c
--- linux/arch/mips/kernel/sysmips.c.orig	Mon Apr 23 11:32:54 2001
+++ linux/arch/mips/kernel/sysmips.c	Tue Jun 26 11:50:48 2001
@@ -16,7 +16,7 @@
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <linux/utsname.h>
-
+#include <linux/signal.h>
 #include <asm/cachectl.h>
 #include <asm/pgalloc.h>
 #include <asm/sysmips.h>
@@ -75,53 +75,83 @@
 	}
 
 	case MIPS_ATOMIC_SET: {
-#ifdef CONFIG_CPU_HAS_LLSC
-		unsigned int tmp;
+		int *ptr, val, ret, err, tmp;
+		struct siginfo info;
 
-		p = (int *) arg1;
-		errno = verify_area(VERIFY_WRITE, p, sizeof(*p));
-		if (errno)
-			return errno;
-		errno = 0;
-
-		__asm__(".set\tpush\t\t\t# sysmips(MIPS_ATOMIC, ...)\n\t"
-			".set\tmips2\n\t"
-			".set\tnoat\n\t"
-			"1:\tll\t%0, %4\n\t"
-			"move\t$1, %3\n\t"
-			"2:\tsc\t$1, %1\n\t"
-			"beqz\t$1, 1b\n\t"
-			".set\tpop\n\t"
-			".section\t.fixup,\"ax\"\n"
-			"3:\tli\t%2, 1\t\t\t# error\n\t"
-			".previous\n\t"
-			".section\t__ex_table,\"a\"\n\t"
-			".word\t1b, 3b\n\t"
-			".word\t2b, 3b\n\t"
-			".previous\n\t"
-			: "=&r" (tmp), "=o" (* (u32 *) p), "=r" (errno)
-			: "r" (arg2), "o" (* (u32 *) p), "2" (errno)
-			: "$1");
+		ptr = (int *)arg1;
+		val = (int)arg2;
 
-		if (errno)
-			return -EFAULT;
+		/* Don't emulate unaligned accesses. */
+		if ((int)ptr & 3) {
+			info.si_signo = SIGBUS;
+                        info.si_code = BUS_ADRALN;
+			goto fault;
+		}
+
+		/* A zero here saves us three instructions. */
+		err = verify_area(VERIFY_WRITE, ptr, 0);
+		if (err) {
+                        info.si_signo = SIGSEGV;
+			info.si_code = SEGV_ACCERR;
+			goto fault;
+		}
 
-		/* We're skipping error handling etc.  */
-		if (current->ptrace & PT_TRACESYS)
-			syscall_trace();
-
-		((struct pt_regs *)&cmd)->regs[2] = tmp;
-		((struct pt_regs *)&cmd)->regs[7] = 0;
-
-		__asm__ __volatile__(
-			"move\t$29, %0\n\t"
-			"j\to32_ret_from_sys_call"
-			: /* No outputs */
-			: "r" (&cmd));
-		/* Unreached */
+#ifdef CONFIG_CPU_HAS_LLSC
+		__asm__(".set   mips2\n\t"
+			"1:\n\t"
+			"ll     %0,%5\n\t"
+	                ".set   push\n\t"
+	                ".set   noreorder\n\t"
+	                "beq    %0,%4,3f\n\t"
+	                " move  %3,%4\n"
+	                ".set   pop\n\t"
+	                "2:\n\t"
+	                "sc     %3,%1\n\t"
+	                "beqz   %3,1b\n\t"
+	                "3:\n\t"
+	                ".set   mips0\n\t"
+	                ".section .fixup,\"ax\"\n"
+	                "4:\n\t"
+	                "li     %2,%7\n\t"
+	                "j      3b\n\t"
+	                ".previous\n\t"
+	                ".section __ex_table,\"a\"\n\t"
+	                ".word  1b,4b\n\t"
+	                ".word  2b,4b\n\t"
+	                ".previous"
+	                : "=&r" (ret), "=R" (*ptr), "=r" (err), "=&r" (tmp)
+	                : "r" (val), "1" (*ptr), "2" (0), "i" (-EFAULT));
 #else
-	printk("sys_sysmips(MIPS_ATOMIC_SET, ...) not ready for !CONFIG_CPU_HAS_LLSC\n");
+		save_and_cli(tmp);
+		err = __get_user(ret, ptr);
+		if (ret != val)
+		err |= __put_user(val, ptr);    /* No fault
+                                                   unless unwriteable. */
+		restore_flags(tmp);
 #endif
+
+		if (err) {
+                        info.si_signo = SIGSEGV;
+			info.si_code = SEGV_MAPERR;
+			goto fault;
+		}
+			
+		if ( (ret < 0) && (ret >= -EMAXERRNO) ) {
+                        info.si_signo = SIGSYS;
+			info.si_code = 0;
+			goto fault;
+		}
+			
+		return ret;
+
+fault:
+		/* Go back to SYSCALL. */
+		((struct pt_regs *)&cmd)->cp0_epc -= 4;
+
+		info.si_addr = (void *)((struct pt_regs *)&cmd)->cp0_epc;
+		force_sig_info(info.si_signo, &info, current);
+
+		return 0;
 	}
 
 	case MIPS_FIXADE:

[-- Attachment #3: flo-fast-sysmips.0105X.X.patch --]
[-- Type: text/plain, Size: 4595 bytes --]

diff -Nur linux.orig/arch/mips/kernel/Makefile linux/arch/mips/kernel/Makefile
--- linux.orig/arch/mips/kernel/Makefile        Mon Apr  9 00:23:08 2001
+++ linux/arch/mips/kernel/Makefile     Mon Apr  9 00:23:34 2001
@@ -20,7 +20,7 @@
 obj-y                          += branch.o process.o signal.o entry.o \
                                   traps.o ptrace.o vm86.o ioport.o reset.o \
                                   semaphore.o setup.o syscall.o sysmips.o \
-                                  ipc.o scall_o32.o unaligned.o
+                                  ipc.o scall_o32.o unaligned.o fast-sysmips.o
 obj-$(CONFIG_MODULES)          += mips_ksyms.o

 ifdef CONFIG_CPU_R3000
@@ -69,5 +69,6 @@

 entry.o: entry.S
 head.o: head.S
+fast-sysmips.o: fast-sysmips.S

 include $(TOPDIR)/Rules.make
diff -Nur linux.orig/arch/mips/kernel/fast-sysmips.S linux/arch/mips/kernel/fast-sysmips.S
--- linux.orig/arch/mips/kernel/fast-sysmips.S  Thu Jan  1 01:00:00 1970
+++ linux/arch/mips/kernel/fast-sysmips.S       Mon Apr  9 00:28:20 2001
@@ -0,0 +1,85 @@
+/*
+ * MIPS_ATOMIC_SET asm implementation for ll/sc capable cpus
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2001 Florian Lohoff <flo@rfc822.org>
+ *
+ */
+#include <asm/asm.h>
+#include <asm/mipsregs.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/isadep.h>
+#include <asm/unistd.h>
+#include <asm/sysmips.h>
+#include <asm/offset.h>
+#include <asm/errno.h>
+
+#define PT_TRACESYS     0x00000002
+
+       EXPORT(fast_sysmips)
+
+       .set    noreorder
+
+       li      t0, MIPS_ATOMIC_SET
+       beq     a0, t0, 1f
+        nop
+       j       sys_sysmips
+        nop
+
+1:
+
+       # a0 - MIPS_ATOMIC_SET
+       # a1 - mem ptr
+       # a2 - value
+
+       addiu   sp, sp, -8                      # Reserve space
+       sw      a0, (sp)                        # Save arg0
+
+       addiu   a0, a1, 4                       # addr+size
+       ori     v0, a1, 4                       # addr | size
+       lw      v1, THREAD_CURDS(gp)            # current->thread.current_ds
+       or      v0, v0, a0                      # addr | size | (addr+size)
+       and     v1, v1, v0                      # (mask)&(addr | size | (addr+size)
+       bltz    v1, 5f
+        nop
+
+2:
+       ll      v0, (a1)
+       move    t0, a2
+       sc      t0, (a1)
+       beqz    t0, 2b
+        nop
+
+       sw      v0, PT_R2+8(sp)                 # Result value
+       sw      zero, PT_R7+8(sp)               # Success indicator
+
+       lw      t0, TASK_PTRACE(gp)             # syscall tracing enabled?
+       andi    t0, PT_TRACESYS
+       bnez    t0, 3f
+        nop
+
+4:
+       lw      a0, (sp)                        # Restore arg0
+       addiu   sp, sp, 8                       # Restore sp
+
+       j       o32_ret_from_sys_call
+        nop
+
+3:
+       sw      ra, 4(sp)
+       jal     syscall_trace
+        nop
+       lw      ra, 4(sp)
+       j       4b
+        nop
+
+5:
+       lw      a0, (sp)                        # Restore arg0
+       addiu   sp, sp, 8                       # Restore sp
+       j       ra
+        li     v0, -EFAULT
+
diff -Nur linux.orig/arch/mips/kernel/irix5sys.h linux/arch/mips/kernel/irix5sys.h
--- linux.orig/arch/mips/kernel/irix5sys.h      Mon Apr  9 00:16:29 2001
+++ linux/arch/mips/kernel/irix5sys.h   Sun Apr  8 21:21:16 2001
@@ -69,7 +69,7 @@
 SYS(irix_getgid, 0)                    /* 1047  getgid()              V*/
 SYS(irix_unimp, 0)                     /* 1048  (XXX IRIX 4 ssig)     V*/
 SYS(irix_msgsys, 6)                    /* 1049  sys_msgsys            V*/
-SYS(sys_sysmips, 4)                    /* 1050  sysmips()            HV*/
+SYS(fast_sysmips, 4)                   /* 1050  sysmips()            HV*/
 SYS(irix_unimp, 0)                     /* 1051  XXX sysacct()        IV*/
 SYS(irix_shmsys, 5)                    /* 1052  sys_shmsys            V*/
 SYS(irix_semsys, 0)                    /* 1053  sys_semsys            V*/
diff -Nur linux.orig/arch/mips/kernel/syscalls.h linux/arch/mips/kernel/syscalls.h
--- linux.orig/arch/mips/kernel/syscalls.h      Mon Apr  9 00:16:30 2001
+++ linux/arch/mips/kernel/syscalls.h   Sun Apr  8 21:21:43 2001
@@ -163,7 +163,7 @@
 SYS(sys_writev, 3)
 SYS(sys_cacheflush, 3)
 SYS(sys_cachectl, 3)
-SYS(sys_sysmips, 4)
+SYS(fast_sysmips, 4)
 SYS(sys_ni_syscall, 0)                         /* 4150 */
 SYS(sys_getsid, 1)
 SYS(sys_fdatasync, 0)


  parent reply	other threads:[~2001-07-06 22:13 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-07-06  8:15 Illegal instruction Carsten Langgaard
2001-07-06  9:27 ` Houten K.H.C. van (Karel)
2001-07-06 11:42   ` Maciej W. Rozycki
2001-07-06 13:26 ` Dan Aizenstros
2001-07-06 22:04 ` Jun Sun [this message]
2001-07-10 11:14   ` Carsten Langgaard
2001-07-10 17:31     ` H . J . Lu
2001-07-16 11:26       ` Carsten Langgaard
2001-07-16 21:28         ` Updates on RedHat 7.1/mips H . J . Lu
2001-07-17 19:16           ` Carsten Langgaard
2001-07-17 19:29             ` H . J . Lu
2001-07-17 19:50               ` Daniel Jacobowitz
2001-07-17 19:57                 ` H . J . Lu
2001-07-17 20:09                   ` Ilya Volynets
2001-07-17 20:11                     ` H . J . Lu
2001-07-18  3:52                       ` Arnaldo Carvalho de Melo
2001-07-18  4:01                         ` Ilya Volynets
2001-07-18  7:13               ` Carsten Langgaard
2001-07-18 15:11                 ` H . J . Lu
2001-07-18 15:23                   ` Carsten Langgaard
2001-07-18 20:53                     ` Seth Mos
2001-07-19  0:36                       ` H . J . Lu
2001-07-19 21:03                         ` Seth Mos

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3B4635FB.1ED5D222@mvista.com \
    --to=jsun@mvista.com \
    --cc=carstenl@mips.com \
    --cc=linux-mips@oss.sgi.com \
    --cc=ralf@oss.sgi.com \
    --cc=vhouten@kpn.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox