| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-08-02 10:55:55 +01:00
										 |  |  |  *  arch/arm/include/asm/mmu_context.h | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  *  Copyright (C) 1996 Russell King. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU General Public License version 2 as | 
					
						
							|  |  |  |  * published by the Free Software Foundation. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  Changelog: | 
					
						
							|  |  |  |  *   27-06-1996	RMK	Created | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #ifndef __ASM_ARM_MMU_CONTEXT_H
 | 
					
						
							|  |  |  | #define __ASM_ARM_MMU_CONTEXT_H
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-16 17:23:57 +00:00
										 |  |  | #include <linux/compiler.h>
 | 
					
						
							| 
									
										
										
										
											2008-11-29 17:35:51 +00:00
										 |  |  | #include <linux/sched.h>
 | 
					
						
							| 
									
										
										
										
											2005-11-06 19:47:04 +00:00
										 |  |  | #include <asm/cacheflush.h>
 | 
					
						
							| 
									
										
										
										
											2008-08-10 18:10:19 +01:00
										 |  |  | #include <asm/cachetype.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #include <asm/proc-fns.h>
 | 
					
						
							| 
									
										
										
										
											2007-05-02 19:27:14 +02:00
										 |  |  | #include <asm-generic/mm_hooks.h>
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-29 20:17:15 +01:00
										 |  |  | void __check_kvm_seq(struct mm_struct *mm); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-05-17 10:19:23 +01:00
										 |  |  | #ifdef CONFIG_CPU_HAS_ASID
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * On ARMv6, we have the following structure in the Context ID: | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * 31                         7          0 | 
					
						
							|  |  |  |  * +-------------------------+-----------+ | 
					
						
							|  |  |  |  * |      process ID         |   ASID    | | 
					
						
							|  |  |  |  * +-------------------------+-----------+ | 
					
						
							|  |  |  |  * |              context ID             | | 
					
						
							|  |  |  |  * +-------------------------------------+ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * The ASID is used to tag entries in the CPU caches and TLBs. | 
					
						
							|  |  |  |  * The context ID is used by debuggers and trace logic, and | 
					
						
							|  |  |  |  * should be unique within all running processes. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-05-08 20:03:09 +01:00
										 |  |  | #define ASID_BITS		8
 | 
					
						
							|  |  |  | #define ASID_MASK		((~0) << ASID_BITS)
 | 
					
						
							|  |  |  | #define ASID_FIRST_VERSION	(1 << ASID_BITS)
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | extern unsigned int cpu_last_asid; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void __init_new_context(struct task_struct *tsk, struct mm_struct *mm); | 
					
						
							|  |  |  | void __new_context(struct mm_struct *mm); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static inline void check_context(struct mm_struct *mm) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (unlikely((mm->context.id ^ cpu_last_asid) >> ASID_BITS)) | 
					
						
							|  |  |  | 		__new_context(mm); | 
					
						
							| 
									
										
										
										
											2006-06-29 20:17:15 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) | 
					
						
							|  |  |  | 		__check_kvm_seq(mm); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define init_new_context(tsk,mm)	(__init_new_context(tsk,mm),0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-06-29 20:17:15 +01:00
										 |  |  | static inline void check_context(struct mm_struct *mm) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-07-24 12:34:56 +01:00
										 |  |  | #ifdef CONFIG_MMU
 | 
					
						
							| 
									
										
										
										
											2006-06-29 20:17:15 +01:00
										 |  |  | 	if (unlikely(mm->context.kvm_seq != init_mm.context.kvm_seq)) | 
					
						
							|  |  |  | 		__check_kvm_seq(mm); | 
					
						
							| 
									
										
										
										
											2009-07-24 12:34:56 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2006-06-29 20:17:15 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | #define init_new_context(tsk,mm)	0
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define destroy_context(mm)		do { } while(0)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This is called when "tsk" is about to enter lazy TLB mode. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * mm:  describes the currently active mm context | 
					
						
							|  |  |  |  * tsk: task which is entering lazy tlb | 
					
						
							|  |  |  |  * cpu: cpu number which is entering lazy tlb | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * tsk->mm will be NULL | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * This is the actual mm switch as far as the scheduler | 
					
						
							|  |  |  |  * is concerned.  No registers are touched.  We avoid | 
					
						
							|  |  |  |  * calling the CPU specific function when the mm hasn't | 
					
						
							|  |  |  |  * actually changed. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | static inline void | 
					
						
							|  |  |  | switch_mm(struct mm_struct *prev, struct mm_struct *next, | 
					
						
							|  |  |  | 	  struct task_struct *tsk) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-06-20 20:46:52 +01:00
										 |  |  | #ifdef CONFIG_MMU
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	unsigned int cpu = smp_processor_id(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-13 10:28:36 +01:00
										 |  |  | #ifdef CONFIG_SMP
 | 
					
						
							|  |  |  | 	/* check for possible thread migration */ | 
					
						
							| 
									
										
										
										
											2009-09-24 09:34:49 -06:00
										 |  |  | 	if (!cpumask_empty(mm_cpumask(next)) && | 
					
						
							|  |  |  | 	    !cpumask_test_cpu(cpu, mm_cpumask(next))) | 
					
						
							| 
									
										
										
										
											2008-06-13 10:28:36 +01:00
										 |  |  | 		__flush_icache_all(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2009-09-24 09:34:49 -06:00
										 |  |  | 	if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 		check_context(next); | 
					
						
							|  |  |  | 		cpu_switch_mm(next->pgd, next); | 
					
						
							| 
									
										
										
										
											2005-11-03 20:32:45 +00:00
										 |  |  | 		if (cache_is_vivt()) | 
					
						
							| 
									
										
										
										
											2009-09-24 09:34:49 -06:00
										 |  |  | 			cpumask_clear_cpu(cpu, mm_cpumask(prev)); | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2006-06-20 20:46:52 +01:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2005-04-16 15:20:36 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define deactivate_mm(tsk,mm)	do { } while (0)
 | 
					
						
							|  |  |  | #define activate_mm(prev,next)	switch_mm(prev, next, NULL)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 |