]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - arch/powerpc/xmon/xmon.c
Merge tag 'powerpc-4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
[linux.git] / arch / powerpc / xmon / xmon.c
index 82e1a3ee6e0fc0e8bf53ea22e8dd986ab2de508b..a0842f1ff72ca931cb576834d9fe8e5e42c9748e 100644 (file)
@@ -41,6 +41,7 @@
 #include <asm/pgtable.h>
 #include <asm/mmu.h>
 #include <asm/mmu_context.h>
+#include <asm/plpar_wrappers.h>
 #include <asm/cputable.h>
 #include <asm/rtas.h>
 #include <asm/sstep.h>
 #include <asm/paca.h>
 #endif
 
-#if defined(CONFIG_PPC_SPLPAR)
-#include <asm/plpar_wrappers.h>
-#else
-static inline long plapr_set_ciabr(unsigned long ciabr) {return 0; };
-#endif
-
 #include "nonstdio.h"
 #include "dis-asm.h"
 
@@ -328,7 +323,7 @@ static void write_ciabr(unsigned long ciabr)
                mtspr(SPRN_CIABR, ciabr);
                return;
        }
-       plapr_set_ciabr(ciabr);
+       plpar_set_ciabr(ciabr);
 }
 
 /**
@@ -1273,6 +1268,16 @@ static long check_bp_loc(unsigned long addr)
        return 1;
 }
 
+/* Force enable xmon if not already enabled */
+static inline void force_enable_xmon(void)
+{
+       /* Enable xmon hooks if needed */
+       if (!xmon_on) {
+               printf("xmon: Enabling debugger hooks\n");
+               xmon_on = 1;
+       }
+}
+
 static char *breakpoint_help_string =
     "Breakpoint command usage:\n"
     "b                show breakpoints\n"
@@ -1297,6 +1302,10 @@ bpt_cmds(void)
        static const char badaddr[] = "Only kernel addresses are permitted for breakpoints\n";
        int mode;
        case 'd':       /* bd - hardware data breakpoint */
+               if (!ppc_breakpoint_available()) {
+                       printf("Hardware data breakpoint not supported on this cpu\n");
+                       break;
+               }
                mode = 7;
                cmd = inchar();
                if (cmd == 'r')
@@ -1315,6 +1324,8 @@ bpt_cmds(void)
                        dabr.address &= ~HW_BRK_TYPE_DABR;
                        dabr.enabled = mode | BP_DABR;
                }
+
+               force_enable_xmon();
                break;
 
        case 'i':       /* bi - hardware instr breakpoint */
@@ -1335,6 +1346,7 @@ bpt_cmds(void)
                if (bp != NULL) {
                        bp->enabled |= BP_CIABR;
                        iabr = bp;
+                       force_enable_xmon();
                }
                break;
 #endif
@@ -1399,8 +1411,10 @@ bpt_cmds(void)
                if (!check_bp_loc(a))
                        break;
                bp = new_breakpoint(a);
-               if (bp != NULL)
+               if (bp != NULL) {
                        bp->enabled |= BP_TRAP;
+                       force_enable_xmon();
+               }
                break;
        }
 }
@@ -2327,7 +2341,7 @@ static void dump_one_paca(int cpu)
        catch_memory_errors = 1;
        sync();
 
-       p = &paca[cpu];
+       p = paca_ptrs[cpu];
 
        printf("paca for cpu 0x%x @ %px:\n", cpu, p);
 
@@ -3649,11 +3663,35 @@ device_initcall(setup_xmon_sysrq);
 #endif /* CONFIG_MAGIC_SYSRQ */
 
 #ifdef CONFIG_DEBUG_FS
+static void clear_all_bpt(void)
+{
+       int i;
+
+       /* clear/unpatch all breakpoints */
+       remove_bpts();
+       remove_cpu_bpts();
+
+       /* Disable all breakpoints */
+       for (i = 0; i < NBPTS; ++i)
+               bpts[i].enabled = 0;
+
+       /* Clear any data or iabr breakpoints */
+       if (iabr || dabr.enabled) {
+               iabr = NULL;
+               dabr.enabled = 0;
+       }
+
+       printf("xmon: All breakpoints cleared\n");
+}
+
 static int xmon_dbgfs_set(void *data, u64 val)
 {
        xmon_on = !!val;
        xmon_init(xmon_on);
 
+       /* make sure all breakpoints removed when disabling */
+       if (!xmon_on)
+               clear_all_bpt();
        return 0;
 }