diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-08-19 16:23:48 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2015-08-21 08:55:49 -0400 |
commit | 1eef5d2f1b461c120bcd82077edee5ec706ac53b (patch) | |
tree | b95a7132189a44d9a826e7b44fbbe5cae74d75fb | |
parent | d770e558e21961ad6cfdf0ff7df0eb5d7d4f0754 (diff) |
ARM: domains: switch to keeping domain value in register
Rather than modifying both the domain access control register and our
per-thread copy, modify only the domain access control register, and
use the per-thread copy to save and restore the register over context
switches. We can also avoid the explicit initialisation of the
init thread_info structure.
This allows us to avoid needing to gain access to the thread information
at the uaccess control sites.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r-- | arch/arm/include/asm/domain.h | 20 | ||||
-rw-r--r-- | arch/arm/include/asm/thread_info.h | 3 | ||||
-rw-r--r-- | arch/arm/kernel/entry-armv.S | 2 | ||||
-rw-r--r-- | arch/arm/kernel/process.c | 13 |
4 files changed, 27 insertions, 11 deletions
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h index 6ddbe446425e..7f2941905714 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h | |||
@@ -59,6 +59,17 @@ | |||
59 | 59 | ||
60 | #ifndef __ASSEMBLY__ | 60 | #ifndef __ASSEMBLY__ |
61 | 61 | ||
62 | static inline unsigned int get_domain(void) | ||
63 | { | ||
64 | unsigned int domain; | ||
65 | |||
66 | asm( | ||
67 | "mrc p15, 0, %0, c3, c0 @ get domain" | ||
68 | : "=r" (domain)); | ||
69 | |||
70 | return domain; | ||
71 | } | ||
72 | |||
62 | #ifdef CONFIG_CPU_USE_DOMAINS | 73 | #ifdef CONFIG_CPU_USE_DOMAINS |
63 | static inline void set_domain(unsigned val) | 74 | static inline void set_domain(unsigned val) |
64 | { | 75 | { |
@@ -70,11 +81,10 @@ static inline void set_domain(unsigned val) | |||
70 | 81 | ||
71 | #define modify_domain(dom,type) \ | 82 | #define modify_domain(dom,type) \ |
72 | do { \ | 83 | do { \ |
73 | struct thread_info *thread = current_thread_info(); \ | 84 | unsigned int domain = get_domain(); \ |
74 | unsigned int domain = thread->cpu_domain; \ | 85 | domain &= ~domain_val(dom, DOMAIN_MANAGER); \ |
75 | domain &= ~domain_val(dom, DOMAIN_MANAGER); \ | 86 | domain = domain | domain_val(dom, type); \ |
76 | thread->cpu_domain = domain | domain_val(dom, type); \ | 87 | set_domain(domain); \ |
77 | set_domain(thread->cpu_domain); \ | ||
78 | } while (0) | 88 | } while (0) |
79 | 89 | ||
80 | #else | 90 | #else |
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index bd32eded3e50..0a0aec410d8c 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h | |||
@@ -74,9 +74,6 @@ struct thread_info { | |||
74 | .flags = 0, \ | 74 | .flags = 0, \ |
75 | .preempt_count = INIT_PREEMPT_COUNT, \ | 75 | .preempt_count = INIT_PREEMPT_COUNT, \ |
76 | .addr_limit = KERNEL_DS, \ | 76 | .addr_limit = KERNEL_DS, \ |
77 | .cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \ | ||
78 | domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \ | ||
79 | domain_val(DOMAIN_IO, DOMAIN_CLIENT), \ | ||
80 | } | 77 | } |
81 | 78 | ||
82 | #define init_thread_info (init_thread_union.thread_info) | 79 | #define init_thread_info (init_thread_union.thread_info) |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 7dac3086e361..d19adcf6c580 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -770,6 +770,8 @@ ENTRY(__switch_to) | |||
770 | ldr r4, [r2, #TI_TP_VALUE] | 770 | ldr r4, [r2, #TI_TP_VALUE] |
771 | ldr r5, [r2, #TI_TP_VALUE + 4] | 771 | ldr r5, [r2, #TI_TP_VALUE + 4] |
772 | #ifdef CONFIG_CPU_USE_DOMAINS | 772 | #ifdef CONFIG_CPU_USE_DOMAINS |
773 | mrc p15, 0, r6, c3, c0, 0 @ Get domain register | ||
774 | str r6, [r1, #TI_CPU_DOMAIN] @ Save old domain register | ||
773 | ldr r6, [r2, #TI_CPU_DOMAIN] | 775 | ldr r6, [r2, #TI_CPU_DOMAIN] |
774 | #endif | 776 | #endif |
775 | switch_tls r1, r4, r5, r3, r7 | 777 | switch_tls r1, r4, r5, r3, r7 |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index f192a2a41719..e722f9b3c9b1 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -146,10 +146,9 @@ void __show_regs(struct pt_regs *regs) | |||
146 | buf[0] = '\0'; | 146 | buf[0] = '\0'; |
147 | #ifdef CONFIG_CPU_CP15_MMU | 147 | #ifdef CONFIG_CPU_CP15_MMU |
148 | { | 148 | { |
149 | unsigned int transbase, dac; | 149 | unsigned int transbase, dac = get_domain(); |
150 | asm("mrc p15, 0, %0, c2, c0\n\t" | 150 | asm("mrc p15, 0, %0, c2, c0\n\t" |
151 | "mrc p15, 0, %1, c3, c0\n" | 151 | : "=r" (transbase)); |
152 | : "=r" (transbase), "=r" (dac)); | ||
153 | snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x", | 152 | snprintf(buf, sizeof(buf), " Table: %08x DAC: %08x", |
154 | transbase, dac); | 153 | transbase, dac); |
155 | } | 154 | } |
@@ -210,6 +209,14 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start, | |||
210 | 209 | ||
211 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); | 210 | memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save)); |
212 | 211 | ||
212 | /* | ||
213 | * Copy the initial value of the domain access control register | ||
214 | * from the current thread: thread->addr_limit will have been | ||
215 | * copied from the current thread via setup_thread_stack() in | ||
216 | * kernel/fork.c | ||
217 | */ | ||
218 | thread->cpu_domain = get_domain(); | ||
219 | |||
213 | if (likely(!(p->flags & PF_KTHREAD))) { | 220 | if (likely(!(p->flags & PF_KTHREAD))) { |
214 | *childregs = *current_pt_regs(); | 221 | *childregs = *current_pt_regs(); |
215 | childregs->ARM_r0 = 0; | 222 | childregs->ARM_r0 = 0; |