aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/skas/mmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/kernel/skas/mmu.c')
-rw-r--r--arch/um/kernel/skas/mmu.c64
1 files changed, 29 insertions, 35 deletions
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 902d74138952..c5475ecd9fd4 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -1,20 +1,12 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h"
7#include "linux/list.h"
8#include "linux/spinlock.h"
9#include "linux/slab.h"
10#include "linux/errno.h"
11#include "linux/mm.h" 6#include "linux/mm.h"
12#include "asm/current.h" 7#include "linux/sched.h"
13#include "asm/segment.h"
14#include "asm/mmu.h"
15#include "asm/pgalloc.h" 8#include "asm/pgalloc.h"
16#include "asm/pgtable.h" 9#include "asm/pgtable.h"
17#include "asm/ldt.h"
18#include "os.h" 10#include "os.h"
19#include "skas.h" 11#include "skas.h"
20 12
@@ -41,10 +33,11 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
41 if (!pte) 33 if (!pte)
42 goto out_pte; 34 goto out_pte;
43 35
44 /* There's an interaction between the skas0 stub pages, stack 36 /*
37 * There's an interaction between the skas0 stub pages, stack
45 * randomization, and the BUG at the end of exit_mmap. exit_mmap 38 * randomization, and the BUG at the end of exit_mmap. exit_mmap
46 * checks that the number of page tables freed is the same as had 39 * checks that the number of page tables freed is the same as had
47 * been allocated. If the stack is on the last page table page, 40 * been allocated. If the stack is on the last page table page,
48 * then the stack pte page will be freed, and if not, it won't. To 41 * then the stack pte page will be freed, and if not, it won't. To
49 * avoid having to know where the stack is, or if the process mapped 42 * avoid having to know where the stack is, or if the process mapped
50 * something at the top of its address space for some other reason, 43 * something at the top of its address space for some other reason,
@@ -54,36 +47,37 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
54 * destroy_context_skas. 47 * destroy_context_skas.
55 */ 48 */
56 49
57 mm->context.skas.last_page_table = pmd_page_vaddr(*pmd); 50 mm->context.skas.last_page_table = pmd_page_vaddr(*pmd);
58#ifdef CONFIG_3_LEVEL_PGTABLES 51#ifdef CONFIG_3_LEVEL_PGTABLES
59 mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); 52 mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud));
60#endif 53#endif
61 54
62 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); 55 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
63 *pte = pte_mkread(*pte); 56 *pte = pte_mkread(*pte);
64 return(0); 57 return 0;
65 58
66 out_pmd: 59 out_pmd:
67 pud_free(pud); 60 pud_free(pud);
68 out_pte: 61 out_pte:
69 pmd_free(pmd); 62 pmd_free(pmd);
70 out: 63 out:
71 return(-ENOMEM); 64 return -ENOMEM;
72} 65}
73 66
74int init_new_context(struct task_struct *task, struct mm_struct *mm) 67int init_new_context(struct task_struct *task, struct mm_struct *mm)
75{ 68{
76 struct mmu_context_skas *from_mm = NULL; 69 struct mmu_context_skas *from_mm = NULL;
77 struct mmu_context_skas *to_mm = &mm->context.skas; 70 struct mmu_context_skas *to_mm = &mm->context.skas;
78 unsigned long stack = 0; 71 unsigned long stack = 0;
79 int ret = -ENOMEM; 72 int ret = -ENOMEM;
80 73
81 if(skas_needs_stub){ 74 if (skas_needs_stub) {
82 stack = get_zeroed_page(GFP_KERNEL); 75 stack = get_zeroed_page(GFP_KERNEL);
83 if(stack == 0) 76 if (stack == 0)
84 goto out; 77 goto out;
85 78
86 /* This zeros the entry that pgd_alloc didn't, needed since 79 /*
80 * This zeros the entry that pgd_alloc didn't, needed since
87 * we are about to reinitialize it, and want mm.nr_ptes to 81 * we are about to reinitialize it, and want mm.nr_ptes to
88 * be accurate. 82 * be accurate.
89 */ 83 */
@@ -91,39 +85,39 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
91 85
92 ret = init_stub_pte(mm, CONFIG_STUB_CODE, 86 ret = init_stub_pte(mm, CONFIG_STUB_CODE,
93 (unsigned long) &__syscall_stub_start); 87 (unsigned long) &__syscall_stub_start);
94 if(ret) 88 if (ret)
95 goto out_free; 89 goto out_free;
96 90
97 ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); 91 ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack);
98 if(ret) 92 if (ret)
99 goto out_free; 93 goto out_free;
100 94
101 mm->nr_ptes--; 95 mm->nr_ptes--;
102 } 96 }
103 97
104 to_mm->id.stack = stack; 98 to_mm->id.stack = stack;
105 if(current->mm != NULL && current->mm != &init_mm) 99 if (current->mm != NULL && current->mm != &init_mm)
106 from_mm = &current->mm->context.skas; 100 from_mm = &current->mm->context.skas;
107 101
108 if(proc_mm){ 102 if (proc_mm) {
109 ret = new_mm(stack); 103 ret = new_mm(stack);
110 if(ret < 0){ 104 if (ret < 0) {
111 printk("init_new_context_skas - new_mm failed, " 105 printk(KERN_ERR "init_new_context_skas - "
112 "errno = %d\n", ret); 106 "new_mm failed, errno = %d\n", ret);
113 goto out_free; 107 goto out_free;
114 } 108 }
115 to_mm->id.u.mm_fd = ret; 109 to_mm->id.u.mm_fd = ret;
116 } 110 }
117 else { 111 else {
118 if(from_mm) 112 if (from_mm)
119 to_mm->id.u.pid = copy_context_skas0(stack, 113 to_mm->id.u.pid = copy_context_skas0(stack,
120 from_mm->id.u.pid); 114 from_mm->id.u.pid);
121 else to_mm->id.u.pid = start_userspace(stack); 115 else to_mm->id.u.pid = start_userspace(stack);
122 } 116 }
123 117
124 ret = init_new_ldt(to_mm, from_mm); 118 ret = init_new_ldt(to_mm, from_mm);
125 if(ret < 0){ 119 if (ret < 0) {
126 printk("init_new_context_skas - init_ldt" 120 printk(KERN_ERR "init_new_context_skas - init_ldt"
127 " failed, errno = %d\n", ret); 121 " failed, errno = %d\n", ret);
128 goto out_free; 122 goto out_free;
129 } 123 }
@@ -131,7 +125,7 @@ int init_new_context(struct task_struct *task, struct mm_struct *mm)
131 return 0; 125 return 0;
132 126
133 out_free: 127 out_free:
134 if(to_mm->id.stack != 0) 128 if (to_mm->id.stack != 0)
135 free_page(to_mm->id.stack); 129 free_page(to_mm->id.stack);
136 out: 130 out:
137 return ret; 131 return ret;
@@ -141,12 +135,12 @@ void destroy_context(struct mm_struct *mm)
141{ 135{
142 struct mmu_context_skas *mmu = &mm->context.skas; 136 struct mmu_context_skas *mmu = &mm->context.skas;
143 137
144 if(proc_mm) 138 if (proc_mm)
145 os_close_file(mmu->id.u.mm_fd); 139 os_close_file(mmu->id.u.mm_fd);
146 else 140 else
147 os_kill_ptraced_process(mmu->id.u.pid, 1); 141 os_kill_ptraced_process(mmu->id.u.pid, 1);
148 142
149 if(!proc_mm || !ptrace_faultinfo){ 143 if (!proc_mm || !ptrace_faultinfo) {
150 free_page(mmu->id.stack); 144 free_page(mmu->id.stack);
151 pte_lock_deinit(virt_to_page(mmu->last_page_table)); 145 pte_lock_deinit(virt_to_page(mmu->last_page_table));
152 pte_free_kernel((pte_t *) mmu->last_page_table); 146 pte_free_kernel((pte_t *) mmu->last_page_table);