All of lore.kernel.org
 help / color / mirror / Atom feed
From: taras.kondratiuk@linaro.org (Taras Kondratiuk)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 14/15] ARM: add uprobes support
Date: Wed, 04 Dec 2013 19:23:02 +0200	[thread overview]
Message-ID: <529F64F6.6010209@linaro.org> (raw)
In-Reply-To: <1385520814-10663-15-git-send-email-dave.long@linaro.org>

On 11/27/2013 04:53 AM, David Long wrote:
> From: "David A. Long" <dave.long@linaro.org>
> 
> Using Rabin Vincent's ARM uprobes patches as a base, enable uprobes
> support on ARM.
> 
> Caveats:
> 
>  - Thumb is not supported
>  - XOL abort/trap handling is not implemented
> 
> Signed-off-by: David A. Long <dave.long@linaro.org>
> ---
>  arch/arm/Kconfig                   |   4 +
>  arch/arm/include/asm/ptrace.h      |   6 +
>  arch/arm/include/asm/thread_info.h |   5 +-
>  arch/arm/include/asm/uprobes.h     |  34 ++++++
>  arch/arm/kernel/Makefile           |   1 +
>  arch/arm/kernel/signal.c           |   4 +
>  arch/arm/kernel/uprobes-arm.c      | 223 +++++++++++++++++++++++++++++++++++++
>  arch/arm/kernel/uprobes.c          | 198 ++++++++++++++++++++++++++++++++
>  arch/arm/kernel/uprobes.h          |  27 +++++
>  9 files changed, 501 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/include/asm/uprobes.h
>  create mode 100644 arch/arm/kernel/uprobes-arm.c
>  create mode 100644 arch/arm/kernel/uprobes.c
>  create mode 100644 arch/arm/kernel/uprobes.h
> 

[snip]

> diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/kernel/uprobes-arm.c
> new file mode 100644
> index 0000000..0a83ad7
> --- /dev/null
> +++ b/arch/arm/kernel/uprobes-arm.c
> @@ -0,0 +1,223 @@
> +#include <linux/kernel.h>
> +#include <linux/wait.h>
> +#include <linux/uprobes.h>
> +#include <linux/module.h>
> +
> +#include "probes.h"
> +#include "probes-arm.h"
> +#include "uprobes.h"
> +
> +static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
> +{
> +	probes_opcode_t insn = *pinsn;

In a current implementation pinsn points to an ixol field of arch_uprobe
structure, which has native endianness and is written via
__opcode_to_mem_arm() macro in arch_uprobe_analyze_insn() function.
So *pinsn should be wrapped with __opcode_to_mem_arm/__mem_to_opcode_arm()
macros in this function.

> +	probes_opcode_t temp;
> +	probes_opcode_t mask;
> +	int freereg;
> +	u32 free = 0xffff;
> +	u32 regs;
> +
> +	for (regs = oregs; regs; regs >>= 4, insn >>= 4) {
> +		if ((regs & 0xf) == REG_TYPE_NONE)
> +			continue;
> +
> +		free &= ~(1 << (insn & 0xf));
> +	}
> +
> +	/* No PC, no problem */
> +	if (free & (1 << 15))
> +		return 15;
> +
> +	if (!free)
> +		return -1;
> +
> +	/*
> +	 * fls instead of ffs ensures that for "ldrd r0, r1, [pc]" we would
> +	 * pick LR instead of R1.
> +	 */
> +	freereg = free = fls(free) - 1;
> +
> +	temp = *pinsn;
> +	insn = *pinsn;
> +	regs = oregs;
> +	mask = 0xf;
> +
> +	for (; regs; regs >>= 4, mask <<= 4, free <<= 4, temp >>= 4) {
> +		if ((regs & 0xf) == REG_TYPE_NONE)
> +			continue;
> +
> +		if ((temp & 0xf) != 15)
> +			continue;
> +
> +		insn &= ~mask;
> +		insn |= free & mask;
> +	}
> +
> +	*pinsn = insn;
> +	return freereg;
> +}
> +

[snip]

> +
> +enum probes_insn
> +uprobe_decode_ldmstm(probes_opcode_t insn,
> +		     struct arch_specific_insn *asi, struct decode_header *d)
> +{
> +	struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
> +						   asi);
> +	unsigned reglist = insn & 0xffff;
> +	int rn = (insn >> 16) & 0xf;
> +	int lbit = insn & (1 << 20);
> +	unsigned used = reglist | (1 << rn);
> +
> +	if (rn == 15)
> +		return INSN_REJECTED;
> +
> +	if (!(used & (1 << 15)))
> +		return INSN_GOOD;
> +
> +	if (used & (1 << 14))
> +		return INSN_REJECTED;
> +
> +	/* Use LR instead of PC */
> +	insn ^= 0xc000;
> +
> +	auprobe->pcreg = 14;
> +	auprobe->ixol[0] = insn;

