aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/process.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2016-05-13 11:40:20 +0100
committerRussell King <rmk+kernel@armlinux.org.uk>2016-07-07 16:01:01 +0100
commite6978e4bf181fb3b5f8cb6f71b4fe30fbf1b655c (patch)
treedddb20dbc9a5e594e406e71ed598039b33e0a4be /arch/arm/kernel/process.c
parentARM: 8584/1: floppy: avoid gcc-6 warning (diff)
downloadlinux-dev-e6978e4bf181fb3b5f8cb6f71b4fe30fbf1b655c.tar.xz
linux-dev-e6978e4bf181fb3b5f8cb6f71b4fe30fbf1b655c.zip
ARM: save and reset the address limit when entering an exception
When we enter an exception, the current address limit should not apply to the exception context: if the exception context wishes to access kernel space via the user accessors (eg, perf code), it must explicitly request such access. Acked-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'arch/arm/kernel/process.c')
-rw-r--r--arch/arm/kernel/process.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index f1c720c0d568..612eb530f33f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -96,19 +96,23 @@ void __show_regs(struct pt_regs *regs)
unsigned long flags;
char buf[64];
#ifndef CONFIG_CPU_V7M
- unsigned int domain;
+ unsigned int domain, fs;
#ifdef CONFIG_CPU_SW_DOMAIN_PAN
/*
* Get the domain register for the parent context. In user
* mode, we don't save the DACR, so lets use what it should
* be. For other modes, we place it after the pt_regs struct.
*/
- if (user_mode(regs))
+ if (user_mode(regs)) {
domain = DACR_UACCESS_ENABLE;
- else
+ fs = get_fs();
+ } else {
domain = to_svc_pt_regs(regs)->dacr;
+ fs = to_svc_pt_regs(regs)->addr_limit;
+ }
#else
domain = get_domain();
+ fs = get_fs();
#endif
#endif
@@ -144,7 +148,7 @@ void __show_regs(struct pt_regs *regs)
if ((domain & domain_mask(DOMAIN_USER)) ==
domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
segment = "none";
- else if (get_fs() == get_ds())
+ else if (fs == get_ds())
segment = "kernel";
else
segment = "user";