diff options
Diffstat (limited to 'include/asm-s390/mmu_context.h')
-rw-r--r-- | include/asm-s390/mmu_context.h | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h index a77d4ba3c8eb..b5a34c6f91a9 100644 --- a/include/asm-s390/mmu_context.h +++ b/include/asm-s390/mmu_context.h | |||
@@ -10,15 +10,19 @@ | |||
10 | #define __S390_MMU_CONTEXT_H | 10 | #define __S390_MMU_CONTEXT_H |
11 | 11 | ||
12 | #include <asm/pgalloc.h> | 12 | #include <asm/pgalloc.h> |
13 | #include <asm/uaccess.h> | ||
13 | #include <asm-generic/mm_hooks.h> | 14 | #include <asm-generic/mm_hooks.h> |
14 | 15 | ||
15 | static inline int init_new_context(struct task_struct *tsk, | 16 | static inline int init_new_context(struct task_struct *tsk, |
16 | struct mm_struct *mm) | 17 | struct mm_struct *mm) |
17 | { | 18 | { |
18 | mm->context = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; | 19 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; |
19 | #ifdef CONFIG_64BIT | 20 | #ifdef CONFIG_64BIT |
20 | mm->context |= _ASCE_TYPE_REGION3; | 21 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; |
21 | #endif | 22 | #endif |
23 | mm->context.noexec = s390_noexec; | ||
24 | mm->context.asce_limit = STACK_TOP_MAX; | ||
25 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); | ||
22 | return 0; | 26 | return 0; |
23 | } | 27 | } |
24 | 28 | ||
@@ -32,24 +36,25 @@ static inline int init_new_context(struct task_struct *tsk, | |||
32 | 36 | ||
33 | static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) | 37 | static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) |
34 | { | 38 | { |
35 | S390_lowcore.user_asce = mm->context | __pa(mm->pgd); | 39 | pgd_t *pgd = mm->pgd; |
40 | |||
41 | S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); | ||
36 | if (switch_amode) { | 42 | if (switch_amode) { |
37 | /* Load primary space page table origin. */ | 43 | /* Load primary space page table origin. */ |
38 | pgd_t *shadow_pgd = get_shadow_table(mm->pgd) ? : mm->pgd; | 44 | pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd; |
39 | S390_lowcore.user_exec_asce = mm->context | __pa(shadow_pgd); | 45 | S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd); |
40 | asm volatile(LCTL_OPCODE" 1,1,%0\n" | 46 | asm volatile(LCTL_OPCODE" 1,1,%0\n" |
41 | : : "m" (S390_lowcore.user_exec_asce) ); | 47 | : : "m" (S390_lowcore.user_exec_asce) ); |
42 | } else | 48 | } else |
43 | /* Load home space page table origin. */ | 49 | /* Load home space page table origin. */ |
44 | asm volatile(LCTL_OPCODE" 13,13,%0" | 50 | asm volatile(LCTL_OPCODE" 13,13,%0" |
45 | : : "m" (S390_lowcore.user_asce) ); | 51 | : : "m" (S390_lowcore.user_asce) ); |
52 | set_fs(current->thread.mm_segment); | ||
46 | } | 53 | } |
47 | 54 | ||
48 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | 55 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, |
49 | struct task_struct *tsk) | 56 | struct task_struct *tsk) |
50 | { | 57 | { |
51 | if (unlikely(prev == next)) | ||
52 | return; | ||
53 | cpu_set(smp_processor_id(), next->cpu_vm_mask); | 58 | cpu_set(smp_processor_id(), next->cpu_vm_mask); |
54 | update_mm(next, tsk); | 59 | update_mm(next, tsk); |
55 | } | 60 | } |
@@ -61,7 +66,6 @@ static inline void activate_mm(struct mm_struct *prev, | |||
61 | struct mm_struct *next) | 66 | struct mm_struct *next) |
62 | { | 67 | { |
63 | switch_mm(prev, next, current); | 68 | switch_mm(prev, next, current); |
64 | set_fs(current->thread.mm_segment); | ||
65 | } | 69 | } |
66 | 70 | ||
67 | #endif /* __S390_MMU_CONTEXT_H */ | 71 | #endif /* __S390_MMU_CONTEXT_H */ |