insn contains canonical opcode, but ixol should contain
an opcode in native endianness. So it should be

auprobe->ixol[0] = __opcode_to_mem_arm(insn);

> +
> +	auprobe->prehandler = uprobe_set_pc;
> +	if (lbit)
> +		auprobe->posthandler = uprobe_write_pc;
> +	else
> +		auprobe->posthandler = uprobe_unset_pc;
> +
> +	return INSN_GOOD;
> +}
> +


-- 
Taras Kondratiuk

WARNING: multiple messages have this Message-ID (diff)
From: Taras Kondratiuk <taras.kondratiuk@linaro.org>
To: David Long <dave.long@linaro.org>
Cc: linux-arm-kernel@lists.infradead.org,
	Russell King <linux@arm.linux.org.uk>,
	Rabin Vincent <rabin@rab.in>,
	"Jon Medhurst (Tixy)" <tixy@linaro.org>,
	Oleg Nesterov <oleg@redhat.com>,
	Srikar Dronamraju <srikar@linux.vnet.ibm.com>,
	Ingo Molnar <mingo@redhat.com>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
	Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>,
	davem@davemloft.net, Peter Zijlstra <a.p.zijlstra@chello.nl>,
	Paul Mackerras <paulus@samba.org>,
	Arnaldo Carvalho de Melo <acme@ghostprotocols.net>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3 14/15] ARM: add uprobes support
Date: Wed, 04 Dec 2013 19:23:02 +0200	[thread overview]
Message-ID: <529F64F6.6010209@linaro.org> (raw)
In-Reply-To: <1385520814-10663-15-git-send-email-dave.long@linaro.org>

On 11/27/2013 04:53 AM, David Long wrote:
> From: "David A. Long" <dave.long@linaro.org>
> 
> Using Rabin Vincent's ARM uprobes patches as a base, enable uprobes
> support on ARM.
> 
> Caveats:
> 
>  - Thumb is not supported
>  - XOL abort/trap handling is not implemented
> 
> Signed-off-by: David A. Long <dave.long@linaro.org>
> ---
>  arch/arm/Kconfig                   |   4 +
>  arch/arm/include/asm/ptrace.h      |   6 +
>  arch/arm/include/asm/thread_info.h |   5 +-
>  arch/arm/include/asm/uprobes.h     |  34 ++++++
>  arch/arm/kernel/Makefile           |   1 +
>  arch/arm/kernel/signal.c           |   4 +
>  arch/arm/kernel/uprobes-arm.c      | 223 +++++++++++++++++++++++++++++++++++++
>  arch/arm/kernel/uprobes.c          | 198 ++++++++++++++++++++++++++++++++
>  arch/arm/kernel/uprobes.h          |  27 +++++
>  9 files changed, 501 insertions(+), 1 deletion(-)
>  create mode 100644 arch/arm/include/asm/uprobes.h
>  create mode 100644 arch/arm/kernel/uprobes-arm.c
>  create mode 100644 arch/arm/kernel/uprobes.c
>  create mode 100644 arch/arm/kernel/uprobes.h
> 

[snip]

> diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/kernel/uprobes-arm.c
> new file mode 100644
> index 0000000..0a83ad7
> --- /dev/null
> +++ b/arch/arm/kernel/uprobes-arm.c
> @@ -0,0 +1,223 @@
> +#include <linux/kernel.h>
> +#include <linux/wait.h>
> +#include <linux/uprobes.h>
> +#include <linux/module.h>
> +
> +#include "probes.h"
> +#include "probes-arm.h"
> +#include "uprobes.h"
> +
> +static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
> +{
> +	probes_opcode_t insn = *pinsn;

In a current implementation pinsn points to an ixol field of arch_uprobe
structure, which has native endianness and is written via
__opcode_to_mem_arm() macro in arch_uprobe_analyze_insn() function.
So *pinsn should be wrapped with __opcode_to_mem_arm/__mem_to_opcode_arm()
macros in this function.

> +	probes_opcode_t temp;
> +	probes_opcode_t mask;
> +	int freereg;
> +	u32 free = 0xffff;
> +	u32 regs;
> +
> +	for (regs = oregs; regs; regs >>= 4, insn >>= 4) {
> +		if ((regs & 0xf) == REG_TYPE_NONE)
> +			continue;
> +
> +		free &= ~(1 << (insn & 0xf));
> +	}
> +
> +	/* No PC, no problem */
> +	if (free & (1 << 15))
> +		return 15;
> +
> +	if (!free)
> +		return -1;
> +
> +	/*
> +	 * fls instead of ffs ensures that for "ldrd r0, r1, [pc]" we would
> +	 * pick LR instead of R1.
> +	 */
> +	freereg = free = fls(free) - 1;
> +
> +	temp = *pinsn;
> +	insn = *pinsn;
> +	regs = oregs;
> +	mask = 0xf;
> +
> +	for (; regs; regs >>= 4, mask <<= 4, free <<= 4, temp >>= 4) {
> +		if ((regs & 0xf) == REG_TYPE_NONE)
> +			continue;
> +
> +		if ((temp & 0xf) != 15)
> +			continue;
> +
> +		insn &= ~mask;
> +		insn |= free & mask;
> +	}
> +
> +	*pinsn = insn;
> +	return freereg;
> +}
> +

