linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/4] ARM: context tracking: add exception support
Date: Thu, 21 Mar 2013 21:49:08 +0000	[thread overview]
Message-ID: <20130321214908.GU4977@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <1363824121-26169-2-git-send-email-khilman@linaro.org>

On Wed, Mar 20, 2013 at 05:01:58PM -0700, Kevin Hilman wrote:
> Add ARM support for the context tracking subsystem by instrumenting
> exception entry/exit points.
> 
> Special thanks to Mats Liljegren for testing, collaboration and adding
> support for exceptions/faults that were missing in early test versions.

Not sure all of these are a good idea or are correct...

> @@ -405,7 +406,9 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
>  	unsigned int instr;
>  	siginfo_t info;
>  	void __user *pc;
> +	enum ctx_state prev_state;
>  
> +	prev_state = exception_enter();
>  	pc = (void __user *)instruction_pointer(regs);
>  
>  	if (processor_mode(regs) == SVC_MODE) {
> @@ -433,8 +436,10 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
>  		goto die_sig;
>  	}
>  
> -	if (call_undef_hook(regs, instr) == 0)
> +	if (call_undef_hook(regs, instr) == 0) {
> +		exception_exit(prev_state);
>  		return;
> +	}
>  
>  die_sig:
>  #ifdef CONFIG_DEBUG_USER
> @@ -451,12 +456,17 @@ die_sig:
>  	info.si_addr  = pc;
>  
>  	arm_notify_die("Oops - undefined instruction", regs, &info, 0, 6);
> +	exception_exit(prev_state);

So, FP emulation and VFP support happens via a separate path.  Does this
also need to be instrumented?

>  }
>  
>  asmlinkage void do_unexp_fiq (struct pt_regs *regs)
>  {
> +	enum ctx_state prev_state;
> +
> +	prev_state = exception_enter();
>  	printk("Hmm.  Unexpected FIQ received, but trying to continue\n");
>  	printk("You may have a hardware problem...\n");
> +	exception_exit(prev_state);

Not a good idea.  If we get here chances are things are really broken.

>  }
>  
>  /*
> @@ -467,6 +477,9 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs)
>   */
>  asmlinkage void bad_mode(struct pt_regs *regs, int reason)
>  {
> +	enum ctx_state prev_state;
> +
> +	prev_state = exception_enter();
>  	console_verbose();
>  
>  	printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]);

Same here.  If we get here, we're probably about to die a horrid death.

> @@ -746,7 +759,9 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
>  {
>  	unsigned long addr = instruction_pointer(regs);
>  	siginfo_t info;
> +	enum ctx_state prev_state;
>  
> +	prev_state = exception_enter();
>  #ifdef CONFIG_DEBUG_USER
>  	if (user_debug & UDBG_BADABORT) {
>  		printk(KERN_ERR "[%d] %s: bad data abort: code %d instr 0x%08lx\n",
> @@ -762,6 +777,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs)
>  	info.si_addr  = (void __user *)addr;
>  
>  	arm_notify_die("unknown data abort code", regs, &info, instr, 0);
> +	exception_exit(prev_state);
>  }
>  
>  void __readwrite_bug(const char *fn)
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index 5dbf13f..759b70d 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -19,6 +19,7 @@
>  #include <linux/sched.h>
>  #include <linux/highmem.h>
>  #include <linux/perf_event.h>
> +#include <linux/context_tracking.h>
>  
>  #include <asm/exception.h>
>  #include <asm/pgtable.h>
> @@ -424,9 +425,15 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
>  	pgd_t *pgd, *pgd_k;
>  	pud_t *pud, *pud_k;
>  	pmd_t *pmd, *pmd_k;
> -
> -	if (addr < TASK_SIZE)
> -		return do_page_fault(addr, fsr, regs);
> +	enum ctx_state prev_state;
> +
> +	prev_state = exception_enter();
> +	if (addr < TASK_SIZE) {
> +		int ret;
> +		ret = do_page_fault(addr, fsr, regs);
> +		exception_exit(prev_state);
> +		return ret;
> +	}
>  
>  	if (user_mode(regs))
>  		goto bad_area;
> @@ -472,10 +479,12 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
>  		goto bad_area;
>  
>  	copy_pmd(pmd, pmd_k);
> +	exception_exit(prev_state);
>  	return 0;
>  
>  bad_area:
>  	do_bad_area(addr, fsr, regs);
> +	exception_exit(prev_state);
>  	return 0;
>  }
>  #else					/* CONFIG_MMU */
> @@ -494,7 +503,12 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
>  static int
>  do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  {
> +	enum ctx_state prev_state;
> +
> +	prev_state = exception_enter();
>  	do_bad_area(addr, fsr, regs);
> +	exception_exit(prev_state);
> +
>  	return 0;
>  }
>  
> @@ -542,9 +556,11 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  {
>  	const struct fsr_info *inf = fsr_info + fsr_fs(fsr);
>  	struct siginfo info;
> +	enum ctx_state prev_state;
>  
> +	prev_state = exception_enter();
>  	if (!inf->fn(addr, fsr & ~FSR_LNX_PF, regs))
> -		return;
> +		goto out;
>  
>  	printk(KERN_ALERT "Unhandled fault: %s (0x%03x) at 0x%08lx\n",
>  		inf->name, fsr, addr);
> @@ -554,6 +570,8 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  	info.si_code  = inf->code;
>  	info.si_addr  = (void __user *)addr;
>  	arm_notify_die("", regs, &info, fsr, 0);
> +out:
> +	exception_exit(prev_state);
>  }
>  
>  void __init
> @@ -574,9 +592,11 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
>  {
>  	const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
>  	struct siginfo info;
> +	enum ctx_state prev_state;
>  
> +	prev_state = exception_enter();
>  	if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
> -		return;
> +		goto out;
>  
>  	printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
>  		inf->name, ifsr, addr);
> @@ -586,6 +606,8 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
>  	info.si_code  = inf->code;
>  	info.si_addr  = (void __user *)addr;
>  	arm_notify_die("", regs, &info, ifsr, 0);
> +out:
> +	exception_exit(prev_state);
>  }
>  
>  #ifndef CONFIG_ARM_LPAE

What is the reason for putting all this in the individual functions
and not in the prefetch/data abort handlers -
do_PrefetchAbort()/do_DataAbort()?

  reply	other threads:[~2013-03-21 21:49 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-21  0:01 [PATCH 0/4] ARM: add support for context tracking subsystem Kevin Hilman
2013-03-21  0:01 ` [PATCH 1/4] ARM: context tracking: add exception support Kevin Hilman
2013-03-21 21:49   ` Russell King - ARM Linux [this message]
2013-03-22  0:33     ` Kevin Hilman
2013-03-26  0:28     ` Kevin Hilman
2013-03-21  0:01 ` [PATCH 2/4] ARM: context tracking: instrument system calls Kevin Hilman
2013-03-21  0:02 ` [PATCH 3/4] ARM: context tracking: handle post exception/syscall/IRQ work Kevin Hilman
2013-03-21  0:02 ` [PATCH 4/4] ARM: Kconfig: allow context tracking Kevin Hilman

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=20130321214908.GU4977@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).