@@ -34,8 +34,12 @@ struct arch_hw_breakpoint {
static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl)
{
- return (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
+ u32 reg = (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) |
ctrl.enabled;
+ /* set HMC and SSC when debug target is EL2 */
+ if (ctrl.privilege == AARCH64_BREAKPOINT_EL2)
+ reg |= (3 << 14) | (1 << 13);
+ return reg
}
static inline void decode_ctrl_reg(u32 reg,
@@ -59,6 +63,7 @@ static inline void decode_ctrl_reg(u32 reg,
#define AARCH64_ESR_ACCESS_MASK (1 << 6)
/* Privilege Levels */
+#define AARCH64_BREAKPOINT_EL2 0
#define AARCH64_BREAKPOINT_EL1 1
#define AARCH64_BREAKPOINT_EL0 2
@@ -162,6 +162,7 @@ static enum debug_el debug_exception_level(int privilege)
case AARCH64_BREAKPOINT_EL0:
return DBG_ACTIVE_EL0;
case AARCH64_BREAKPOINT_EL1:
+ case AARCH64_BREAKPOINT_EL2:
return DBG_ACTIVE_EL1;
default:
pr_warning("invalid breakpoint privilege level %d\n", privilege);
@@ -456,7 +457,8 @@ static int arch_build_bp_info(struct perf_event *bp)
* that would complicate the stepping code.
*/
if (arch_check_bp_in_kernelspace(bp))
- info->ctrl.privilege = AARCH64_BREAKPOINT_EL1;
+ info->ctrl.privilege = is_kernel_in_hyp_mode() ?
+ AARCH64_BREAKPOINT_EL2 : AARCH64_BREAKPOINT_EL1;
else
info->ctrl.privilege = AARCH64_BREAKPOINT_EL0;
@@ -526,7 +528,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
* Disallow per-task kernel breakpoints since these would
* complicate the stepping code.
*/
- if (info->ctrl.privilege == AARCH64_BREAKPOINT_EL1 && bp->hw.target)
+ if (info->ctrl.privilege != AARCH64_BREAKPOINT_EL0 && bp->hw.target)
return -EINVAL;
return 0;