Browse Source

efDataPreprocessing memoryCall.c 沈瑞清 commit at 2020-12-25

沈瑞清 4 years ago
parent
commit
b771202d8a
1 changed files with 135 additions and 0 deletions
  1. 135 0
      efDataPreprocessing/dataSharedMemory/memoryCall.c

+ 135 - 0
efDataPreprocessing/dataSharedMemory/memoryCall.c

@@ -657,3 +657,138 @@ got_exception:
  	       una_reg(3), una_reg(4), una_reg(5));
 	printk("r6 = %016lx  r7 = %016lx  r8 = %016lx\n",
 	       una_reg(6), una_reg(7), una_reg(8));
+	printk("r9 = %016lx  r10= %016lx  r11= %016lx\n",
+	       una_reg(9), una_reg(10), una_reg(11));
+	printk("r12= %016lx  r13= %016lx  r14= %016lx\n",
+	       una_reg(12), una_reg(13), una_reg(14));
+	printk("r15= %016lx\n", una_reg(15));
+	printk("r16= %016lx  r17= %016lx  r18= %016lx\n",
+	       una_reg(16), una_reg(17), una_reg(18));
+	printk("r19= %016lx  r20= %016lx  r21= %016lx\n",
+ 	       una_reg(19), una_reg(20), una_reg(21));
+ 	printk("r22= %016lx  r23= %016lx  r24= %016lx\n",
+	       una_reg(22), una_reg(23), una_reg(24));
+	printk("r25= %016lx  r27= %016lx  r28= %016lx\n",
+	       una_reg(25), una_reg(27), una_reg(28));
+	printk("gp = %016lx  sp = %p\n", regs->gp, regs+1);
+
+	dik_show_code((unsigned int *)pc);
+	dik_show_trace((unsigned long *)(regs+1));
+
+	if (test_and_set_thread_flag (TIF_DIE_IF_KERNEL)) {
+		printk("die_if_kernel recursion detected.\n");
+		local_irq_enable();
+		while (1);
+	}
+	do_exit(SIGSEGV);
+}
+
+/*
+ * Convert an s-floating point value in memory format to the
+ * corresponding value in register format.  The exponent
+ * needs to be remapped to preserve non-finite values
+ * (infinities, not-a-numbers, denormals).
+ */
+static inline unsigned long
+s_mem_to_reg (unsigned long s_mem)
+{
+	unsigned long frac    = (s_mem >>  0) & 0x7fffff;
+	unsigned long sign    = (s_mem >> 31) & 0x1;
+	unsigned long exp_msb = (s_mem >> 30) & 0x1;
+	unsigned long exp_low = (s_mem >> 23) & 0x7f;
+	unsigned long exp;
+
+	exp = (exp_msb << 10) | exp_low;	/* common case */
+	if (exp_msb) {
+		if (exp_low == 0x7f) {
+			exp = 0x7ff;
+		}
+	} else {
+		if (exp_low == 0x00) {
+			exp = 0x000;
+		} else {
+			exp |= (0x7 << 7);
+		}
+	}
+	return (sign << 63) | (exp << 52) | (frac << 29);
+}
+
+/*
+ * Convert an s-floating point value in register format to the
+ * corresponding value in memory format.
+ */
+static inline unsigned long
+s_reg_to_mem (unsigned long s_reg)
+{
+	return ((s_reg >> 62) << 30) | ((s_reg << 5) >> 34);
+}
+
+/*
+ * Handle user-level unaligned fault.  Handling user-level unaligned
+ * faults is *extremely* slow and produces nasty messages.  A user
+ * program *should* fix unaligned faults ASAP.
+ *
+ * Notice that we have (almost) the regular kernel stack layout here,
+ * so finding the appropriate registers is a little more difficult
+ * than in the kernel case.
+ *
+ * Finally, we handle regular integer load/stores only.  In
+ * particular, load-linked/store-conditionally and floating point
+ * load/stores are not supported.  The former make no sense with
+ * unaligned faults (they are guaranteed to fail) and I don't think
+ * the latter will occur in any decent program.
+ *
+ * Sigh. We *do* have to handle some FP operations, because GCC will
+ * uses them as temporary storage for integer memory to memory copies.
+ * However, we need to deal with stt/ldt and sts/lds only.
+ */
+
+#define OP_INT_MASK	( 1L << 0x28 | 1L << 0x2c   /* ldl stl */	\
+			| 1L << 0x29 | 1L << 0x2d   /* ldq stq */	\
+			| 1L << 0x0c | 1L << 0x0d   /* ldwu stw */	\
+			| 1L << 0x0a | 1L << 0x0e ) /* ldbu stb */
+
+#define OP_WRITE_MASK	( 1L << 0x26 | 1L << 0x27   /* sts stt */	\
+			| 1L << 0x2c | 1L << 0x2d   /* stl stq */	\
+			| 1L << 0x0d | 1L << 0x0e ) /* stw stb */
+
+#define R(x)	((size_t) &((struct pt_regs *)0)->x)
+
+static int unauser_reg_offsets[32] = {
+	R(r0), R(r1), R(r2), R(r3), R(r4), R(r5), R(r6), R(r7), R(r8),
+	/* r9 ... r15 are stored in front of regs.  */
+	-56, -48, -40, -32, -24, -16, -8,
+	R(r16), R(r17), R(r18),
+	R(r19), R(r20), R(r21), R(r22), R(r23), R(r24), R(r25), R(r26),
+	R(r27), R(r28), R(gp),
+	0, 0
+};
+
+#undef R
+
+asmlinkage void
+do_entUnaUser(void __user * va, unsigned long opcode,
+	      unsigned long reg, struct pt_regs *regs)
+{
+	static DEFINE_RATELIMIT_STATE(ratelimit, 5 * HZ, 5);
+
+	unsigned long tmp1, tmp2, tmp3, tmp4;
+	unsigned long fake_reg, *reg_addr = &fake_reg;
+	siginfo_t info;
+	long error;
+
+	/* Check the UAC bits to decide what the user wants us to do
+	   with the unaliged access.  */
+
+	if (!(current_thread_info()->status & TS_UAC_NOPRINT)) {
+		if (__ratelimit(&ratelimit)) {
+			printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
+			       current->comm, task_pid_nr(current),
+			       regs->pc - 4, va, opcode, reg);
+		}
+	}
+	if ((current_thread_info()->status & TS_UAC_SIGBUS))
+		goto give_sigbus;
+	/* Not sure why you'd want to use this, but... */
+	if ((current_thread_info()->status & TS_UAC_NOFIX))
+		return;