/*
* #imm16 values used for BRK instruction generation
* Allowed values for kgbd are 0x400 - 0x7ff
+ * 0x100: for triggering a fault on purpose (reserved)
* 0x400: for dynamic BRK instruction
* 0x401: for compile time BRK instruction
*/
+#define FAULT_BRK_IMM 0x100
#define KGDB_DYN_DGB_BRK_IMM 0x400
#define KDBG_COMPILED_DBG_BRK_IMM 0x401
*/
#define AARCH64_BREAK_MON 0xd4200000
+/*
+ * BRK instruction for provoking a fault on purpose
+ * Unlike kgdb, #imm16 value with unallocated handler is used for faulting.
+ */
+#define AARCH64_BREAK_FAULT (AARCH64_BREAK_MON | (FAULT_BRK_IMM << 5))
+
/*
* Extract byte from BRK instruction
*/
#include <linux/smp.h>
#include <linux/stop_machine.h>
#include <linux/uaccess.h>
+
#include <asm/cacheflush.h>
+#include <asm/debug-monitors.h>
#include <asm/insn.h>
#define AARCH64_INSN_SF_BIT BIT(31)
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, reg);
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
insn = aarch64_insn_encode_ldst_size(size, insn);
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
BUG_ON(imm & ~(SZ_4K - 1));
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
BUG_ON(immr & ~mask);
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
BUG_ON(imm & ~(SZ_64K - 1));
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
insn |= (shift >> 4) << 21;
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}
switch (variant) {
break;
default:
BUG_ON(1);
+ return AARCH64_BREAK_FAULT;
}