All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] MIPS: Get ready for non-executable stack.
@ 2014-12-03 23:44 David Daney
  2014-12-03 23:44 ` [PATCH 1/3] MIPS: Add FPU emulator counter for non-FPU instructions emulated David Daney
                   ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: David Daney @ 2014-12-03 23:44 UTC (permalink / raw)
  To: linux-mips, ralf
  Cc: Leonid Yegoshin, Zubair.Kakakhel, geert+renesas, peterz,
	paul.gortmaker, macro, chenhc, cl, mingo, richard, zajec5,
	james.hogan, keescook, tj, alex, pbonzini, blogic, paul.burton,
	qais.yousef, linux-kernel, markos.chandras, dengcheng.zhu,
	manuel.lauss, lars.persson, David Daney

From: David Daney <david.daney@cavium.com>

Currently the MIPS FPU emulator uses eXecute Out of Line (XOL) on the
stack to handle instructions in the delay slots of FPU branches.
Because of this MIPS cannot have a non-executable stack.

A previous patch set from Leonid Yegoshin attempts to address the
problem by moving the XOL location to a thread private mapping of a
dedicated page.

I present here an alternative: Add an instruction set emulator and use
it to execute the FPU delay slot instructions.  The benefit of this
approach is that we don't have to allocate a page per user-space
thread for XOL, and we keep the TLB handling code slightly simpler as
a result.

Currently this is a proof of concept, as it doesn't yet handle MIPS64
nor microMIPS instructions.  But it is sufficient to run the entire
Debian distribution on a FPU-less CPU.

Comments welcome.

David Daney (3):
  MIPS: Add FPU emulator counter for non-FPU instructions emulated.
  MIPS: Add full ISA emulator.
  MIPS: Use full instruction emulation for FPU emulator delay slot
    emulation.

 arch/mips/include/asm/fpu_emulator.h |   1 +
 arch/mips/kernel/Makefile            |   3 +-
 arch/mips/kernel/insn-emul.c         | 815 +++++++++++++++++++++++++++++++++++
 arch/mips/math-emu/cp1emu.c          |  13 +-
 arch/mips/math-emu/me-debugfs.c      |   1 +
 5 files changed, 830 insertions(+), 3 deletions(-)
 create mode 100644 arch/mips/kernel/insn-emul.c

-- 
1.7.11.7


^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH 1/3] MIPS: Add FPU emulator counter for non-FPU instructions emulated.
  2014-12-03 23:44 [PATCH 0/3] MIPS: Get ready for non-executable stack David Daney
@ 2014-12-03 23:44 ` David Daney
  2014-12-03 23:44 ` [PATCH 2/3] MIPS: Add full ISA emulator David Daney
  2014-12-03 23:44 ` [PATCH 3/3] MIPS: Use full instruction emulation for FPU emulator delay slot emulation David Daney
  2 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-03 23:44 UTC (permalink / raw)
  To: linux-mips, ralf
  Cc: Leonid Yegoshin, Zubair.Kakakhel, geert+renesas, peterz,
	paul.gortmaker, macro, chenhc, cl, mingo, richard, zajec5,
	james.hogan, keescook, tj, alex, pbonzini, blogic, paul.burton,
	qais.yousef, linux-kernel, markos.chandras, dengcheng.zhu,
	manuel.lauss, lars.persson, David Daney

From: David Daney <david.daney@cavium.com>

Used in follow-on patch, the counter is called "insn_emul".

Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/mips/include/asm/fpu_emulator.h | 1 +
 arch/mips/math-emu/me-debugfs.c      | 1 +
 2 files changed, 2 insertions(+)

diff --git a/arch/mips/include/asm/fpu_emulator.h b/arch/mips/include/asm/fpu_emulator.h
index 6370c82..bd5b63f 100644
--- a/arch/mips/include/asm/fpu_emulator.h
+++ b/arch/mips/include/asm/fpu_emulator.h
@@ -45,6 +45,7 @@ struct mips_fpu_emulator_stats {
 	unsigned long ieee754_zerodiv;
 	unsigned long ieee754_invalidop;
 	unsigned long ds_emul;
+	unsigned long insn_emul;
 };
 
 DECLARE_PER_CPU(struct mips_fpu_emulator_stats, fpuemustats);
diff --git a/arch/mips/math-emu/me-debugfs.c b/arch/mips/math-emu/me-debugfs.c
index f308e0f..93fc155 100644
--- a/arch/mips/math-emu/me-debugfs.c
+++ b/arch/mips/math-emu/me-debugfs.c
@@ -62,6 +62,7 @@ do {									\
 	FPU_STAT_CREATE(ieee754_zerodiv);
 	FPU_STAT_CREATE(ieee754_invalidop);
 	FPU_STAT_CREATE(ds_emul);
+	FPU_STAT_CREATE(insn_emul);
 
 	return 0;
 }
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 2/3] MIPS: Add full ISA emulator.
  2014-12-03 23:44 [PATCH 0/3] MIPS: Get ready for non-executable stack David Daney
  2014-12-03 23:44 ` [PATCH 1/3] MIPS: Add FPU emulator counter for non-FPU instructions emulated David Daney
@ 2014-12-03 23:44 ` David Daney
  2014-12-03 23:55     ` Leonid Yegoshin
  2014-12-03 23:44 ` [PATCH 3/3] MIPS: Use full instruction emulation for FPU emulator delay slot emulation David Daney
  2 siblings, 1 reply; 22+ messages in thread
From: David Daney @ 2014-12-03 23:44 UTC (permalink / raw)
  To: linux-mips, ralf
  Cc: Leonid Yegoshin, Zubair.Kakakhel, geert+renesas, peterz,
	paul.gortmaker, macro, chenhc, cl, mingo, richard, zajec5,
	james.hogan, keescook, tj, alex, pbonzini, blogic, paul.burton,
	qais.yousef, linux-kernel, markos.chandras, dengcheng.zhu,
	manuel.lauss, lars.persson, David Daney

From: David Daney <david.daney@cavium.com>

Used in follow-on patch to replace FPU delay-slot instruction
execution on stack.

Only 32-bit instructions are emulated right now, still need to add
64-bit.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/mips/kernel/Makefile    |   3 +-
 arch/mips/kernel/insn-emul.c | 815 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 817 insertions(+), 1 deletion(-)
 create mode 100644 arch/mips/kernel/insn-emul.c

diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 008a2fe..b6e550d 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -6,7 +6,8 @@ extra-y		:= head.o vmlinux.lds
 
 obj-y		+= cpu-probe.o branch.o entry.o genex.o idle.o irq.o process.o \
 		   prom.o ptrace.o reset.o setup.o signal.o syscall.o \
-		   time.o topology.o traps.o unaligned.o watch.o vdso.o
+		   time.o topology.o traps.o unaligned.o watch.o vdso.o \
+		   insn-emul.o
 
 ifdef CONFIG_FUNCTION_TRACER
 CFLAGS_REMOVE_ftrace.o = -pg
