]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
dtrace: correct mutex_* subroutines
authorKris Van Hees <kris.van.hees@oracle.com>
Tue, 16 May 2017 13:33:26 +0000 (09:33 -0400)
committerKris Van Hees <kris.van.hees@oracle.com>
Tue, 23 May 2017 13:36:02 +0000 (09:36 -0400)
The mutex_* subroutines were not accessing the state of a mutex
correctly, causing incorrect results.

This commit also cleans up DIF emulation debug output a tiny bit.

Orabug: 26044447
Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com>
Reviewed-by: Tomas Jedlicka <tomas.jedlicka@oracle.com>
dtrace/dtrace_dif.c

index b27861c60fbfa29aaa66b6903669351c81db4125..974d18284935d4bfcedf5edd6cb72b195c40c2e8 100644 (file)
@@ -2378,11 +2378,7 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
        volatile uint16_t       *flags = &this_cpu_core->cpuc_dtrace_flags;
        volatile uintptr_t      *illval = &this_cpu_core->cpuc_dtrace_illval;
        dtrace_vstate_t         *vstate = &state->dts_vstate;
-
-       union {
-               struct mutex mi;
-               uint64_t mx;
-       } m;
+       struct mutex            mtx;
 
        union {
                rwlock_t ri;
@@ -2398,26 +2394,32 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
                break;
 
        case DIF_SUBR_MUTEX_OWNED:
+               regs[rd] = 0;
                if (!dtrace_canload(tupregs[0].dttk_value,
-                                   sizeof(struct mutex), mstate, vstate)) {
-                       regs[rd] = 0;
+                                   sizeof(struct mutex), mstate, vstate))
+                       break;
+
+               dtrace_bcopy((const void *)(uintptr_t)tupregs[0].dttk_value,
+                            &mtx, sizeof(struct mutex));
+               if (*flags & CPU_DTRACE_FAULT)
                        break;
-               }
 
-               m.mx = dtrace_load64(tupregs[0].dttk_value);
-               regs[rd] = mutex_owned(&m.mi);
+               regs[rd] = mutex_owned(&mtx);
                break;
 
        case DIF_SUBR_MUTEX_OWNER:
+               regs[rd] = 0;
                if (!dtrace_canload(tupregs[0].dttk_value,
-                                   sizeof(struct mutex), mstate, vstate)) {
-                       regs[rd] = 0;
+                                   sizeof(struct mutex), mstate, vstate))
+                       break;
+
+               dtrace_bcopy((const void *)(uintptr_t)tupregs[0].dttk_value,
+                            &mtx, sizeof(struct mutex));
+               if (*flags & CPU_DTRACE_FAULT)
                        break;
-               }
 
-               m.mx = dtrace_load64(tupregs[0].dttk_value);
 #ifdef CONFIG_SMP
-               regs[rd] = (uintptr_t)m.mi.owner;
+               regs[rd] = (uintptr_t)mtx.owner;
 #else
                regs[rd] = 0;
 #endif
@@ -2430,7 +2432,6 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
                        break;
                }
 
-               m.mx = dtrace_load64(tupregs[0].dttk_value);
                /*
                 * On Linux, all mutexes are adaptive.
                 */
@@ -2444,7 +2445,6 @@ static void dtrace_dif_subr(uint_t subr, uint_t rd, uint64_t *regs,
                        break;
                }
 
-               m.mx = dtrace_load64(tupregs[0].dttk_value);
                /*
                 * On Linux, all mutexes are adaptive.
                 */
@@ -4050,7 +4050,7 @@ uint64_t dtrace_dif_emulate(dtrace_difo_t *difo, dtrace_mstate_t *mstate,
                r2 = DIF_INSTR_R2(instr);
                rd = DIF_INSTR_RD(instr);
 
-               dt_dbg_dif("      Executing opcode %d (%d, %d, %d)\n",
+               dt_dbg_dif("      Executing opcode %02x (%02x, %02x, %02x)\n",
                           DIF_INSTR_OP(instr), r1, r2, rd);
 
                switch (DIF_INSTR_OP(instr)) {