Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd9648df authored by Anton Blanchard's avatar Anton Blanchard Committed by Paul Mackerras
Browse files

[PATCH] ppc64: Add ptrace data breakpoint support



Add hardware data breakpoint support.

Signed-off-by: default avatarAnton Blanchard <anton@samba.org>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent a94d3085
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@
#include <asm/sections.h>
#include <asm/tlbflush.h>
#include <asm/time.h>
#include <asm/plpar_wrappers.h>

#ifndef CONFIG_SMP
struct task_struct *last_task_used_math = NULL;
@@ -163,7 +164,30 @@ int dump_task_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)

#endif /* CONFIG_ALTIVEC */

static void set_dabr_spr(unsigned long val)
{
	mtspr(SPRN_DABR, val);
}

int set_dabr(unsigned long dabr)
{
	int ret = 0;

	if (firmware_has_feature(FW_FEATURE_XDABR)) {
		/* We want to catch accesses from kernel and userspace */
		unsigned long flags = H_DABRX_KERNEL|H_DABRX_USER;
		ret = plpar_set_xdabr(dabr, flags);
	} else if (firmware_has_feature(FW_FEATURE_DABR)) {
		ret = plpar_set_dabr(dabr);
	} else {
		set_dabr_spr(dabr);
	}

	return ret;
}

DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
static DEFINE_PER_CPU(unsigned long, current_dabr);

struct task_struct *__switch_to(struct task_struct *prev,
				struct task_struct *new)
@@ -198,6 +222,11 @@ struct task_struct *__switch_to(struct task_struct *prev,
		new->thread.regs->msr |= MSR_VEC;
#endif /* CONFIG_ALTIVEC */

	if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
		set_dabr(new->thread.dabr);
		__get_cpu_var(current_dabr) = new->thread.dabr;
	}

	flush_tlb_pending();

	new_thread = &new->thread;
@@ -334,6 +363,11 @@ void flush_thread(void)
		last_task_used_altivec = NULL;
#endif /* CONFIG_ALTIVEC */
#endif /* CONFIG_SMP */

	if (current->thread.dabr) {
		current->thread.dabr = 0;
		set_dabr(0);
	}
}

void
+13 −0
Original line number Diff line number Diff line
@@ -207,6 +207,19 @@ int sys_ptrace(long request, long pid, long addr, long data)
		break;
	}

	case PTRACE_GET_DEBUGREG: {
		ret = -EINVAL;
		/* We only support one DABR and no IABRS at the moment */
		if (addr > 0)
			break;
		ret = put_user(child->thread.dabr,
			       (unsigned long __user *)data);
		break;
	}

	case PTRACE_SET_DEBUGREG:
		ret = ptrace_set_debugreg(child, addr, data);

	case PTRACE_DETACH:
		ret = ptrace_detach(child, data);
		break;
+13 −0
Original line number Diff line number Diff line
@@ -338,6 +338,19 @@ int sys32_ptrace(long request, long pid, unsigned long addr, unsigned long data)
		break;
	}

	case PTRACE_GET_DEBUGREG: {
		ret = -EINVAL;
		/* We only support one DABR and no IABRS at the moment */
		if (addr > 0)
			break;
		ret = put_user(child->thread.dabr, (u32 __user *)data);
		break;
	}

	case PTRACE_SET_DEBUGREG:
		ret = ptrace_set_debugreg(child, addr, data);
		break;

	case PTRACE_DETACH:
		ret = ptrace_detach(child, data);
		break;
+0 −2
Original line number Diff line number Diff line
@@ -59,8 +59,6 @@ char mce_data_buf[RTAS_ERROR_LOG_MAX]
/* This is true if we are using the firmware NMI handler (typically LPAR) */
extern int fwnmi_active;

extern void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);

static int ras_get_sensor_state_token;
static int ras_check_exception_token;

+9 −0
Original line number Diff line number Diff line
@@ -550,6 +550,15 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
		/* Whee!  Actually deliver the signal.  */
		if (TRAP(regs) == 0x0C00)
			syscall_restart(regs, &ka);

		/*
		 * Reenable the DABR before delivering the signal to
		 * user space. The DABR will have been cleared if it
		 * triggered inside the kernel.
		 */
		if (current->thread.dabr)
			set_dabr(current->thread.dabr);

		return handle_signal(signr, &ka, &info, oldset, regs);
	}

Loading