diff --git a/arch/mips/kernel/insn-emul.c b/arch/mips/kernel/insn-emul.c
new file mode 100644
index 0000000..62e39e9
--- /dev/null
+++ b/arch/mips/kernel/insn-emul.c
@@ -0,0 +1,815 @@
+/*
+ * 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) 2014 Cavium, Inc.
+ */
+
+#include <asm/inst.h>
+#include <asm/ptrace.h>
+#include <asm/barrier.h>
+#include <asm/signal.h>
+#include <asm/uaccess.h>
+
+static int mips64_spec_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	return SIGILL;
+}
+
+static int mips_spec_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	union mips_instruction insn;
+	u32 rs32, rt32, rd32;
+	u64 t1_64, t2_64;
+	s64 t1_64s, t2_64s;
+	u32 t1_32, t2_32;
+	s32 t1_32s, t2_32s;
+	s32 rs32s, rt32s, rd32s;
+	int sa;
+
+	insn.word = ir;
+	switch (insn.r_format.func) {
+	case sll_op:
+		if (insn.r_format.rs != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result "NOP" */
+		rt32 = regs->regs[insn.r_format.rt];
+		sa = insn.r_format.re;
+		rd32 = rt32 << sa;
+		regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+		return 0;
+	case srl_op:
+		if (insn.r_format.rs == 0) {
+			/* SRL */
+			if (insn.r_format.rd == 0)
+				return 0; /* ignore result */
+			rt32 = regs->regs[insn.r_format.rt];
+			rd32 = rt32 >> insn.r_format.re;
+			regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+			return 0;
+		} else if (insn.r_format.rs == 1) {
+			/* ROTR */
+			if (insn.r_format.rd == 0)
+				return 0; /* ignore result */
+			rt32 = regs->regs[insn.r_format.rt];
+			sa = insn.r_format.re;
+			rd32 = (rt32 >> sa) | (rt32 << (32 - sa));
+			regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+			return 0;
+		}
+		return SIGILL;
+	case sra_op:
+		if (insn.r_format.rs != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rt32s = regs->regs[insn.r_format.rt];
+		sa = insn.r_format.re;
+		rd32s = rt32s >> sa;
+		regs->regs[insn.r_format.rd] = (long)rd32s;
+		return 0;
+	case sllv_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = regs->regs[insn.r_format.rt];
+		sa = rs32 & 0x1f;
+		rd32 = rt32 << sa;
+		regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+		return 0;
+	case srlv_op:
+		if (insn.r_format.re == 0) {
+			/* SRLV */
+			if (insn.r_format.rd == 0)
+				return 0; /* ignore result */
+			rs32 = regs->regs[insn.r_format.rs];
+			rt32 = regs->regs[insn.r_format.rt];
+			sa = rs32 & 0x1f;
+			rd32 = rt32 >> sa;
+			regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+			return 0;
+		} else if (insn.r_format.re == 1) {
+			/* ROTRV */
+			if (insn.r_format.rd == 0)
+				return 0; /* ignore result */
+			rs32 = regs->regs[insn.r_format.rs];
+			rt32 = regs->regs[insn.r_format.rt];
+			sa = rs32 & 0x1f;
+			rd32 = (rt32 >> sa) | (rt32 << (32 - sa));
+			regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+			return 0;
+		}
+		return SIGILL;
+	case srav_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32s = regs->regs[insn.r_format.rt];
+		sa = rs32 & 0x1f;
+		rd32s = rt32s >> sa;
+		regs->regs[insn.r_format.rd] = (long)rd32s;
+		return 0;
+	case movz_op:
+		if (insn.r_format.rs != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		if (regs->regs[insn.r_format.rt] == 0)
+			regs->regs[insn.r_format.rd] = regs->regs[insn.r_format.rs];
+		return 0;
+	case movn_op:
+		if (insn.r_format.rs != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		if (regs->regs[insn.r_format.rt] != 0)
+			regs->regs[insn.r_format.rd] = regs->regs[insn.r_format.rs];
+		return 0;
+	case sync_op:
+		mb(); /* an mb() is a SYNC */
+		return 0;
+	case mfhi_op:
+		if (insn.r_format.rs != 0 || insn.r_format.rt != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] = regs->hi;
+		return 0;
+	case mthi_op:
+		if (insn.r_format.rt != 0 || insn.r_format.rd != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			regs->hi = 0;
+		regs->hi = regs->regs[insn.r_format.rs];
+		return 0;
+	case mflo_op:
+		if (insn.r_format.rs != 0 || insn.r_format.rt != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] = regs->lo;
+		return 0;
+	case mtlo_op:
+		if (insn.r_format.rt != 0 || insn.r_format.rd != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			regs->lo = 0;
+		regs->lo = regs->regs[insn.r_format.rs];
+		return 0;
+	case mult_op:
+		if (insn.r_format.rd != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		rs32s = regs->regs[insn.r_format.rs];
+		rt32s = regs->regs[insn.r_format.rt];
+		t1_64s = rs32s;
+		t2_64s = rt32s;
+		t1_64s *= t2_64s;
+		t1_64 = t1_64s;
+		t1_32 = t1_64 >> 32;
+		t2_32 = t1_64 & 0xffffffffu;
+		regs->lo = (long)(s32)t2_32;
+		regs->hi = (long)(s32)t1_32;
+		return 0;
+	case multu_op:
+		if (insn.r_format.rd != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = regs->regs[insn.r_format.rt];
+		t1_64 = rs32;
+		t2_64 = rt32;
+		t1_64 *= t2_64;
+		t1_32 = t1_64 >> 32;
+		t2_32 = t1_64 & 0xffffffffu;
+		regs->lo = (long)(s32)t2_32;
+		regs->hi = (long)(s32)t1_32;
+		return 0;
+	case div_op:
+		if (insn.r_format.rd != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		rs32s = regs->regs[insn.r_format.rs];
+		rt32s = regs->regs[insn.r_format.rt];
+		if (rt32s == 0)
+			return 0; /* Undefined on div/zero, do nothing */
+		t1_32s = rs32s / rt32s;
+		t2_32s = rs32s % rt32s;
+		regs->lo = (long)t1_32s;
+		regs->hi = (long)t2_32s;
+		return 0;
+	case divu_op:
+		if (insn.r_format.rd != 0 || insn.r_format.re != 0)
+			return SIGILL;
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = regs->regs[insn.r_format.rt];
+		if (rt32 == 0)
+			return 0; /* Undefined on div/zero, do nothing */
+		t1_32 = rs32 / rt32;
+		t2_32 = rs32 % rt32;
+		regs->lo = (long)(s32)t1_32;
+		regs->hi = (long)(s32)t2_32;
+		return 0;
+	case addu_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = regs->regs[insn.r_format.rt];
+		rd32 = rs32 + rt32;
+		regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+		return 0;
+	case subu_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = regs->regs[insn.r_format.rt];
+		rd32 = rs32 - rt32;
+		regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+		return 0;
+	case and_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] =
+			regs->regs[insn.r_format.rs] & regs->regs[insn.r_format.rt];
+		return 0;
+	case or_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] =
+			regs->regs[insn.r_format.rs] | regs->regs[insn.r_format.rt];
+		return 0;
+	case xor_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] =
+			regs->regs[insn.r_format.rs] ^ regs->regs[insn.r_format.rt];
+		return 0;
+	case nor_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] =
+			~(regs->regs[insn.r_format.rs] | regs->regs[insn.r_format.rt]);
+		return 0;
+	case slt_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] =
+			((long)regs->regs[insn.r_format.rs]) < ((long)regs->regs[insn.r_format.rt]) ? 1 : 0;
+		return 0;
+	case sltu_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.r_format.rd] =
+			regs->regs[insn.r_format.rs] < regs->regs[insn.r_format.rt] ? 1 : 0;
+		return 0;
+	case dsllv_op:
+	case dsrlv_op:
+	case dsrav_op:
+	case dmult_op:
+	case dmultu_op:
+	case ddiv_op:
+	case ddivu_op:
+	case dadd_op:
+	case daddu_op:
+	case dsub_op:
+	case dsubu_op:
+	case dsll_op:
+	case dsrl_op:
+	case dsra_op:
+	case dsll32_op:
+	case dsrl32_op:
+	case dsra32_op:
+		return mips64_spec_emul(regs, ir);
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips_imm_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	union mips_instruction insn;
+	u32 rs32, rt32;
+	s32 rs32s;
+	u32 t1_32;
+	s32 t1_32s;
+	unsigned long t1;
+
+	insn.word = ir;
+	switch (insn.i_format.opcode) {
+	case addiu_op:
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.i_format.rs];
+		t1_32s = insn.i_format.simmediate;
+		t1_32 = t1_32s;
+		rt32 = rs32 + t1_32;
+		regs->regs[insn.i_format.rt] = (long)(s32)rt32;
+		return 0;
+	case slti_op:
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		rs32s = regs->regs[insn.i_format.rs];
+		t1_32s = insn.i_format.simmediate;
+		regs->regs[insn.i_format.rt] = rs32s > t1_32s ? 1 : 0;
+		return 0;
+	case sltiu_op:
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.i_format.rs];
+		t1_32s = insn.i_format.simmediate;
+		t1_32 = t1_32s;
+		regs->regs[insn.i_format.rt] = rs32 > t1_32 ? 1 : 0;
+		return 0;
+	case andi_op:
+		if (insn.u_format.rt == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.u_format.rs];
+		t1 = insn.u_format.uimmediate;
+		regs->regs[insn.u_format.rt] = t1 & regs->regs[insn.u_format.rs];
+		return 0;
+	case ori_op:
+		if (insn.u_format.rt == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.u_format.rs];
+		t1 = insn.u_format.uimmediate;
+		regs->regs[insn.u_format.rt] = t1 | regs->regs[insn.u_format.rs];
+		return 0;
+	case xori_op:
+		if (insn.u_format.rt == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.u_format.rs];
+		t1 = insn.u_format.uimmediate;
+		regs->regs[insn.u_format.rt] = t1 ^ regs->regs[insn.u_format.rs];
+		return 0;
+	case lui_op:
+		if (insn.u_format.rs != 0)
+			return SIGILL;
+		if (insn.u_format.rt == 0)
+			return 0; /* ignore result */
+		t1_32 = insn.u_format.uimmediate;
+		t1_32 <<= 16;
+		regs->regs[insn.u_format.rt] = (long)(s32)t1_32;
+		return 0;
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips64_imm_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	return SIGILL;
+}
+
+static int mips64_spec2_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	return SIGILL;
+}
+
+static int mips_spec2_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	union mips_instruction insn;
+	s32 rs32s, rt32s;
+	u32 rs32, rt32;
+	s64 t1_64s, t2_64s;
+	u64 t1_64, t2_64, t3_64;
+	u32 t1_32, t2_32;
+	int i;
+
+	insn.word = ir;
+	switch (insn.r_format.func) {
+	case madd_op:
+	case msub_op:
+
+		if (insn.r_format.re != 0 || insn.r_format.rd != 0)
+			return SIGILL;
+		rs32s = regs->regs[insn.r_format.rs];
+		rt32s = regs->regs[insn.r_format.rt];
+		t1_64s = rs32s;
+		t2_64s = rt32s;
+		t1_64s = t1_64s * t2_64s;	/* Product */
+		t1_32 = regs->hi;
+		t2_32 = regs->lo;
+		t1_64 = t1_32;
+		t2_64 = t2_32;
+		t1_64 = (t1_64 << 32) | t2_64;
+		t2_64s = t1_64;			/* (hi, lo) */
+		if (insn.r_format.func == madd_op)
+			t2_64s = t2_64s + t1_64s; /* (hi, lo) + Product */
+		else
+			t2_64s = t2_64s - t1_64s; /* (hi, lo) - Product */
+		t1_64 = t2_64s;
+
+		t2_64 = t1_64 & 0xffffffffu;
+		t1_64 = t1_64 >> 32;
+		t1_32 = t1_64;
+		t2_32 = t2_64;
+		regs->hi = (long)(s32)t1_32;
+		regs->lo = (long)(s32)t2_32;
+		return 0;
+
+	case maddu_op:
+	case msubu_op:
+		if (insn.r_format.re != 0 || insn.r_format.rd != 0)
+			return SIGILL;
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = regs->regs[insn.r_format.rt];
+		t1_64 = rs32;
+		t2_64 = rt32;
+		t1_64 = t1_64 * t2_64;		/* Product */
+		t1_32 = regs->hi;
+		t2_32 = regs->lo;
+		t2_64 = t1_32;
+		t3_64 = t2_32;
+		t2_64 = (t2_64 << 32) | t3_64;	/* (hi, lo) */
+
+		if (insn.r_format.func == maddu_op)
+			t1_64 = t2_64 + t1_64;	/* (hi, lo) + Product */
+		else
+			t1_64 = t2_64 - t1_64;	/* (hi, lo) - Product */
+
+		t2_64 = t1_64 & 0xffffffffu;
+		t1_64 = t1_64 >> 32;
+		t1_32 = t1_64;
+		t2_32 = t2_64;
+		regs->hi = (long)(s32)t1_32;
+		regs->lo = (long)(s32)t2_32;
+		return 0;
+
+	case mul_op:
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rs32s = regs->regs[insn.r_format.rs];
+		rt32s = regs->regs[insn.r_format.rt];
+		t1_64s = rs32s;
+		t2_64s = rt32s;
+		t1_64s = t1_64s * t2_64s;
+		t1_64 = t1_64s;
+		t1_32 = t1_64;
+		regs->regs[insn.r_format.rd] = (long)(s32)t1_32;
+		return 0;
+
+	case clz_op:
+	case clo_op:
+		t2_32 = (insn.r_format.func == clz_op) ? 0 : 1;
+		if (insn.r_format.re != 0)
+			return SIGILL;
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.r_format.rs];
+		t1_32 = 0;
+		for (i = 31; i <= 0; i--) {
+			if (((rs32 >> i) & 1) == t2_32)
+				t1_32++;
+			else
+				break;
+		}
+		regs->regs[insn.r_format.rd] = t1_32;
+		return 0;
+
+	case dclz_op:
+	case dclo_op:
+		return mips64_spec2_emul(regs, ir);
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips64_spec3_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	return SIGILL;
+}
+
+static int mips_bshfl_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	union mips_instruction insn;
+	u32 rt32, rd32;
+	s8 t8s;
+	s16 t16s;
+
+	insn.word = ir;
+	if (insn.r_format.rs != 0)
+		return SIGILL;
+
+	switch (insn.r_format.re) {
+	case wsbh_op:
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		rt32 = regs->regs[insn.r_format.rt];
+		rd32 = ((rt32 >> 8) & 0x00ff00ffu) | ((rt32 << 8) & 0xff00ff00u);
+		regs->regs[insn.r_format.rd] = (long)(s32)rd32;
+		return 0;
+	case seb_op:
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		t8s = regs->regs[insn.r_format.rt];
+		regs->regs[insn.r_format.rd] = (long)t8s;
+		return 0;
+	case seh_op:
+		if (insn.r_format.rd == 0)
+			return 0; /* ignore result */
+		t16s = regs->regs[insn.r_format.rt];
+		regs->regs[insn.r_format.rd] = (long)t16s;
+		return 0;
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips_dbshfl_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	union mips_instruction insn;
+
+	insn.word = ir;
+	switch (insn.r_format.re) {
+	case wsbh_op: /* DSBH */
+	case dshd_op:
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips_spec3_emul(struct pt_regs *regs, mips_instruction ir)
+{
+	union mips_instruction insn;
+	u32 rs32, rt32;
+	u32 t1_32;
+
+	insn.word = ir;
+	switch (insn.r_format.func) {
+	case ext_op:
+		if (insn.r_format.rt == 0)
+			return 0; /* ignore result */
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = rs32 >> insn.r_format.re;
+		rt32 = rt32 & (0xffffffffu >> (31 - insn.r_format.rd));
+		regs->regs[insn.r_format.rt] = (long)(s32)rt32;
+		return 0;
+	case ins_op:
+		if (insn.r_format.rt == 0)
+			return 0; /* ignore result */
+		t1_32 = 0xffffffffu >> (31 - insn.r_format.rd + insn.r_format.re);
+		t1_32 = t1_32 << insn.r_format.re; /* Mask */
+		rs32 = regs->regs[insn.r_format.rs];
+		rt32 = regs->regs[insn.r_format.rt];
+		rt32 = (rt32 & ~t1_32);
+		rs32 = (rs32 << insn.r_format.re) & t1_32;
+		rt32 = rt32 | rs32;
+		regs->regs[insn.r_format.rt] = (long)(s32)rt32;
+		return 0;
+	case bshfl_op:
+		return  mips_bshfl_emul(regs, ir);
+	case dbshfl_op:
+		return  mips_dbshfl_emul(regs, ir);
+	case rdhwr_op:
+
+	case dextm_op:
+	case dextu_op:
+	case dext_op:
+	case dinsm_op:
+	case dinsu_op:
+	case dins_op:
+		return mips64_spec3_emul(regs, ir);
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips_load_emul(struct pt_regs *regs, mips_instruction ir, void *__user *fault_addr)
+{
+	s8 __user *va8s;
+	s16 __user *va16s;
+	s32 __user *va32s;
+	u8 __user *va8;
+	u16 __user *va16;
+	union mips_instruction insn;
+	long base;
+	s8 t8s;
+	u8 t8;
+	s16 t16s;
+	u16 t16;
+	s32 t32s;
+
+	insn.word = ir;
+
+	base = regs->regs[insn.i_format.rs];
+	base = base + insn.i_format.simmediate;
+
+	switch (insn.i_format.opcode) {
+	case lb_op:
+		va8s = (s8 __user *)base;
+		if (!access_ok(VERIFY_READ, va8s, sizeof(t8s))) {
+			*fault_addr = va8s;
+			return SIGBUS;
+		}
+		if (__get_user_nocheck(t8s, va8s, sizeof(t8s))) {
+			*fault_addr = va8s;
+			return SIGSEGV;
+		}
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.i_format.rt] = (long)t8s;
+		return 0;
+	case lh_op:
+		va16s = (s16 __user *)base;
+		if (!access_ok(VERIFY_READ, va16s, sizeof(t16s))) {
+			*fault_addr = va16s;
+			return SIGBUS;
+		}
+		if (__get_user_nocheck(t16s, va16s, sizeof(t16s))) {
+			*fault_addr = va16s;
+			return SIGSEGV;
+		}
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.i_format.rt] = (long)t16s;
+		return 0;
+	case lw_op:
+		va32s = (s32 __user *)base;
+		if (!access_ok(VERIFY_READ, va32s, sizeof(t32s))) {
+			*fault_addr = va32s;
+			return SIGBUS;
+		}
+		if (__get_user_nocheck(t32s, va32s, sizeof(t32s))) {
+			*fault_addr = va32s;
+			return SIGSEGV;
+		}
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.i_format.rt] = (long)t32s;
+		return 0;
+	case lbu_op:
+		va8 = (u8 __user *)base;
+		if (!access_ok(VERIFY_READ, va8, sizeof(t8))) {
+			*fault_addr = va8;
+			return SIGBUS;
+		}
+		if (__get_user_nocheck(t8, va8, sizeof(t8))) {
+			*fault_addr = va8;
+			return SIGSEGV;
+		}
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.i_format.rt] = t8;
+		return 0;
+	case lhu_op:
+		va16 = (u16 __user *)base;
+		if (!access_ok(VERIFY_READ, va16, sizeof(t16))) {
+			*fault_addr = va16;
+			return SIGBUS;
+		}
+		if (__get_user_nocheck(t16, va16, sizeof(t16))) {
+			*fault_addr = va16;
+			return SIGSEGV;
+		}
+		if (insn.i_format.rt == 0)
+			return 0; /* ignore result */
+		regs->regs[insn.i_format.rt] = t16;
+		return 0;
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips_store_emul(struct pt_regs *regs, mips_instruction ir, void *__user *fault_addr)
+{
+	u8 __user *va8;
+	u16 __user *va16;
+	u32 __user *va32;
+	u8 t8;
+	u16 t16;
+	u32 t32;
+	union mips_instruction insn;
+	long base;
+
+	insn.word = ir;
+
+	base = regs->regs[insn.i_format.rs];
+	base = base + insn.i_format.simmediate;
+
+	switch (insn.i_format.opcode) {
+	case sb_op:
+		va8 = (u8 __user *)base;
+		if (!access_ok(VERIFY_WRITE, va8, sizeof(t8))) {
+			*fault_addr = va8;
+			return SIGBUS;
+		}
+		t8 = (u8)regs->regs[insn.i_format.rt];
+		if (__put_user_nocheck(t8, va8, sizeof(t8))) {
+			*fault_addr = va8;
+			return SIGSEGV;
+		}
+		return 0;
+	case sh_op:
+		va16 = (u16 __user *)base;
+		if (!access_ok(VERIFY_WRITE, va16, sizeof(t16))) {
+			*fault_addr = va16;
+			return SIGBUS;
+		}
+		t16 = (u16)regs->regs[insn.i_format.rt];
+		if (__put_user_nocheck(t16, va16, sizeof(t16))) {
+			*fault_addr = va16;
+			return SIGSEGV;
+		}
+		return 0;
+	case sw_op:
+		va32 = (u32 __user *)base;
+		if (!access_ok(VERIFY_WRITE, va32, sizeof(t32))) {
+			*fault_addr = va32;
+			return SIGBUS;
+		}
+		t32 = (u32)regs->regs[insn.i_format.rt];
+		if (__put_user_nocheck(t32, va32, sizeof(t32))) {
+			*fault_addr = va32;
+			return SIGSEGV;
+		}
+		return 0;
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips64_load_emul(struct pt_regs *regs, mips_instruction ir, void *__user *fault_addr)
+{
+	union mips_instruction insn;
+
+	insn.word = ir;
+	switch (insn.i_format.opcode) {
+	default:
+		return SIGILL;
+	}
+}
+
+static int mips64_store_emul(struct pt_regs *regs, mips_instruction ir, void *__user *fault_addr)
+{
+	union mips_instruction insn;
+
+	insn.word = ir;
+	switch (insn.i_format.opcode) {
+	default:
+		return SIGILL;
+	}
+}
+
+int mips_insn_emul(struct pt_regs *regs, mips_instruction ir, void *__user *fault_addr)
+{
+	switch (MIPSInst_OPCODE(ir)) {
+	case spec_op:
+		return mips_spec_emul(regs, ir);
+	case addi_op:
+	case addiu_op:
+	case slti_op:
+	case sltiu_op:
+	case andi_op:
+	case ori_op:
+	case xori_op:
+	case lui_op:
+		return mips_imm_emul(regs, ir);
+	case daddi_op:
+	case daddiu_op:
+		return mips64_imm_emul(regs, ir);
+	case spec2_op:
+		return mips_spec2_emul(regs, ir);
+	case spec3_op:
+		return mips_spec3_emul(regs, ir);
+	case lb_op:
+	case lh_op:
+	case lw_op:
+	case lbu_op:
+	case lhu_op:
+		return mips_load_emul(regs, ir, fault_addr);
+	case sb_op:
+	case sh_op:
+	case sw_op:
+		return mips_store_emul(regs, ir, fault_addr);
+	case lwu_op:
+	case ld_op:
+		return mips64_load_emul(regs, ir, fault_addr);
+	case sd_op:
+		return mips64_store_emul(regs, ir, fault_addr);
+	case pref_op:
+		return 0; /* OK to ignore PREF */
+	default:
+		return SIGILL;
+	}
+}
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* [PATCH 3/3] MIPS: Use full instruction emulation for FPU emulator delay slot emulation.
  2014-12-03 23:44 [PATCH 0/3] MIPS: Get ready for non-executable stack David Daney
  2014-12-03 23:44 ` [PATCH 1/3] MIPS: Add FPU emulator counter for non-FPU instructions emulated David Daney
  2014-12-03 23:44 ` [PATCH 2/3] MIPS: Add full ISA emulator David Daney
@ 2014-12-03 23:44 ` David Daney
  2 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-03 23:44 UTC (permalink / raw)
  To: linux-mips, ralf
  Cc: Leonid Yegoshin, Zubair.Kakakhel, geert+renesas, peterz,
	paul.gortmaker, macro, chenhc, cl, mingo, richard, zajec5,
	james.hogan, keescook, tj, alex, pbonzini, blogic, paul.burton,
	qais.yousef, linux-kernel, markos.chandras, dengcheng.zhu,
	manuel.lauss, lars.persson, David Daney

From: David Daney <david.daney@cavium.com>

Current delay slot handling does eXecute Out of Line (XOL) on the
stack, which prevents a non-executable stack.  Use the instruction
emulator instead.

Tested by booting 32-bit Debian on OCTEON.  More than 1700
instructions emulated to login to command line.

Signed-off-by: David Daney <david.daney@cavium.com>
---
 arch/mips/math-emu/cp1emu.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index cac529a..787de7a 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -694,11 +694,12 @@ do {									\
  * Emulate the single floating point instruction pointed at by EPC.
  * Two instructions if the instruction is in a branch delay slot.
  */
-
+int mips_insn_emul(struct pt_regs *regs, mips_instruction ir, void *__user *fault_addr);
 static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
 		struct mm_decoded_insn dec_insn, void *__user *fault_addr)
 {
 	unsigned long contpc = xcp->cp0_epc + dec_insn.pc_inc;
+	unsigned long origpc = xcp->cp0_epc;
 	unsigned int cond, cbit;
 	mips_instruction ir;
 	int likely, pc_inc;
@@ -1038,7 +1039,15 @@ emul:
 				 * Single step the non-cp1
 				 * instruction in the dslot
 				 */
-				return mips_dsemul(xcp, ir, contpc);
+				sig = mips_insn_emul(xcp, ir, fault_addr);
+				if (sig == 0) {
+					xcp->cp0_epc = contpc;
+					MIPS_FPU_EMU_INC_STATS(insn_emul);
+				} else {
+					xcp->cp0_epc = origpc;
+					pr_err("mips_insn_emul: %08x ->%d\n", (unsigned)ir, sig);
+				}
+				return sig;
 			} else if (likely) {	/* branch not taken */
 					/*
 					 * branch likely nullifies
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-03 23:55     ` Leonid Yegoshin
  0 siblings, 0 replies; 22+ messages in thread
From: Leonid Yegoshin @ 2014-12-03 23:55 UTC (permalink / raw)
  To: David Daney, linux-mips, ralf
  Cc: Zubair.Kakakhel, geert+renesas, peterz, paul.gortmaker, macro,
	chenhc, cl, mingo, richard, zajec5, james.hogan, keescook, tj,
	alex, pbonzini, blogic, paul.burton, qais.yousef, linux-kernel,
	markos.chandras, dengcheng.zhu, manuel.lauss, lars.persson,
	David Daney

On 12/03/2014 03:44 PM, David Daney wrote:

(...)

Big work but it doesn't support customized instructions, multiple ASEs, 
MIPS R6 etc.

Well, it is still not a replacement of XOL emulation.
Even close.



^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-03 23:55     ` Leonid Yegoshin
  0 siblings, 0 replies; 22+ messages in thread
From: Leonid Yegoshin @ 2014-12-03 23:55 UTC (permalink / raw)
  To: David Daney, linux-mips, ralf
  Cc: Zubair.Kakakhel, geert+renesas, peterz, paul.gortmaker, macro,
	chenhc, cl, mingo, richard, zajec5, james.hogan, keescook, tj,
	alex, pbonzini, blogic, paul.burton, qais.yousef, linux-kernel,
	markos.chandras, dengcheng.zhu, manuel.lauss, lars.persson,
	David Daney

On 12/03/2014 03:44 PM, David Daney wrote:

(...)

Big work but it doesn't support customized instructions, multiple ASEs, 
MIPS R6 etc.

Well, it is still not a replacement of XOL emulation.
Even close.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  0:20       ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04  0:20 UTC (permalink / raw)
  To: Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 03:55 PM, Leonid Yegoshin wrote:
> On 12/03/2014 03:44 PM, David Daney wrote:
>
> (...)
>
> Big work

Not really, although by number of lines of code, it is about 3x the size 
of your patch, it only touches the existing code in one place.  It only 
took about 3 days to write, adding full MIPS64 and R6 support would 
probably be less than another week of work.

microMIPS I haven't looked at as we don't have anything to test it on.

> but it doesn't support customized instructions,

GCC will never put these in the delay slot of a FPU branch, so it is not 
needed.

> multiple ASEs,

Same as above.  But any instructions that are deemed necessary can 
easily be added.

> MIPS R6

It is a proof of concept.  R6 can easily be added if needed.

Your XOL emulation doesn't handle R6 either, so this is no worse than 
your patch in that respect.

> etc.

GCC will never put trapping instructions in the delay slot either.

All we have to support are non-trapping and non-branch/jump instructions 
from the ISA manuals that can be executed from userspace processes. 
That makes it slightly simpler than complete ISA emulation.

>
> Well, it is still not a replacement of XOL emulation.

For use by the FPU emulator, it is probably good enough

> Even close.

I disagree, that is why I took the time to do it.

>
>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  0:20       ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04  0:20 UTC (permalink / raw)
  To: Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 03:55 PM, Leonid Yegoshin wrote:
> On 12/03/2014 03:44 PM, David Daney wrote:
>
> (...)
>
> Big work

Not really, although by number of lines of code, it is about 3x the size 
of your patch, it only touches the existing code in one place.  It only 
took about 3 days to write, adding full MIPS64 and R6 support would 
probably be less than another week of work.

microMIPS I haven't looked at as we don't have anything to test it on.

> but it doesn't support customized instructions,

GCC will never put these in the delay slot of a FPU branch, so it is not 
needed.

> multiple ASEs,

Same as above.  But any instructions that are deemed necessary can 
easily be added.

> MIPS R6

It is a proof of concept.  R6 can easily be added if needed.

Your XOL emulation doesn't handle R6 either, so this is no worse than 
your patch in that respect.

> etc.

GCC will never put trapping instructions in the delay slot either.

All we have to support are non-trapping and non-branch/jump instructions 
from the ISA manuals that can be executed from userspace processes. 
That makes it slightly simpler than complete ISA emulation.

>
> Well, it is still not a replacement of XOL emulation.

For use by the FPU emulator, it is probably good enough

> Even close.

I disagree, that is why I took the time to do it.

>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  0:52         ` Leonid Yegoshin
  0 siblings, 0 replies; 22+ messages in thread
From: Leonid Yegoshin @ 2014-12-04  0:52 UTC (permalink / raw)
  To: David Daney
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 04:20 PM, David Daney wrote:
> On 12/03/2014 03:55 PM, Leonid Yegoshin wrote:
>> On 12/03/2014 03:44 PM, David Daney wrote:
>>
>> (...)
>>
>> Big work
>
> Not really, although by number of lines of code, it is about 3x the 
> size of your patch, it only touches the existing code in one place.  
> It only took about 3 days to write, adding full MIPS64 and R6 support 
> would probably be less than another week of work.
>
> microMIPS I haven't looked at as we don't have anything to test it on.
>
>> but it doesn't support customized instructions,
>
> GCC will never put these in the delay slot of a FPU branch, so it is 
> not needed.

I doubt that it is correct in all situations and with any GCC parameter 
combination.

Never say never, if it is about toolchain. IMG Arch team was assured 
that branch likely are never used and removed it in MIPS R6, but BGEZL 
(or so) was a first which I hit then I ran GLIBC.

Besides GCC there are LLVM and another JITs.

>
>> multiple ASEs,
>
> Same as above.  But any instructions that are deemed necessary can 
> easily be added.
>
>> MIPS R6
>
> It is a proof of concept.  R6 can easily be added if needed.
>
> Your XOL emulation doesn't handle R6 either, so this is no worse than 
> your patch in that respect.

You probably didn't research it well. A lot of changes in 
arch/mips/kernel/branch.c and and arch/mips/math-emu/cp1emu.c, all of it 
related with R6.

>
>> etc.
>
> GCC will never put trapping instructions in the delay slot either.

It seems like it is not correct and requires a more accurate statement. 
FPU instructions may trap, LWL and LWR traps on R6 with RI, etc. Yes, 
there are restrictions but basing a kernel on that assumptions is 
unsafe. The only safe is HW architecture document.

Finally, there is a manual encoding too.

>
> All we have to support are non-trapping and non-branch/jump 
> instructions from the ISA manuals that can be executed from userspace 
> processes. That makes it slightly simpler than complete ISA emulation.
>
>>
>> Well, it is still not a replacement of XOL emulation.
>
> For use by the FPU emulator, it is probably good enough
>
>> Even close.
>
> I disagree, that is why I took the time to do it.
>
>>
>>
>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  0:52         ` Leonid Yegoshin
  0 siblings, 0 replies; 22+ messages in thread
From: Leonid Yegoshin @ 2014-12-04  0:52 UTC (permalink / raw)
  To: David Daney
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 04:20 PM, David Daney wrote:
> On 12/03/2014 03:55 PM, Leonid Yegoshin wrote:
>> On 12/03/2014 03:44 PM, David Daney wrote:
>>
>> (...)
>>
>> Big work
>
> Not really, although by number of lines of code, it is about 3x the 
> size of your patch, it only touches the existing code in one place.  
> It only took about 3 days to write, adding full MIPS64 and R6 support 
> would probably be less than another week of work.
>
> microMIPS I haven't looked at as we don't have anything to test it on.
>
>> but it doesn't support customized instructions,
>
> GCC will never put these in the delay slot of a FPU branch, so it is 
> not needed.

I doubt that it is correct in all situations and with any GCC parameter 
combination.

Never say never, if it is about toolchain. IMG Arch team was assured 
that branch likely are never used and removed it in MIPS R6, but BGEZL 
(or so) was a first which I hit then I ran GLIBC.

Besides GCC there are LLVM and another JITs.

>
>> multiple ASEs,
>
> Same as above.  But any instructions that are deemed necessary can 
> easily be added.
>
>> MIPS R6
>
> It is a proof of concept.  R6 can easily be added if needed.
>
> Your XOL emulation doesn't handle R6 either, so this is no worse than 
> your patch in that respect.

You probably didn't research it well. A lot of changes in 
arch/mips/kernel/branch.c and and arch/mips/math-emu/cp1emu.c, all of it 
related with R6.

>
>> etc.
>
> GCC will never put trapping instructions in the delay slot either.

It seems like it is not correct and requires a more accurate statement. 
FPU instructions may trap, LWL and LWR traps on R6 with RI, etc. Yes, 
there are restrictions but basing a kernel on that assumptions is 
unsafe. The only safe is HW architecture document.

Finally, there is a manual encoding too.

>
> All we have to support are non-trapping and non-branch/jump 
> instructions from the ISA manuals that can be executed from userspace 
> processes. That makes it slightly simpler than complete ISA emulation.
>
>>
>> Well, it is still not a replacement of XOL emulation.
>
> For use by the FPU emulator, it is probably good enough
>
>> Even close.
>
> I disagree, that is why I took the time to do it.
>
>>
>>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  1:29           ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04  1:29 UTC (permalink / raw)
  To: Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 04:52 PM, Leonid Yegoshin wrote:
> On 12/03/2014 04:20 PM, David Daney wrote:
>> On 12/03/2014 03:55 PM, Leonid Yegoshin wrote:
>>> On 12/03/2014 03:44 PM, David Daney wrote:
>>>
>>> (...)
>>>
>>> Big work
>>
>> Not really, although by number of lines of code, it is about 3x the
>> size of your patch, it only touches the existing code in one place. It
>> only took about 3 days to write, adding full MIPS64 and R6 support
>> would probably be less than another week of work.
>>
>> microMIPS I haven't looked at as we don't have anything to test it on.
>>
>>> but it doesn't support customized instructions,
>>
>> GCC will never put these in the delay slot of a FPU branch, so it is
>> not needed.
>
> I doubt that it is correct in all situations and with any GCC parameter
> combination.

My GCC experts assert that it is true.

>
> Never say never, if it is about toolchain. IMG Arch team was assured
> that branch likely are never used and removed it in MIPS R6, but BGEZL
> (or so) was a first which I hit then I ran GLIBC.

The fact that the Arch Team designed R6 without bothering to determine 
what legacy code does is not relevant to this conversation.

>
> Besides GCC there are LLVM and another JITs.
>

They don't do it either.  But that is not really important.  We can 
easily emulate faulting instructions if needed.

>>
>>> multiple ASEs,
>>
>> Same as above.  But any instructions that are deemed necessary can
>> easily be added.
>>
>>> MIPS R6
>>
>> It is a proof of concept.  R6 can easily be added if needed.
>>
>> Your XOL emulation doesn't handle R6 either, so this is no worse than
>> your patch in that respect.
>
> You probably didn't research it well. A lot of changes in
> arch/mips/kernel/branch.c and and arch/mips/math-emu/cp1emu.c, all of it
> related with R6.
>

I looked at:
commit 3a18ca061311f2f1ee9c44012f89c7436d392117

And I saw no R6 support.

Is it there, or in some other branch that isn't merged?


>>
>>> etc.
>>
>> GCC will never put trapping instructions in the delay slot either.
>
> It seems like it is not correct and requires a more accurate statement.
> FPU instructions may trap, LWL and LWR traps on R6 with RI, etc. Yes,
> there are restrictions but basing a kernel on that assumptions is
> unsafe. The only safe is HW architecture document.
>
> Finally, there is a manual encoding too.
>
>>
>> All we have to support are non-trapping and non-branch/jump
>> instructions from the ISA manuals that can be executed from userspace
>> processes. That makes it slightly simpler than complete ISA emulation.
>>
>>>
>>> Well, it is still not a replacement of XOL emulation.
>>
>> For use by the FPU emulator, it is probably good enough
>>
>>> Even close.
>>
>> I disagree, that is why I took the time to do it.
>>
>>>
>>>
>>
>


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  1:29           ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04  1:29 UTC (permalink / raw)
  To: Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 04:52 PM, Leonid Yegoshin wrote:
> On 12/03/2014 04:20 PM, David Daney wrote:
>> On 12/03/2014 03:55 PM, Leonid Yegoshin wrote:
>>> On 12/03/2014 03:44 PM, David Daney wrote:
>>>
>>> (...)
>>>
>>> Big work
>>
>> Not really, although by number of lines of code, it is about 3x the
>> size of your patch, it only touches the existing code in one place. It
>> only took about 3 days to write, adding full MIPS64 and R6 support
>> would probably be less than another week of work.
>>
>> microMIPS I haven't looked at as we don't have anything to test it on.
>>
>>> but it doesn't support customized instructions,
>>
>> GCC will never put these in the delay slot of a FPU branch, so it is
>> not needed.
>
> I doubt that it is correct in all situations and with any GCC parameter
> combination.

My GCC experts assert that it is true.

>
> Never say never, if it is about toolchain. IMG Arch team was assured
> that branch likely are never used and removed it in MIPS R6, but BGEZL
> (or so) was a first which I hit then I ran GLIBC.

The fact that the Arch Team designed R6 without bothering to determine 
what legacy code does is not relevant to this conversation.

>
> Besides GCC there are LLVM and another JITs.
>

They don't do it either.  But that is not really important.  We can 
easily emulate faulting instructions if needed.

>>
>>> multiple ASEs,
>>
>> Same as above.  But any instructions that are deemed necessary can
>> easily be added.
>>
>>> MIPS R6
>>
>> It is a proof of concept.  R6 can easily be added if needed.
>>
>> Your XOL emulation doesn't handle R6 either, so this is no worse than
>> your patch in that respect.
>
> You probably didn't research it well. A lot of changes in
> arch/mips/kernel/branch.c and and arch/mips/math-emu/cp1emu.c, all of it
> related with R6.
>

I looked at:
commit 3a18ca061311f2f1ee9c44012f89c7436d392117

And I saw no R6 support.

Is it there, or in some other branch that isn't merged?


>>
>>> etc.
>>
>> GCC will never put trapping instructions in the delay slot either.
>
> It seems like it is not correct and requires a more accurate statement.
> FPU instructions may trap, LWL and LWR traps on R6 with RI, etc. Yes,
> there are restrictions but basing a kernel on that assumptions is
> unsafe. The only safe is HW architecture document.
>
> Finally, there is a manual encoding too.
>
>>
>> All we have to support are non-trapping and non-branch/jump
>> instructions from the ISA manuals that can be executed from userspace
>> processes. That makes it slightly simpler than complete ISA emulation.
>>
>>>
>>> Well, it is still not a replacement of XOL emulation.
>>
>> For use by the FPU emulator, it is probably good enough
>>
>>> Even close.
>>
>> I disagree, that is why I took the time to do it.
>>
>>>
>>>
>>
>

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  2:21               ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04  2:21 UTC (permalink / raw)
  To: Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 05:56 PM, Leonid Yegoshin wrote:
> David,
>
> I feel we can close a discission at that point - we disagree which
> approach is better, and there is no sense to continue dancing around.
>

That is something I do agree with.

> I see only two technical issues here which differs:
>
> 1.  You believe your GCC experts, I trust HW Architecture manual and
> don't trust toolchain people too much ==> we see a different value in
> fact that your approach has a subset of emulated ISAs (and it can't, of
> course, emulate anything because some custom opcodes are reused).

Yes, I agree that the emulation approach cannot handle some of the cases 
you mention (most would have to be the result of hand coded assembly 
specifically trying to break it).

>
> 2.  My approach is ready to use and is used right now, you still have a
> framework which passed an initial boot.


Let's add some more, please correct me if I misstate the facts:

3) Your approach uses one additional page of memory per user space 
thread, even if emulation is never needed or there is a hardware FPU.

4) Your approach adds a Thread creation overhead of copy_page().

>
>
> On 12/03/2014 05:29 PM, David Daney wrote:
>> On 12/03/2014 04:52 PM, Leonid Yegoshin wrote:
>>> On 12/03/2014 04:20 PM, David Daney wrote:
>>>> It is a proof of concept.  R6 can easily be added if needed.
>>>>
>>>> Your XOL emulation doesn't handle R6 either, so this is no worse than
>>>> your patch in that respect.
>>>
>>> You probably didn't research it well. A lot of changes in
>>> arch/mips/kernel/branch.c and and arch/mips/math-emu/cp1emu.c, all of it
>>> related with R6.
>>>
>>
>> I looked at:
>> commit 3a18ca061311f2f1ee9c44012f89c7436d392117
>>
>> And I saw no R6 support.
>>
>> Is it there, or in some other branch that isn't merged?
>
> Sorry, I misunderstood your statement:
>
> Yes, my "MIPS: Setup an instruction emulation in VDSO protected page
> instead of user stack <http://patchwork.linux-mips.org/patch/8631/>" has
> no any MIPS R6 specifics and actually has no any another MIPS Rx
> specific or FPU specific besides the fact that emulation can be done by
> multiple emulators and a small stack is supported in so-called "VDSO"
> page. I just remember that I pointed you to place where MIPS R6 is done
> and it has a lot of MIPS R6 instruction emulation and confused both events.
>
> - Leonid.


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04  2:21               ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04  2:21 UTC (permalink / raw)
  To: Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	paul.burton, qais.yousef, linux-kernel, markos.chandras,
	dengcheng.zhu, manuel.lauss, lars.persson, David Daney

On 12/03/2014 05:56 PM, Leonid Yegoshin wrote:
> David,
>
> I feel we can close a discission at that point - we disagree which
> approach is better, and there is no sense to continue dancing around.
>

That is something I do agree with.

> I see only two technical issues here which differs:
>
> 1.  You believe your GCC experts, I trust HW Architecture manual and
> don't trust toolchain people too much ==> we see a different value in
> fact that your approach has a subset of emulated ISAs (and it can't, of
> course, emulate anything because some custom opcodes are reused).

Yes, I agree that the emulation approach cannot handle some of the cases 
you mention (most would have to be the result of hand coded assembly 
specifically trying to break it).

>
> 2.  My approach is ready to use and is used right now, you still have a
> framework which passed an initial boot.


Let's add some more, please correct me if I misstate the facts:

3) Your approach uses one additional page of memory per user space 
thread, even if emulation is never needed or there is a hardware FPU.

4) Your approach adds a Thread creation overhead of copy_page().

>
>
> On 12/03/2014 05:29 PM, David Daney wrote:
>> On 12/03/2014 04:52 PM, Leonid Yegoshin wrote:
>>> On 12/03/2014 04:20 PM, David Daney wrote:
>>>> It is a proof of concept.  R6 can easily be added if needed.
>>>>
>>>> Your XOL emulation doesn't handle R6 either, so this is no worse than
>>>> your patch in that respect.
>>>
>>> You probably didn't research it well. A lot of changes in
>>> arch/mips/kernel/branch.c and and arch/mips/math-emu/cp1emu.c, all of it
>>> related with R6.
>>>
>>
>> I looked at:
>> commit 3a18ca061311f2f1ee9c44012f89c7436d392117
>>
>> And I saw no R6 support.
>>
>> Is it there, or in some other branch that isn't merged?
>
> Sorry, I misunderstood your statement:
>
> Yes, my "MIPS: Setup an instruction emulation in VDSO protected page
> instead of user stack <http://patchwork.linux-mips.org/patch/8631/>" has
> no any MIPS R6 specifics and actually has no any another MIPS Rx
> specific or FPU specific besides the fact that emulation can be done by
> multiple emulators and a small stack is supported in so-called "VDSO"
> page. I just remember that I pointed you to place where MIPS R6 is done
> and it has a lot of MIPS R6 instruction emulation and confused both events.
>
> - Leonid.

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04 10:16                 ` Paul Burton
  0 siblings, 0 replies; 22+ messages in thread
From: Paul Burton @ 2014-12-04 10:16 UTC (permalink / raw)
  To: David Daney, Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	qais.yousef, linux-kernel, markos.chandras, dengcheng.zhu,
	manuel.lauss, lars.persson, David Daney

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

Nice work David, I like this approach. It's so much simpler than hacking
atop the current dsemul code. I also imagine this could be reused for
emulation of instructions removed in r6, when running pre-r6 userland
binaries on r6 systems.

On Wed, Dec 03, 2014 at 06:21:36PM -0800, David Daney wrote:
> On 12/03/2014 05:56 PM, Leonid Yegoshin wrote:
> >I see only two technical issues here which differs:
> >
> >1.  You believe your GCC experts, I trust HW Architecture manual and
> >don't trust toolchain people too much ==> we see a different value in
> >fact that your approach has a subset of emulated ISAs (and it can't, of
> >course, emulate anything because some custom opcodes are reused).
> 
> Yes, I agree that the emulation approach cannot handle some of the cases you
> mention (most would have to be the result of hand coded assembly
> specifically trying to break it).

I'm not sure I'd agree even with that - ASEs & vendor-specific
instructions could easily be added if necessary.

On Thu, Dec 04, 2014 at 05:56:51PM -0800, Leonid Yehoshin wrote:
> >2.  My approach is ready to use and is used right now, you still have a
> >framework which passed an initial boot.

Subjective.

Thanks,
    Paul

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04 10:16                 ` Paul Burton
  0 siblings, 0 replies; 22+ messages in thread
From: Paul Burton @ 2014-12-04 10:16 UTC (permalink / raw)
  To: David Daney, Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	qais.yousef, linux-kernel, markos.chandras, dengcheng.zhu,
	manuel.lauss, lars.persson, David Daney

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

Nice work David, I like this approach. It's so much simpler than hacking
atop the current dsemul code. I also imagine this could be reused for
emulation of instructions removed in r6, when running pre-r6 userland
binaries on r6 systems.

On Wed, Dec 03, 2014 at 06:21:36PM -0800, David Daney wrote:
> On 12/03/2014 05:56 PM, Leonid Yegoshin wrote:
> >I see only two technical issues here which differs:
> >
> >1.  You believe your GCC experts, I trust HW Architecture manual and
> >don't trust toolchain people too much ==> we see a different value in
> >fact that your approach has a subset of emulated ISAs (and it can't, of
> >course, emulate anything because some custom opcodes are reused).
> 
> Yes, I agree that the emulation approach cannot handle some of the cases you
> mention (most would have to be the result of hand coded assembly
> specifically trying to break it).

I'm not sure I'd agree even with that - ASEs & vendor-specific
instructions could easily be added if necessary.

On Thu, Dec 04, 2014 at 05:56:51PM -0800, Leonid Yehoshin wrote:
> >2.  My approach is ready to use and is used right now, you still have a
> >framework which passed an initial boot.

Subjective.

Thanks,
    Paul

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04 10:45                   ` Qais Yousef
  0 siblings, 0 replies; 22+ messages in thread
From: Qais Yousef @ 2014-12-04 10:45 UTC (permalink / raw)
  To: Paul Burton, David Daney, Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	linux-kernel, markos.chandras, dengcheng.zhu, manuel.lauss,
	lars.persson, David Daney

By all means I don't really understand the whole issues surrounding this 
but this approach looks better to me as well. It seems more generic and 
future proof and at least I can understand the patch series.

But did I say I don't understand all of this? Would be nice to hear from 
more people :)

Qais

On 12/04/2014 10:16 AM, Paul Burton wrote:
> Nice work David, I like this approach. It's so much simpler than hacking
> atop the current dsemul code. I also imagine this could be reused for
> emulation of instructions removed in r6, when running pre-r6 userland
> binaries on r6 systems.
>
> On Wed, Dec 03, 2014 at 06:21:36PM -0800, David Daney wrote:
>> On 12/03/2014 05:56 PM, Leonid Yegoshin wrote:
>>> I see only two technical issues here which differs:
>>>
>>> 1.  You believe your GCC experts, I trust HW Architecture manual and
>>> don't trust toolchain people too much ==> we see a different value in
>>> fact that your approach has a subset of emulated ISAs (and it can't, of
>>> course, emulate anything because some custom opcodes are reused).
>> Yes, I agree that the emulation approach cannot handle some of the cases you
>> mention (most would have to be the result of hand coded assembly
>> specifically trying to break it).
> I'm not sure I'd agree even with that - ASEs & vendor-specific
> instructions could easily be added if necessary.
>
> On Thu, Dec 04, 2014 at 05:56:51PM -0800, Leonid Yehoshin wrote:
>>> 2.  My approach is ready to use and is used right now, you still have a
>>> framework which passed an initial boot.
> Subjective.
>
> Thanks,
>      Paul


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04 10:45                   ` Qais Yousef
  0 siblings, 0 replies; 22+ messages in thread
From: Qais Yousef @ 2014-12-04 10:45 UTC (permalink / raw)
  To: Paul Burton, David Daney, Leonid Yegoshin
  Cc: David Daney, linux-mips, ralf, Zubair.Kakakhel, geert+renesas,
	peterz, paul.gortmaker, macro, chenhc, cl, mingo, richard,
	zajec5, james.hogan, keescook, tj, alex, pbonzini, blogic,
	linux-kernel, markos.chandras, dengcheng.zhu, manuel.lauss,
	lars.persson, David Daney

By all means I don't really understand the whole issues surrounding this 
but this approach looks better to me as well. It seems more generic and 
future proof and at least I can understand the patch series.

But did I say I don't understand all of this? Would be nice to hear from 
more people :)

Qais

On 12/04/2014 10:16 AM, Paul Burton wrote:
> Nice work David, I like this approach. It's so much simpler than hacking
> atop the current dsemul code. I also imagine this could be reused for
> emulation of instructions removed in r6, when running pre-r6 userland
> binaries on r6 systems.
>
> On Wed, Dec 03, 2014 at 06:21:36PM -0800, David Daney wrote:
>> On 12/03/2014 05:56 PM, Leonid Yegoshin wrote:
>>> I see only two technical issues here which differs:
>>>
>>> 1.  You believe your GCC experts, I trust HW Architecture manual and
>>> don't trust toolchain people too much ==> we see a different value in
>>> fact that your approach has a subset of emulated ISAs (and it can't, of
>>> course, emulate anything because some custom opcodes are reused).
>> Yes, I agree that the emulation approach cannot handle some of the cases you
>> mention (most would have to be the result of hand coded assembly
>> specifically trying to break it).
> I'm not sure I'd agree even with that - ASEs & vendor-specific
> instructions could easily be added if necessary.
>
> On Thu, Dec 04, 2014 at 05:56:51PM -0800, Leonid Yehoshin wrote:
>>> 2.  My approach is ready to use and is used right now, you still have a
>>> framework which passed an initial boot.
> Subjective.
>
> Thanks,
>      Paul

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
  2014-12-04  0:20       ` David Daney
  (?)
  (?)
@ 2014-12-04 11:49       ` Maciej W. Rozycki
  2014-12-04 17:40           ` David Daney
  -1 siblings, 1 reply; 22+ messages in thread
From: Maciej W. Rozycki @ 2014-12-04 11:49 UTC (permalink / raw)
  To: David Daney
  Cc: Leonid Yegoshin, David Daney, linux-mips, Ralf Baechle,
	Zubair.Kakakhel, geert+renesas, peterz, paul.gortmaker, chenhc,
	cl, Ingo Molnar, richard, zajec5, james.hogan, keescook, tj,
	alex, pbonzini, blogic, paul.burton, qais.yousef, linux-kernel,
	markos.chandras, dengcheng.zhu, manuel.lauss, lars.persson,
	David Daney

On Wed, 3 Dec 2014, David Daney wrote:

> > but it doesn't support customized instructions,
> 
> GCC will never put these in the delay slot of a FPU branch, so it is not
> needed.
> 
> > multiple ASEs,
> 
> Same as above.  But any instructions that are deemed necessary can easily be
> added.

 GAS will happily schedule any instruction into a branch delay slot as 
long as the instruction is not architecturally forbidden there (e.g. 
ERET), there is no data dependency with the branch that would affect the 
result produced and the instruction is not an explicit exception trap 
operation (BREAK, SYSCALL, TEQ, etc.).  For some reason, unknown to me all 
MT ASE instructions are disallowed too.  Anything else -- free to go in!

 Of course instructions can be scheduled into branch delay slots manually 
too, in handcoded assembly, and that has to continue working.

  Maciej

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04 17:40           ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04 17:40 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Leonid Yegoshin, David Daney, linux-mips, Ralf Baechle,
	Zubair.Kakakhel, geert+renesas, peterz, paul.gortmaker, chenhc,
	cl, Ingo Molnar, richard, zajec5, james.hogan, keescook, tj,
	alex, pbonzini, blogic, paul.burton, qais.yousef, linux-kernel,
	markos.chandras, dengcheng.zhu, manuel.lauss, lars.persson,
	David Daney

On 12/04/2014 03:49 AM, Maciej W. Rozycki wrote:
> On Wed, 3 Dec 2014, David Daney wrote:
>
>>> but it doesn't support customized instructions,
>>
>> GCC will never put these in the delay slot of a FPU branch, so it is not
>> needed.
>>
>>> multiple ASEs,
>>
>> Same as above.  But any instructions that are deemed necessary can easily be
>> added.
>
>   GAS will happily schedule any instruction into a branch delay slot as
> long as the instruction is not architecturally forbidden there (e.g.
> ERET), there is no data dependency with the branch that would affect the
> result produced and the instruction is not an explicit exception trap
> operation (BREAK, SYSCALL, TEQ, etc.).  For some reason, unknown to me all
> MT ASE instructions are disallowed too.  Anything else -- free to go in!
>
>   Of course instructions can be scheduled into branch delay slots manually
> too, in handcoded assembly, and that has to continue working.
>

It is not difficult to also emulate the trapping instructions.  In order 
to move forward, I will implement the trapping instructions in my 
emulator for the next patch.

Thanks,
David Daney


^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
@ 2014-12-04 17:40           ` David Daney
  0 siblings, 0 replies; 22+ messages in thread
From: David Daney @ 2014-12-04 17:40 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Leonid Yegoshin, David Daney, linux-mips, Ralf Baechle,
	Zubair.Kakakhel, geert+renesas, peterz, paul.gortmaker, chenhc,
	cl, Ingo Molnar, richard, zajec5, james.hogan, keescook, tj,
	alex, pbonzini, blogic, paul.burton, qais.yousef, linux-kernel,
	markos.chandras, dengcheng.zhu, manuel.lauss, lars.persson,
	David Daney

On 12/04/2014 03:49 AM, Maciej W. Rozycki wrote:
> On Wed, 3 Dec 2014, David Daney wrote:
>
>>> but it doesn't support customized instructions,
>>
>> GCC will never put these in the delay slot of a FPU branch, so it is not
>> needed.
>>
>>> multiple ASEs,
>>
>> Same as above.  But any instructions that are deemed necessary can easily be
>> added.
>
>   GAS will happily schedule any instruction into a branch delay slot as
> long as the instruction is not architecturally forbidden there (e.g.
> ERET), there is no data dependency with the branch that would affect the
> result produced and the instruction is not an explicit exception trap
> operation (BREAK, SYSCALL, TEQ, etc.).  For some reason, unknown to me all
> MT ASE instructions are disallowed too.  Anything else -- free to go in!
>
>   Of course instructions can be scheduled into branch delay slots manually
> too, in handcoded assembly, and that has to continue working.
>

It is not difficult to also emulate the trapping instructions.  In order 
to move forward, I will implement the trapping instructions in my 
emulator for the next patch.

Thanks,
David Daney

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH 2/3] MIPS: Add full ISA emulator.
  2014-12-04 17:40           ` David Daney
  (?)
@ 2014-12-04 20:32           ` Maciej W. Rozycki
  -1 siblings, 0 replies; 22+ messages in thread
From: Maciej W. Rozycki @ 2014-12-04 20:32 UTC (permalink / raw)
  To: David Daney
  Cc: Leonid Yegoshin, David Daney, linux-mips, Ralf Baechle,
	Zubair.Kakakhel, geert+renesas, peterz, paul.gortmaker, chenhc,
	cl, Ingo Molnar, richard, zajec5, james.hogan, keescook, tj,
	alex, pbonzini, blogic, paul.burton, qais.yousef, linux-kernel,
	markos.chandras, dengcheng.zhu, manuel.lauss, lars.persson,
	David Daney

On Thu, 4 Dec 2014, David Daney wrote:

> >   GAS will happily schedule any instruction into a branch delay slot as
> > long as the instruction is not architecturally forbidden there (e.g.
> > ERET), there is no data dependency with the branch that would affect the
> > result produced and the instruction is not an explicit exception trap
> > operation (BREAK, SYSCALL, TEQ, etc.).  For some reason, unknown to me all
> > MT ASE instructions are disallowed too.  Anything else -- free to go in!
> >
> >   Of course instructions can be scheduled into branch delay slots manually
> > too, in handcoded assembly, and that has to continue working.
> >
> 
> It is not difficult to also emulate the trapping instructions.  In order to
> move forward, I will implement the trapping instructions in my emulator for
> the next patch.

 I'd be more concerned about getting the more exotic instructions or cases 
right (did you get MADDU right for SmartMIPS processors and set the ACX 
register on them?) -- how do you propose to validate and regression-test 
the emulator in a reproducible manner?

 The combination of the rare case of an instruction being placed in an FP 
branch delay slot and the rarity of some instructions themselves makes me 
scared of bugs lurking there forever and occasionally biting people -- who 
may not be aware that software emulation is involved let alone be capable 
to track them down -- in the most frustrating way.  To say nothing of the 
infinite amount of effort to maintain the emulator associated with adding 
architectural and vendor-specific instructions.  See how much effort has 
been put into QEMU and still it does not get all the MIPS instruction set 
bits right.

  Maciej

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-12-04 20:32 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-03 23:44 [PATCH 0/3] MIPS: Get ready for non-executable stack David Daney
2014-12-03 23:44 ` [PATCH 1/3] MIPS: Add FPU emulator counter for non-FPU instructions emulated David Daney
2014-12-03 23:44 ` [PATCH 2/3] MIPS: Add full ISA emulator David Daney
2014-12-03 23:55   ` Leonid Yegoshin
2014-12-03 23:55     ` Leonid Yegoshin
2014-12-04  0:20     ` David Daney
2014-12-04  0:20       ` David Daney
2014-12-04  0:52       ` Leonid Yegoshin
2014-12-04  0:52         ` Leonid Yegoshin
2014-12-04  1:29         ` David Daney
2014-12-04  1:29           ` David Daney
     [not found]           ` <547FBF63.70802@imgtec.com>
2014-12-04  2:21             ` David Daney
2014-12-04  2:21               ` David Daney
2014-12-04 10:16               ` Paul Burton
2014-12-04 10:16                 ` Paul Burton
2014-12-04 10:45                 ` Qais Yousef
2014-12-04 10:45                   ` Qais Yousef
2014-12-04 11:49       ` Maciej W. Rozycki
2014-12-04 17:40         ` David Daney
2014-12-04 17:40           ` David Daney
2014-12-04 20:32           ` Maciej W. Rozycki
2014-12-03 23:44 ` [PATCH 3/3] MIPS: Use full instruction emulation for FPU emulator delay slot emulation David Daney

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.