linux Attempt to set a breakpoint resulted in kernel panic

Kprobes allows you to break into any kernel routine by modifying the OPCODE of an instruction (Kernel's text pages). In PPC32, kernel text pages are write-protected even if KPROBES is enabled. Thus, when arch_arm_kprobes() attempts to set a breakpoint, i.e. to write a kernel text address, this causes a segmentation fault.
Bug fixed by commit 221ac329e93
Type WriteOnReadOnly
Config "!PPC64 && KPROBES && !KGDB && !XMON && !BDI_SWITCH" (5th degree)
Fix-in mapping
Location arch/powerpc/kernel/
#include <unistd.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>

#define handle_error(msg) \
           do { perror(msg); exit(EXIT_FAILURE); } while (0)

char *buffer;

#if !defined(CONFIG_KGDB) && !defined(CONFIG_XMON) && !defined(CONFIG_BDI_SWITCH)
void allocate_buffer() {
   int pagesize;

   pagesize = sysconf(_SC_PAGE_SIZE);
   if (pagesize == -1)
       handle_error("sysconf");

   buffer = memalign(pagesize, 4*pagesize);
   if (buffer == NULL)
       handle_error("memalign");

   if (mprotect(buffer, 4*pagesize, PROT_READ) == -1)
       handle_error("mprotect");
}
#else
#define allocate_buffer() ({ buffer = malloc(4092); })
#endif


int main(int argc, char** argv)
{
  allocate_buffer();
#ifdef CONFIG_KPROBES
  *buffer = 'a'; // ERROR
#endif
   return 0;
}
diff --git a/simple/221ac32.c b/simple/221ac32.c
--- a/simple/221ac32.c
+++ b/simple/221ac32.c
@@ -10,7 +10,7 @@
 
 char *buffer;
 
-#if !defined(CONFIG_KGDB) && !defined(CONFIG_XMON) && !defined(CONFIG_BDI_SWITCH)
+#if !defined(CONFIG_KGDB) && !defined(CONFIG_XMON) && !defined(CONFIG_BDI_SWITCH) && !defined(CONFIG_KPROBES)
 void allocate_buffer() {
    int pagesize;
 
#include <unistd.h>
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>

int main(int argc, char** argv)
{
  char *buffer;
//  allocate_buffer();
#if !defined(CONFIG_KGDB) && !defined(CONFIG_XMON) && !defined(CONFIG_BDI_SWITCH)
  int pagesize;

  pagesize = sysconf(_SC_PAGE_SIZE);
  if (pagesize == -1)
    do { perror("sysconf"); exit(EXIT_FAILURE); } while (0);

  buffer = memalign(pagesize, 4*pagesize);
  if (buffer == NULL)
    do { perror("memalign"); exit(EXIT_FAILURE); } while (0);

  if (mprotect(buffer, 4*pagesize, PROT_READ) == -1)
    do { perror("mprotect"); exit(EXIT_FAILURE); } while (0);
#else
  buffer = malloc(4092);
#endif

#ifdef CONFIG_KPROBES
  *buffer = 'a'; // ERROR
#endif
   return 0;
}
. arch/powerpc/kernel/kprobes.c:75:arch_arm_kprobe()
. 77: *p->addr = BREAKPOINT_INSTRUCTION;