[snip]

> +
> +enum probes_insn
> +uprobe_decode_ldmstm(probes_opcode_t insn,
> +		     struct arch_specific_insn *asi, struct decode_header *d)
> +{
> +	struct arch_uprobe *auprobe = container_of(asi, struct arch_uprobe,
> +						   asi);
> +	unsigned reglist = insn & 0xffff;
> +	int rn = (insn >> 16) & 0xf;
> +	int lbit = insn & (1 << 20);
> +	unsigned used = reglist | (1 << rn);
> +
> +	if (rn == 15)
> +		return INSN_REJECTED;
> +
> +	if (!(used & (1 << 15)))
> +		return INSN_GOOD;
> +
> +	if (used & (1 << 14))
> +		return INSN_REJECTED;
> +
> +	/* Use LR instead of PC */
> +	insn ^= 0xc000;
> +
> +	auprobe->pcreg = 14;
> +	auprobe->ixol[0] = insn;

insn contains canonical opcode, but ixol should contain
an opcode in native endianness. So it should be

auprobe->ixol[0] = __opcode_to_mem_arm(insn);

> +
> +	auprobe->prehandler = uprobe_set_pc;
> +	if (lbit)
> +		auprobe->posthandler = uprobe_write_pc;
> +	else
> +		auprobe->posthandler = uprobe_unset_pc;
> +
> +	return INSN_GOOD;
> +}
> +


-- 
Taras Kondratiuk

  reply	other threads:[~2013-12-04 17:23 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-27  2:53 [PATCH v3 00/15] uprobes: Add uprobes support for ARM David Long
2013-11-27  2:53 ` David Long
2013-11-27  2:53 ` [PATCH v3 01/15] uprobes: allow ignoring of probe hits David Long
2013-11-27  2:53   ` David Long
2013-11-28 18:41   ` Oleg Nesterov
2013-11-28 18:41     ` Oleg Nesterov
2013-11-27  2:53 ` [PATCH v3 02/15] ARM: move shared uprobe/kprobe definitions into new include file David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 03/15] ARM: Move generic arm instruction parsing code to new files for sharing between features David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 04/15] ARM: move generic thumb instruction parsing code to new files for use by other feature David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 05/15] ARM: use a function table for determining instruction interpreter actions David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 06/15] ARM: Disable jprobes test when built into thumb-mode kernel David Long
2013-11-27  2:53   ` David Long
2013-11-27 10:16   ` Masami Hiramatsu
2013-11-27 10:16     ` Masami Hiramatsu
2013-11-27 10:41     ` Jon Medhurst (Tixy)
2013-11-27  2:53 ` [PATCH v3 07/15] ARM: Remove use of struct kprobe from generic probes code David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 08/15] ARM: Use new opcode type in ARM kprobes/uprobes code David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 09/15] ARM: Make the kprobes condition_check symbol names more generic David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 10/15] ARM: Change more ARM kprobes symbol names to something more David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 11/15] ARM: Rename the shared kprobes/uprobe return value enum David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 12/15] ARM: Change the remaining shared kprobes/uprobes symbols to something generic David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 13/15] ARM: Add an emulate flag to the kprobes/uprobes instruction decode functions David Long
2013-11-27  2:53   ` David Long
2013-11-27  2:53 ` [PATCH v3 14/15] ARM: add uprobes support David Long
2013-11-27  2:53   ` David Long
2013-12-04 17:23   ` Taras Kondratiuk [this message]
2013-12-04 17:23     ` Taras Kondratiuk
2013-11-27  2:53 ` [PATCH v3 15/15] ARM: Remove uprobes dependency on kprobes David Long
2013-11-27  2:53   ` David Long
2013-12-04 17:51 ` [PATCH v3 00/15] uprobes: Add uprobes support for ARM Taras Kondratiuk
2013-12-04 17:51   ` Taras Kondratiuk
2013-12-05 19:48   ` David Long
2013-12-05 19:48     ` David Long
2013-12-05 20:17   ` David Long
2013-12-05 20:17     ` David Long
2013-12-20 16:10     ` Jon Medhurst (Tixy)
2013-12-20 16:10       ` Jon Medhurst (Tixy)

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=529F64F6.6010209@linaro.org \
    --to=taras.kondratiuk@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.