linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: kirill@shutemov.name (Kirill A. Shutemov)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFC PATCH 09/18] ARM: LPAE: Add fault handling support
Date: Mon, 25 Oct 2010 13:17:11 +0300	[thread overview]
Message-ID: <20101025101711.GA32026@shutemov.name> (raw)
In-Reply-To: <20101025090024.25275.59418.stgit@e102109-lin.cambridge.arm.com>

On Mon, Oct 25, 2010 at 10:00:24AM +0100, Catalin Marinas wrote:
> The DFSR and IFSR register format is different when LPAE is enabled. In
> addition, DFSR and IFSR have the similar definitions for the fault type.
> This modifies modifies the fault code to correctly handle the new
> format.
> 
> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
> ---
>  arch/arm/mm/alignment.c |    8 ++++-
>  arch/arm/mm/fault.c     |   80 +++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 87 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
> index 724ba3b..bc98a6e 100644
> --- a/arch/arm/mm/alignment.c
> +++ b/arch/arm/mm/alignment.c
> @@ -906,6 +906,12 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_ARM_LPAE
> +#define ALIGNMENT_FAULT		33
> +#else
> +#define ALIGNMENT_FAULT		1
> +#endif
> +
>  /*
>   * This needs to be done after sysctl_init, otherwise sys/ will be
>   * overwritten.  Actually, this shouldn't be in sys/ at all since
> @@ -939,7 +945,7 @@ static int __init alignment_init(void)
>  		ai_usermode = UM_FIXUP;
>  	}
>  
> -	hook_fault_code(1, do_alignment, SIGBUS, BUS_ADRALN,
> +	hook_fault_code(ALIGNMENT_FAULT, do_alignment, SIGBUS, BUS_ADRALN,
>  			"alignment exception");
>  
>  	/*
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index 2966897..b662aea 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -33,10 +33,15 @@
>  #define FSR_WRITE		(1 << 11)
>  #define FSR_FS4			(1 << 10)
>  #define FSR_FS3_0		(15)
> +#define FSR_FS5_0		(0x3f)
>  
>  static inline int fsr_fs(unsigned int fsr)
>  {
> +#ifdef CONFIG_ARM_LPAE
> +	return fsr & FSR_FS5_0;
> +#else
>  	return (fsr & FSR_FS3_0) | (fsr & FSR_FS4) >> 6;
> +#endif
>  }
>  
>  #ifdef CONFIG_MMU
> @@ -108,7 +113,9 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
>  
>  		pte = pte_offset_map(pmd, addr);
>  		printk(", *pte=%08lx", pte_val(*pte));
> +#ifndef CONFIG_ARM_LPAE
>  		printk(", *ppte=%08lx", pte_val(pte[-LINUX_PTE_OFFSET]));
> +#endif
>  		pte_unmap(pte);
>  	} while(0);
>  
> @@ -467,6 +474,72 @@ static struct fsr_info {
>  	int	code;
>  	const char *name;
>  } fsr_info[] = {
> +#ifdef CONFIG_ARM_LPAE
> +	{ do_bad,		SIGBUS,  0,		"unknown 0"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 1"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 2"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 3"			},
> +	{ do_bad,		SIGBUS,  0,		"reserved translation fault"	},
> +	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 1 translation fault"	},
> +	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"level 2 translation fault"	},
> +	{ do_page_fault,	SIGSEGV, SEGV_MAPERR,	"level 3 translation fault"	},
> +	{ do_bad,		SIGBUS,  0,		"reserved access flag fault"	},
> +	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 1 access flag fault"	},
> +	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 2 access flag fault"	},
> +	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 access flag fault"	},
> +	{ do_bad,		SIGBUS,  0,		"reserved permission fault"	},
> +	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"level 1 permission fault"	},
> +	{ do_sect_fault,	SIGSEGV, SEGV_ACCERR,	"level 2 permission fault"	},
> +	{ do_page_fault,	SIGSEGV, SEGV_ACCERR,	"level 3 permission fault"	},
> +	{ do_bad,		SIGBUS,  0,		"synchronous external abort"	},
> +	{ do_bad,		SIGBUS,  0,		"asynchronous external abort"	},
> +	{ do_bad,		SIGBUS,  0,		"unknown 18"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 19"			},
> +	{ do_bad,		SIGBUS,  0,		"synchronous abort (translation table walk)" },
> +	{ do_bad,		SIGBUS,  0,		"synchronous abort (translation table walk)" },
> +	{ do_bad,		SIGBUS,  0,		"synchronous abort (translation table walk)" },
> +	{ do_bad,		SIGBUS,  0,		"synchronous abort (translation table walk)" },
> +	{ do_bad,		SIGBUS,  0,		"synchronous parity error"	},
> +	{ do_bad,		SIGBUS,  0,		"asynchronous parity error"	},
> +	{ do_bad,		SIGBUS,  0,		"unknown 26"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 27"			},
> +	{ do_bad,		SIGBUS,  0,		"synchronous parity error (translation table walk" },
> +	{ do_bad,		SIGBUS,  0,		"synchronous parity error (translation table walk" },
> +	{ do_bad,		SIGBUS,  0,		"synchronous parity error (translation table walk" },
> +	{ do_bad,		SIGBUS,  0,		"synchronous parity error (translation table walk" },
> +	{ do_bad,		SIGBUS,  0,		"unknown 32"			},
> +	{ do_bad,		SIGILL,  BUS_ADRALN,	"alignment fault"		},

s/SIGILL/SIGBUS/

> +	{ do_bad,		SIGBUS,  0,		"debug event"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 35"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 36"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 37"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 38"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 39"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 40"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 41"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 42"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 43"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 44"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 45"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 46"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 47"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 48"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 49"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 50"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 51"			},
> +	{ do_bad,		SIGBUS,  0,		"implementation fault (lockdown abort)" },
> +	{ do_bad,		SIGBUS,  0,		"unknown 53"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 54"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 55"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 56"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 57"			},
> +	{ do_bad,		SIGBUS,  0,		"implementation fault (coprocessor abort)" },
> +	{ do_bad,		SIGBUS,  0,		"unknown 59"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 60"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 61"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 62"			},
> +	{ do_bad,		SIGBUS,  0,		"unknown 63"			},
> +#else	/* !CONFIG_ARM_LPAE */
>  	/*
>  	 * The following are the standard ARMv3 and ARMv4 aborts.  ARMv5
>  	 * defines these to be "precise" aborts.
> @@ -508,6 +581,7 @@ static struct fsr_info {
>  	{ do_bad,		SIGBUS,  0,		"unknown 29"			   },
>  	{ do_bad,		SIGBUS,  0,		"unknown 30"			   },
>  	{ do_bad,		SIGBUS,  0,		"unknown 31"			   }
> +#endif	/* CONFIG_ARM_LPAE */
>  };
>  
>  void __init
> @@ -546,6 +620,9 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  }
>  
>  
> +#ifdef CONFIG_ARM_LPAE
> +#define ifsr_info	fsr_info
> +#else	/* !CONFIG_ARM_LPAE */
>  static struct fsr_info ifsr_info[] = {
>  	{ do_bad,		SIGBUS,  0,		"unknown 0"			   },
>  	{ do_bad,		SIGBUS,  0,		"unknown 1"			   },
> @@ -580,6 +657,7 @@ static struct fsr_info ifsr_info[] = {
>  	{ do_bad,		SIGBUS,  0,		"unknown 30"			   },
>  	{ do_bad,		SIGBUS,  0,		"unknown 31"			   },
>  };
> +#endif	/* CONFIG_ARM_LPAE */
>  
>  asmlinkage void __exception
>  do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
> @@ -602,6 +680,7 @@ do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
>  
>  static int __init exceptions_init(void)
>  {
> +#ifndef CONFIG_ARM_LPAE
>  	if (cpu_architecture() >= CPU_ARCH_ARMv6) {
>  		hook_fault_code(4, do_translation_fault, SIGSEGV, SEGV_MAPERR,
>  				"I-cache maintenance fault");
> @@ -617,6 +696,7 @@ static int __init exceptions_init(void)
>  		hook_fault_code(6, do_bad, SIGSEGV, SEGV_MAPERR,
>  				"section access flag fault");
>  	}
> +#endif
>  
>  	return 0;
>  }
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
 Kirill A. Shutemov

  reply	other threads:[~2010-10-25 10:17 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-10-25  8:59 [RFC PATCH 00/18] ARM: Add support for the Large Physical Address Extensions Catalin Marinas
2010-10-25  8:59 ` [RFC PATCH 01/18] ARM: LPAE: Use PMD_(SHIFT|SIZE|MASK) instead of PGDIR_* Catalin Marinas
2010-10-25  8:59 ` [RFC PATCH 02/18] ARM: LPAE: Factor out 2-level page table definitions into separate files Catalin Marinas
2010-10-25  8:59 ` [RFC PATCH 03/18] ARM: LPAE: use u32 instead of unsigned long for 32-bit ptes Catalin Marinas
2010-10-25  8:59 ` [RFC PATCH 04/18] ARM: LPAE: Do not assume Linux PTEs are always at PTRS_PER_PTE offset Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 05/18] ARM: LPAE: Introduce L_PTE_NOEXEC and L_PTE_NOWRITE Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 06/18] ARM: LPAE: Introduce the 3-level page table format definitions Catalin Marinas
2010-10-25 11:15   ` Arnd Bergmann
2010-10-25 11:59     ` Catalin Marinas
2010-10-25 13:25       ` Arnd Bergmann
2010-10-25 16:18         ` Catalin Marinas
2010-10-25 18:25           ` Arnd Bergmann
2010-12-06  9:27             ` Christoffer Dall
2010-12-06 14:21               ` Arnd Bergmann
2010-10-25  9:00 ` [RFC PATCH 07/18] ARM: LPAE: Page table maintenance for the 3-level format Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 08/18] ARM: LPAE: MMU setup for the 3-level page table format Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 09/18] ARM: LPAE: Add fault handling support Catalin Marinas
2010-10-25 10:17   ` Kirill A. Shutemov [this message]
2010-10-25 10:35     ` Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 10/18] ARM: LPAE: Add context switching support Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 11/18] ARM: LPAE: Add SMP support for the 3-level page table format Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 12/18] ARM: LPAE: use phys_addr_t instead of unsigned long for physical addresses Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 13/18] ARM: LPAE: ensure dma_addr_t is the same size as phys_addr_t Catalin Marinas
2010-10-25 11:08   ` Arnd Bergmann
2010-10-25 11:32     ` Catalin Marinas
2010-10-25 12:01       ` FUJITA Tomonori
2010-10-25 12:31         ` Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 14/18] ARM: LPAE: mark memory banks with start > ULONG_MAX as highmem Catalin Marinas
2010-10-25  9:00 ` [RFC PATCH 15/18] ARM: LPAE: use phys_addr_t for physical start address in early_mem Catalin Marinas
2010-10-25  9:01 ` [RFC PATCH 16/18] ARM: LPAE: add support for ATAG_MEM64 Catalin Marinas
2010-10-25  9:01 ` [RFC PATCH 17/18] ARM: LPAE: define printk format for physical addresses and page table entries Catalin Marinas
2010-10-25 12:01   ` Kirill A. Shutemov
2010-10-25  9:01 ` [RFC PATCH 18/18] ARM: LPAE: Add the Kconfig entries Catalin Marinas

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=20101025101711.GA32026@shutemov.name \
    --to=kirill@shutemov.name \
    --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).