|
@@ -792,3 +792,37 @@ do_entUnaUser(void __user * va, unsigned long opcode,
|
|
|
/* Not sure why you'd want to use this, but... */
|
|
|
if ((current_thread_info()->status & TS_UAC_NOFIX))
|
|
|
return;
|
|
|
+
|
|
|
+ /* Don't bother reading ds in the access check since we already
|
|
|
+ know that this came from the user. Also rely on the fact that
|
|
|
+ the page at TASK_SIZE is unmapped and so can't be touched anyway. */
|
|
|
+ if (!__access_ok((unsigned long)va, 0, USER_DS))
|
|
|
+ goto give_sigsegv;
|
|
|
+
|
|
|
+ ++unaligned[1].count;
|
|
|
+ unaligned[1].va = (unsigned long)va;
|
|
|
+ unaligned[1].pc = regs->pc - 4;
|
|
|
+
|
|
|
+ if ((1L << opcode) & OP_INT_MASK) {
|
|
|
+ /* it's an integer load/store */
|
|
|
+ if (reg < 30) {
|
|
|
+ reg_addr = (unsigned long *)
|
|
|
+ ((char *)regs + unauser_reg_offsets[reg]);
|
|
|
+ } else if (reg == 30) {
|
|
|
+ /* usp in PAL regs */
|
|
|
+ fake_reg = rdusp();
|
|
|
+ } else {
|
|
|
+ /* zero "register" */
|
|
|
+ fake_reg = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* We don't want to use the generic get/put unaligned macros as
|
|
|
+ we want to trap exceptions. Only if we actually get an
|
|
|
+ exception will we decide whether we should have caught it. */
|
|
|
+
|
|
|
+ switch (opcode) {
|
|
|
+ case 0x0c: /* ldwu */
|
|
|
+ __asm__ __volatile__(
|
|
|
+ "1: ldq_u %1,0(%3)\n"
|
|
|
+ "2: ldq_u %2,1(%3)\n"
|