diff options
author | Bodo Stroesser <bstroesser@fujitsu-siemens.com> | 2005-11-07 03:58:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:31 -0500 |
commit | 858259cf7d1c443c836a2022b78cb281f0a9b95e (patch) | |
tree | 7d306450dd0dfa907bbee1d95f96191c67f74232 /arch/um/kernel | |
parent | e763b793f7e5c09a859fc420eb0de385d80cf636 (diff) |
[PATCH] uml: maintain own LDT entries
Patch imlements full LDT handling in SKAS:
* UML holds it's own LDT table, used to deliver data on
modify_ldt(READ)
* UML disables the default_ldt, inherited from the host (SKAS3)
or resets LDT entries, set by host's clib and inherited in
SKAS0
* A new global variable skas_needs_stub is inserted, that
can be used to decide, whether stub-pages must be supported
or not.
* Uses the syscall-stub to replace missing PTRACE_LDT (therefore,
write_ldt_entry needs to be modified)
Signed-off-by: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Cc: Paolo Giarrusso <blaisorblade@yahoo.it>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/skas/include/mmu-skas.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/skas/include/skas.h | 3 | ||||
-rw-r--r-- | arch/um/kernel/skas/mem.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/skas/mmu.c | 44 | ||||
-rw-r--r-- | arch/um/kernel/skas/process.c | 6 | ||||
-rw-r--r-- | arch/um/kernel/skas/process_kern.c | 2 |
6 files changed, 36 insertions, 23 deletions
diff --git a/arch/um/kernel/skas/include/mmu-skas.h b/arch/um/kernel/skas/include/mmu-skas.h index 09536f81ee42..44110c521e49 100644 --- a/arch/um/kernel/skas/include/mmu-skas.h +++ b/arch/um/kernel/skas/include/mmu-skas.h | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include "linux/config.h" | 9 | #include "linux/config.h" |
10 | #include "mm_id.h" | 10 | #include "mm_id.h" |
11 | #include "asm/ldt.h" | ||
11 | 12 | ||
12 | struct mmu_context_skas { | 13 | struct mmu_context_skas { |
13 | struct mm_id id; | 14 | struct mm_id id; |
@@ -15,6 +16,7 @@ struct mmu_context_skas { | |||
15 | #ifdef CONFIG_3_LEVEL_PGTABLES | 16 | #ifdef CONFIG_3_LEVEL_PGTABLES |
16 | unsigned long last_pmd; | 17 | unsigned long last_pmd; |
17 | #endif | 18 | #endif |
19 | uml_ldt_t ldt; | ||
18 | }; | 20 | }; |
19 | 21 | ||
20 | extern void switch_mm_skas(struct mm_id * mm_idp); | 22 | extern void switch_mm_skas(struct mm_id * mm_idp); |
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h index 060934740f9f..daa2f85b684c 100644 --- a/arch/um/kernel/skas/include/skas.h +++ b/arch/um/kernel/skas/include/skas.h | |||
@@ -10,7 +10,8 @@ | |||
10 | #include "sysdep/ptrace.h" | 10 | #include "sysdep/ptrace.h" |
11 | 11 | ||
12 | extern int userspace_pid[]; | 12 | extern int userspace_pid[]; |
13 | extern int proc_mm, ptrace_faultinfo; | 13 | extern int proc_mm, ptrace_faultinfo, ptrace_ldt; |
14 | extern int skas_needs_stub; | ||
14 | 15 | ||
15 | extern void switch_threads(void *me, void *next); | 16 | extern void switch_threads(void *me, void *next); |
16 | extern void thread_wait(void *sw, void *fb); | 17 | extern void thread_wait(void *sw, void *fb); |
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c index 147466d7ff4f..88ab96c609ce 100644 --- a/arch/um/kernel/skas/mem.c +++ b/arch/um/kernel/skas/mem.c | |||
@@ -20,7 +20,7 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, | |||
20 | *task_size_out = CONFIG_HOST_TASK_SIZE; | 20 | *task_size_out = CONFIG_HOST_TASK_SIZE; |
21 | #else | 21 | #else |
22 | *host_size_out = top; | 22 | *host_size_out = top; |
23 | if (proc_mm && ptrace_faultinfo) | 23 | if (!skas_needs_stub) |
24 | *task_size_out = top; | 24 | *task_size_out = top; |
25 | else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; | 25 | else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; |
26 | #endif | 26 | #endif |
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index 9e5e39cea821..677871f1b37c 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "asm/mmu.h" | 15 | #include "asm/mmu.h" |
16 | #include "asm/pgalloc.h" | 16 | #include "asm/pgalloc.h" |
17 | #include "asm/pgtable.h" | 17 | #include "asm/pgtable.h" |
18 | #include "asm/ldt.h" | ||
18 | #include "os.h" | 19 | #include "os.h" |
19 | #include "skas.h" | 20 | #include "skas.h" |
20 | 21 | ||
@@ -74,13 +75,12 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, | |||
74 | 75 | ||
75 | int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) | 76 | int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) |
76 | { | 77 | { |
77 | struct mm_struct *cur_mm = current->mm; | 78 | struct mmu_context_skas *from_mm = NULL; |
78 | struct mm_id *cur_mm_id = &cur_mm->context.skas.id; | 79 | struct mmu_context_skas *to_mm = &mm->context.skas; |
79 | struct mm_id *mm_id = &mm->context.skas.id; | ||
80 | unsigned long stack = 0; | 80 | unsigned long stack = 0; |
81 | int from, ret = -ENOMEM; | 81 | int from_fd, ret = -ENOMEM; |
82 | 82 | ||
83 | if(!proc_mm || !ptrace_faultinfo){ | 83 | if(skas_needs_stub){ |
84 | stack = get_zeroed_page(GFP_KERNEL); | 84 | stack = get_zeroed_page(GFP_KERNEL); |
85 | if(stack == 0) | 85 | if(stack == 0) |
86 | goto out; | 86 | goto out; |
@@ -102,33 +102,43 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) | |||
102 | 102 | ||
103 | mm->nr_ptes--; | 103 | mm->nr_ptes--; |
104 | } | 104 | } |
105 | mm_id->stack = stack; | 105 | |
106 | to_mm->id.stack = stack; | ||
107 | if(current->mm != NULL && current->mm != &init_mm) | ||
108 | from_mm = ¤t->mm->context.skas; | ||
106 | 109 | ||
107 | if(proc_mm){ | 110 | if(proc_mm){ |
108 | if((cur_mm != NULL) && (cur_mm != &init_mm)) | 111 | if(from_mm) |
109 | from = cur_mm_id->u.mm_fd; | 112 | from_fd = from_mm->id.u.mm_fd; |
110 | else from = -1; | 113 | else from_fd = -1; |
111 | 114 | ||
112 | ret = new_mm(from, stack); | 115 | ret = new_mm(from_fd, stack); |
113 | if(ret < 0){ | 116 | if(ret < 0){ |
114 | printk("init_new_context_skas - new_mm failed, " | 117 | printk("init_new_context_skas - new_mm failed, " |
115 | "errno = %d\n", ret); | 118 | "errno = %d\n", ret); |
116 | goto out_free; | 119 | goto out_free; |
117 | } | 120 | } |
118 | mm_id->u.mm_fd = ret; | 121 | to_mm->id.u.mm_fd = ret; |
119 | } | 122 | } |
120 | else { | 123 | else { |
121 | if((cur_mm != NULL) && (cur_mm != &init_mm)) | 124 | if(from_mm) |
122 | mm_id->u.pid = copy_context_skas0(stack, | 125 | to_mm->id.u.pid = copy_context_skas0(stack, |
123 | cur_mm_id->u.pid); | 126 | from_mm->id.u.pid); |
124 | else mm_id->u.pid = start_userspace(stack); | 127 | else to_mm->id.u.pid = start_userspace(stack); |
128 | } | ||
129 | |||
130 | ret = init_new_ldt(to_mm, from_mm); | ||
131 | if(ret < 0){ | ||
132 | printk("init_new_context_skas - init_ldt" | ||
133 | " failed, errno = %d\n", ret); | ||
134 | goto out_free; | ||
125 | } | 135 | } |
126 | 136 | ||
127 | return 0; | 137 | return 0; |
128 | 138 | ||
129 | out_free: | 139 | out_free: |
130 | if(mm_id->stack != 0) | 140 | if(to_mm->id.stack != 0) |
131 | free_page(mm_id->stack); | 141 | free_page(to_mm->id.stack); |
132 | out: | 142 | out: |
133 | return ret; | 143 | return ret; |
134 | } | 144 | } |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 42f2da687dc8..599d679bd4fc 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -381,9 +381,9 @@ int copy_context_skas0(unsigned long new_stack, int pid) | |||
381 | } | 381 | } |
382 | 382 | ||
383 | /* | 383 | /* |
384 | * This is used only, if proc_mm is available, while PTRACE_FAULTINFO | 384 | * This is used only, if stub pages are needed, while proc_mm is |
385 | * isn't. Opening /proc/mm creates a new mm_context, which lacks the stub-pages | 385 | * availabl. Opening /proc/mm creates a new mm_context, which lacks |
386 | * Thus, we map them using /proc/mm-fd | 386 | * the stub-pages. Thus, we map them using /proc/mm-fd |
387 | */ | 387 | */ |
388 | void map_stub_pages(int fd, unsigned long code, | 388 | void map_stub_pages(int fd, unsigned long code, |
389 | unsigned long data, unsigned long stack) | 389 | unsigned long data, unsigned long stack) |
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index efe92e8aa2a9..9c990253966c 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -145,7 +145,7 @@ int new_mm(int from, unsigned long stack) | |||
145 | "err = %d\n", -n); | 145 | "err = %d\n", -n); |
146 | } | 146 | } |
147 | 147 | ||
148 | if(!ptrace_faultinfo) | 148 | if(skas_needs_stub) |
149 | map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); | 149 | map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); |
150 | 150 | ||
151 | return(fd); | 151 | return(fd); |