aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/process.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@armlinux.org.uk>2016-05-13 06:40:20 -0400
committerRussell King <rmk+kernel@armlinux.org.uk>2016-07-07 11:01:01 -0400
commite6978e4bf181fb3b5f8cb6f71b4fe30fbf1b655c (patch)
treedddb20dbc9a5e594e406e71ed598039b33e0a4be /arch/arm/kernel/process.c
parentdd665be0e243873343a28e18f9f345927b658daf (diff)
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)
96 unsigned long flags; 96 unsigned long flags;
97 char buf[64]; 97 char buf[64];
98#ifndef CONFIG_CPU_V7M 98#ifndef CONFIG_CPU_V7M
99 unsigned int domain; 99 unsigned int domain, fs;
100#ifdef CONFIG_CPU_SW_DOMAIN_PAN 100#ifdef CONFIG_CPU_SW_DOMAIN_PAN
101 /* 101 /*
102 * Get the domain register for the parent context. In user 102 * Get the domain register for the parent context. In user
103 * mode, we don't save the DACR, so lets use what it should 103 * mode, we don't save the DACR, so lets use what it should
104 * be. For other modes, we place it after the pt_regs struct. 104 * be. For other modes, we place it after the pt_regs struct.
105 */ 105 */
106 if (user_mode(regs)) 106 if (user_mode(regs)) {
107 domain = DACR_UACCESS_ENABLE; 107 domain = DACR_UACCESS_ENABLE;
108 else 108 fs = get_fs();
109 } else {
109 domain = to_svc_pt_regs(regs)->dacr; 110 domain = to_svc_pt_regs(regs)->dacr;
111 fs = to_svc_pt_regs(regs)->addr_limit;
112 }
110#else 113#else
111 domain = get_domain(); 114 domain = get_domain();
115 fs = get_fs();
112#endif 116#endif
113#endif 117#endif
114 118
@@ -144,7 +148,7 @@ void __show_regs(struct pt_regs *regs)
144 if ((domain & domain_mask(DOMAIN_USER)) == 148 if ((domain & domain_mask(DOMAIN_USER)) ==
145 domain_val(DOMAIN_USER, DOMAIN_NOACCESS)) 149 domain_val(DOMAIN_USER, DOMAIN_NOACCESS))
146 segment = "none"; 150 segment = "none";
147 else if (get_fs() == get_ds()) 151 else if (fs == get_ds())
148 segment = "kernel"; 152 segment = "kernel";
149 else 153 else
150 segment = "user"; 154 segment = "user";