mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	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>
This commit is contained in:
		
							parent
							
								
									d770e558e2
								
							
						
					
					
						commit
						1eef5d2f1b
					
				
					 4 changed files with 27 additions and 11 deletions
				
			
		| 
						 | 
					@ -59,6 +59,17 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef __ASSEMBLY__
 | 
					#ifndef __ASSEMBLY__
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline unsigned int get_domain(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						unsigned int domain;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						asm(
 | 
				
			||||||
 | 
						"mrc	p15, 0, %0, c3, c0	@ get domain"
 | 
				
			||||||
 | 
						 : "=r" (domain));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return domain;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_CPU_USE_DOMAINS
 | 
					#ifdef CONFIG_CPU_USE_DOMAINS
 | 
				
			||||||
static inline void set_domain(unsigned val)
 | 
					static inline void set_domain(unsigned val)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -70,11 +81,10 @@ static inline void set_domain(unsigned val)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define modify_domain(dom,type)					\
 | 
					#define modify_domain(dom,type)					\
 | 
				
			||||||
	do {							\
 | 
						do {							\
 | 
				
			||||||
	struct thread_info *thread = current_thread_info();	\
 | 
							unsigned int domain = get_domain();		\
 | 
				
			||||||
	unsigned int domain = thread->cpu_domain;		\
 | 
					 | 
				
			||||||
		domain &= ~domain_val(dom, DOMAIN_MANAGER);	\
 | 
							domain &= ~domain_val(dom, DOMAIN_MANAGER);	\
 | 
				
			||||||
	thread->cpu_domain = domain | domain_val(dom, type);	\
 | 
							domain = domain | domain_val(dom, type);	\
 | 
				
			||||||
	set_domain(thread->cpu_domain);				\
 | 
							set_domain(domain);				\
 | 
				
			||||||
	} while (0)
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,9 +74,6 @@ struct thread_info {
 | 
				
			||||||
	.flags		= 0,						\
 | 
						.flags		= 0,						\
 | 
				
			||||||
	.preempt_count	= INIT_PREEMPT_COUNT,				\
 | 
						.preempt_count	= INIT_PREEMPT_COUNT,				\
 | 
				
			||||||
	.addr_limit	= KERNEL_DS,					\
 | 
						.addr_limit	= KERNEL_DS,					\
 | 
				
			||||||
	.cpu_domain	= domain_val(DOMAIN_USER, DOMAIN_MANAGER) |	\
 | 
					 | 
				
			||||||
			  domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) |	\
 | 
					 | 
				
			||||||
			  domain_val(DOMAIN_IO, DOMAIN_CLIENT),		\
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define init_thread_info	(init_thread_union.thread_info)
 | 
					#define init_thread_info	(init_thread_union.thread_info)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -770,6 +770,8 @@ ENTRY(__switch_to)
 | 
				
			||||||
	ldr	r4, [r2, #TI_TP_VALUE]
 | 
						ldr	r4, [r2, #TI_TP_VALUE]
 | 
				
			||||||
	ldr	r5, [r2, #TI_TP_VALUE + 4]
 | 
						ldr	r5, [r2, #TI_TP_VALUE + 4]
 | 
				
			||||||
#ifdef CONFIG_CPU_USE_DOMAINS
 | 
					#ifdef CONFIG_CPU_USE_DOMAINS
 | 
				
			||||||
 | 
						mrc	p15, 0, r6, c3, c0, 0		@ Get domain register
 | 
				
			||||||
 | 
						str	r6, [r1, #TI_CPU_DOMAIN]	@ Save old domain register
 | 
				
			||||||
	ldr	r6, [r2, #TI_CPU_DOMAIN]
 | 
						ldr	r6, [r2, #TI_CPU_DOMAIN]
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	switch_tls r1, r4, r5, r3, r7
 | 
						switch_tls r1, r4, r5, r3, r7
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -146,10 +146,9 @@ void __show_regs(struct pt_regs *regs)
 | 
				
			||||||
		buf[0] = '\0';
 | 
							buf[0] = '\0';
 | 
				
			||||||
#ifdef CONFIG_CPU_CP15_MMU
 | 
					#ifdef CONFIG_CPU_CP15_MMU
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			unsigned int transbase, dac;
 | 
								unsigned int transbase, dac = get_domain();
 | 
				
			||||||
			asm("mrc p15, 0, %0, c2, c0\n\t"
 | 
								asm("mrc p15, 0, %0, c2, c0\n\t"
 | 
				
			||||||
			    "mrc p15, 0, %1, c3, c0\n"
 | 
								    : "=r" (transbase));
 | 
				
			||||||
			    : "=r" (transbase), "=r" (dac));
 | 
					 | 
				
			||||||
			snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
 | 
								snprintf(buf, sizeof(buf), "  Table: %08x  DAC: %08x",
 | 
				
			||||||
			  	transbase, dac);
 | 
								  	transbase, dac);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -210,6 +209,14 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
 | 
						memset(&thread->cpu_context, 0, sizeof(struct cpu_context_save));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * Copy the initial value of the domain access control register
 | 
				
			||||||
 | 
						 * from the current thread: thread->addr_limit will have been
 | 
				
			||||||
 | 
						 * copied from the current thread via setup_thread_stack() in
 | 
				
			||||||
 | 
						 * kernel/fork.c
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						thread->cpu_domain = get_domain();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (likely(!(p->flags & PF_KTHREAD))) {
 | 
						if (likely(!(p->flags & PF_KTHREAD))) {
 | 
				
			||||||
		*childregs = *current_pt_regs();
 | 
							*childregs = *current_pt_regs();
 | 
				
			||||||
		childregs->ARM_r0 = 0;
 | 
							childregs->ARM_r0 = 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue