diff options
author | Paul Mackerras <paulus@samba.org> | 2005-09-25 08:51:50 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2005-09-25 08:51:50 -0400 |
commit | e5baa396af7560382d2cf3f0871d616b61fc284c (patch) | |
tree | 6afc166894b8c8b3b2cf6add72a726be14ae2443 /arch/um/kernel | |
parent | d6a4c847e43c851cc0ddf73087a730227223f989 (diff) | |
parent | ef6bd6eb90ad72ee8ee7ba8b271f27102e9a90c1 (diff) |
Merge from Linus' tree.
Diffstat (limited to 'arch/um/kernel')
-rw-r--r-- | arch/um/kernel/process_kern.c | 3 | ||||
-rw-r--r-- | arch/um/kernel/sigio_user.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/skas/include/uaccess-skas.h | 6 | ||||
-rw-r--r-- | arch/um/kernel/tlb.c | 12 | ||||
-rw-r--r-- | arch/um/kernel/trap_kern.c | 18 | ||||
-rw-r--r-- | arch/um/kernel/tt/include/uaccess-tt.h | 6 | ||||
-rw-r--r-- | arch/um/kernel/tt/process_kern.c | 3 | ||||
-rw-r--r-- | arch/um/kernel/tt/uaccess_user.c | 11 | ||||
-rw-r--r-- | arch/um/kernel/umid.c | 41 | ||||
-rw-r--r-- | arch/um/kernel/user_util.c | 6 |
10 files changed, 66 insertions, 42 deletions
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 39cf568ccfaf..ea65db679e9c 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -82,7 +82,8 @@ unsigned long alloc_stack(int order, int atomic) | |||
82 | unsigned long page; | 82 | unsigned long page; |
83 | int flags = GFP_KERNEL; | 83 | int flags = GFP_KERNEL; |
84 | 84 | ||
85 | if(atomic) flags |= GFP_ATOMIC; | 85 | if (atomic) |
86 | flags = GFP_ATOMIC; | ||
86 | page = __get_free_pages(flags, order); | 87 | page = __get_free_pages(flags, order); |
87 | if(page == 0) | 88 | if(page == 0) |
88 | return(0); | 89 | return(0); |
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index e89218958f38..a52751108aa1 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c | |||
@@ -340,7 +340,7 @@ static int setup_initial_poll(int fd) | |||
340 | { | 340 | { |
341 | struct pollfd *p; | 341 | struct pollfd *p; |
342 | 342 | ||
343 | p = um_kmalloc(sizeof(struct pollfd)); | 343 | p = um_kmalloc_atomic(sizeof(struct pollfd)); |
344 | if(p == NULL){ | 344 | if(p == NULL){ |
345 | printk("setup_initial_poll : failed to allocate poll\n"); | 345 | printk("setup_initial_poll : failed to allocate poll\n"); |
346 | return(-1); | 346 | return(-1); |
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h index 6ee3f3902e68..7da0c2def0ef 100644 --- a/arch/um/kernel/skas/include/uaccess-skas.h +++ b/arch/um/kernel/skas/include/uaccess-skas.h | |||
@@ -18,12 +18,6 @@ | |||
18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ | 18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ |
19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) | 19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) |
20 | 20 | ||
21 | static inline int verify_area_skas(int type, const void __user * addr, | ||
22 | unsigned long size) | ||
23 | { | ||
24 | return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); | ||
25 | } | ||
26 | |||
27 | extern int copy_from_user_skas(void *to, const void __user *from, int n); | 21 | extern int copy_from_user_skas(void *to, const void __user *from, int n); |
28 | extern int copy_to_user_skas(void __user *to, const void *from, int n); | 22 | extern int copy_to_user_skas(void __user *to, const void *from, int n); |
29 | extern int strncpy_from_user_skas(char *dst, const char __user *src, int count); | 23 | extern int strncpy_from_user_skas(char *dst, const char __user *src, int count); |
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 0a562c3c0fd8..f5b0636f9ad7 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c | |||
@@ -193,12 +193,12 @@ void fix_range_common(struct mm_struct *mm, unsigned long start_addr, | |||
193 | r = pte_read(*npte); | 193 | r = pte_read(*npte); |
194 | w = pte_write(*npte); | 194 | w = pte_write(*npte); |
195 | x = pte_exec(*npte); | 195 | x = pte_exec(*npte); |
196 | if(!pte_dirty(*npte)) | 196 | if (!pte_young(*npte)) { |
197 | w = 0; | 197 | r = 0; |
198 | if(!pte_young(*npte)){ | 198 | w = 0; |
199 | r = 0; | 199 | } else if (!pte_dirty(*npte)) { |
200 | w = 0; | 200 | w = 0; |
201 | } | 201 | } |
202 | if(force || pte_newpage(*npte)){ | 202 | if(force || pte_newpage(*npte)){ |
203 | if(pte_present(*npte)) | 203 | if(pte_present(*npte)) |
204 | ret = add_mmap(addr, | 204 | ret = add_mmap(addr, |
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 87cc6fd76ced..d297429ac360 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "asm/a.out.h" | 18 | #include "asm/a.out.h" |
19 | #include "asm/current.h" | 19 | #include "asm/current.h" |
20 | #include "asm/irq.h" | 20 | #include "asm/irq.h" |
21 | #include "sysdep/sigcontext.h" | ||
21 | #include "user_util.h" | 22 | #include "user_util.h" |
22 | #include "kern_util.h" | 23 | #include "kern_util.h" |
23 | #include "kern.h" | 24 | #include "kern.h" |
@@ -39,6 +40,12 @@ int handle_page_fault(unsigned long address, unsigned long ip, | |||
39 | int err = -EFAULT; | 40 | int err = -EFAULT; |
40 | 41 | ||
41 | *code_out = SEGV_MAPERR; | 42 | *code_out = SEGV_MAPERR; |
43 | |||
44 | /* If the fault was during atomic operation, don't take the fault, just | ||
45 | * fail. */ | ||
46 | if (in_atomic()) | ||
47 | goto out_nosemaphore; | ||
48 | |||
42 | down_read(&mm->mmap_sem); | 49 | down_read(&mm->mmap_sem); |
43 | vma = find_vma(mm, address); | 50 | vma = find_vma(mm, address); |
44 | if(!vma) | 51 | if(!vma) |
@@ -89,6 +96,7 @@ survive: | |||
89 | flush_tlb_page(vma, address); | 96 | flush_tlb_page(vma, address); |
90 | out: | 97 | out: |
91 | up_read(&mm->mmap_sem); | 98 | up_read(&mm->mmap_sem); |
99 | out_nosemaphore: | ||
92 | return(err); | 100 | return(err); |
93 | 101 | ||
94 | /* | 102 | /* |
@@ -125,7 +133,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |||
125 | } | 133 | } |
126 | else if(current->mm == NULL) | 134 | else if(current->mm == NULL) |
127 | panic("Segfault with no mm"); | 135 | panic("Segfault with no mm"); |
128 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | 136 | |
137 | if (SEGV_IS_FIXABLE(&fi)) | ||
138 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | ||
139 | else { | ||
140 | err = -EFAULT; | ||
141 | /* A thread accessed NULL, we get a fault, but CR2 is invalid. | ||
142 | * This code is used in __do_copy_from_user() of TT mode. */ | ||
143 | address = 0; | ||
144 | } | ||
129 | 145 | ||
130 | catcher = current->thread.fault_catcher; | 146 | catcher = current->thread.fault_catcher; |
131 | if(!err) | 147 | if(!err) |
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h index aa6db384af80..dc2ebfa8c54f 100644 --- a/arch/um/kernel/tt/include/uaccess-tt.h +++ b/arch/um/kernel/tt/include/uaccess-tt.h | |||
@@ -33,12 +33,6 @@ extern unsigned long uml_physmem; | |||
33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ | 33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ |
34 | (under_task_size(addr, size) || is_stack(addr, size)))) | 34 | (under_task_size(addr, size) || is_stack(addr, size)))) |
35 | 35 | ||
36 | static inline int verify_area_tt(int type, const void __user * addr, | ||
37 | unsigned long size) | ||
38 | { | ||
39 | return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); | ||
40 | } | ||
41 | |||
42 | extern unsigned long get_fault_addr(void); | 36 | extern unsigned long get_fault_addr(void); |
43 | 37 | ||
44 | extern int __do_copy_from_user(void *to, const void *from, int n, | 38 | extern int __do_copy_from_user(void *to, const void *from, int n, |
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 0de05a268b22..cfaa373a6e77 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -23,10 +23,11 @@ | |||
23 | #include "mem_user.h" | 23 | #include "mem_user.h" |
24 | #include "tlb.h" | 24 | #include "tlb.h" |
25 | #include "mode.h" | 25 | #include "mode.h" |
26 | #include "mode_kern.h" | ||
26 | #include "init.h" | 27 | #include "init.h" |
27 | #include "tt.h" | 28 | #include "tt.h" |
28 | 29 | ||
29 | int switch_to_tt(void *prev, void *next, void *last) | 30 | void switch_to_tt(void *prev, void *next) |
30 | { | 31 | { |
31 | struct task_struct *from, *to, *prev_sched; | 32 | struct task_struct *from, *to, *prev_sched; |
32 | unsigned long flags; | 33 | unsigned long flags; |
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c index f01475512ecb..8c220f054b61 100644 --- a/arch/um/kernel/tt/uaccess_user.c +++ b/arch/um/kernel/tt/uaccess_user.c | |||
@@ -22,8 +22,15 @@ int __do_copy_from_user(void *to, const void *from, int n, | |||
22 | __do_copy, &faulted); | 22 | __do_copy, &faulted); |
23 | TASK_REGS(get_current())->tt = save; | 23 | TASK_REGS(get_current())->tt = save; |
24 | 24 | ||
25 | if(!faulted) return(0); | 25 | if(!faulted) |
26 | else return(n - (fault - (unsigned long) from)); | 26 | return 0; |
27 | else if (fault) | ||
28 | return n - (fault - (unsigned long) from); | ||
29 | else | ||
30 | /* In case of a general protection fault, we don't have the | ||
31 | * fault address, so NULL is used instead. Pretend we didn't | ||
32 | * copy anything. */ | ||
33 | return n; | ||
27 | } | 34 | } |
28 | 35 | ||
29 | static void __do_strncpy(void *dst, const void *src, int count) | 36 | static void __do_strncpy(void *dst, const void *src, int count) |
diff --git a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c index 186c28885016..0b21d59ba0cd 100644 --- a/arch/um/kernel/umid.c +++ b/arch/um/kernel/umid.c | |||
@@ -31,6 +31,8 @@ static char *uml_dir = UML_DIR; | |||
31 | /* Changed by set_umid */ | 31 | /* Changed by set_umid */ |
32 | static int umid_is_random = 1; | 32 | static int umid_is_random = 1; |
33 | static int umid_inited = 0; | 33 | static int umid_inited = 0; |
34 | /* Have we created the files? Should we remove them? */ | ||
35 | static int umid_owned = 0; | ||
34 | 36 | ||
35 | static int make_umid(int (*printer)(const char *fmt, ...)); | 37 | static int make_umid(int (*printer)(const char *fmt, ...)); |
36 | 38 | ||
@@ -82,20 +84,21 @@ int __init umid_file_name(char *name, char *buf, int len) | |||
82 | 84 | ||
83 | extern int tracing_pid; | 85 | extern int tracing_pid; |
84 | 86 | ||
85 | static int __init create_pid_file(void) | 87 | static void __init create_pid_file(void) |
86 | { | 88 | { |
87 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; | 89 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; |
88 | char pid[sizeof("nnnnn\0")]; | 90 | char pid[sizeof("nnnnn\0")]; |
89 | int fd, n; | 91 | int fd, n; |
90 | 92 | ||
91 | if(umid_file_name("pid", file, sizeof(file))) return 0; | 93 | if(umid_file_name("pid", file, sizeof(file))) |
94 | return; | ||
92 | 95 | ||
93 | fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), | 96 | fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), |
94 | 0644); | 97 | 0644); |
95 | if(fd < 0){ | 98 | if(fd < 0){ |
96 | printf("Open of machine pid file \"%s\" failed: %s\n", | 99 | printf("Open of machine pid file \"%s\" failed: %s\n", |
97 | file, strerror(-fd)); | 100 | file, strerror(-fd)); |
98 | return 0; | 101 | return; |
99 | } | 102 | } |
100 | 103 | ||
101 | sprintf(pid, "%d\n", os_getpid()); | 104 | sprintf(pid, "%d\n", os_getpid()); |
@@ -103,7 +106,6 @@ static int __init create_pid_file(void) | |||
103 | if(n != strlen(pid)) | 106 | if(n != strlen(pid)) |
104 | printf("Write of pid file failed - err = %d\n", -n); | 107 | printf("Write of pid file failed - err = %d\n", -n); |
105 | os_close_file(fd); | 108 | os_close_file(fd); |
106 | return 0; | ||
107 | } | 109 | } |
108 | 110 | ||
109 | static int actually_do_remove(char *dir) | 111 | static int actually_do_remove(char *dir) |
@@ -147,7 +149,8 @@ static int actually_do_remove(char *dir) | |||
147 | void remove_umid_dir(void) | 149 | void remove_umid_dir(void) |
148 | { | 150 | { |
149 | char dir[strlen(uml_dir) + UMID_LEN + 1]; | 151 | char dir[strlen(uml_dir) + UMID_LEN + 1]; |
150 | if(!umid_inited) return; | 152 | if (!umid_owned) |
153 | return; | ||
151 | 154 | ||
152 | sprintf(dir, "%s%s", uml_dir, umid); | 155 | sprintf(dir, "%s%s", uml_dir, umid); |
153 | actually_do_remove(dir); | 156 | actually_do_remove(dir); |
@@ -155,11 +158,12 @@ void remove_umid_dir(void) | |||
155 | 158 | ||
156 | char *get_umid(int only_if_set) | 159 | char *get_umid(int only_if_set) |
157 | { | 160 | { |
158 | if(only_if_set && umid_is_random) return(NULL); | 161 | if(only_if_set && umid_is_random) |
159 | return(umid); | 162 | return NULL; |
163 | return umid; | ||
160 | } | 164 | } |
161 | 165 | ||
162 | int not_dead_yet(char *dir) | 166 | static int not_dead_yet(char *dir) |
163 | { | 167 | { |
164 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; | 168 | char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; |
165 | char pid[sizeof("nnnnn\0")], *end; | 169 | char pid[sizeof("nnnnn\0")], *end; |
@@ -193,7 +197,8 @@ int not_dead_yet(char *dir) | |||
193 | (p == CHOOSE_MODE(tracing_pid, os_getpid()))) | 197 | (p == CHOOSE_MODE(tracing_pid, os_getpid()))) |
194 | dead = 1; | 198 | dead = 1; |
195 | } | 199 | } |
196 | if(!dead) return(1); | 200 | if(!dead) |
201 | return(1); | ||
197 | return(actually_do_remove(dir)); | 202 | return(actually_do_remove(dir)); |
198 | } | 203 | } |
199 | 204 | ||
@@ -232,16 +237,13 @@ static int __init make_uml_dir(void) | |||
232 | strlcpy(dir, home, sizeof(dir)); | 237 | strlcpy(dir, home, sizeof(dir)); |
233 | uml_dir++; | 238 | uml_dir++; |
234 | } | 239 | } |
240 | strlcat(dir, uml_dir, sizeof(dir)); | ||
235 | len = strlen(dir); | 241 | len = strlen(dir); |
236 | strncat(dir, uml_dir, sizeof(dir) - len); | 242 | if (len > 0 && dir[len - 1] != '/') |
237 | len = strlen(dir); | 243 | strlcat(dir, "/", sizeof(dir)); |
238 | if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){ | ||
239 | dir[len] = '/'; | ||
240 | dir[len + 1] = '\0'; | ||
241 | } | ||
242 | 244 | ||
243 | uml_dir = malloc(strlen(dir) + 1); | 245 | uml_dir = malloc(strlen(dir) + 1); |
244 | if(uml_dir == NULL){ | 246 | if (uml_dir == NULL) { |
245 | printf("make_uml_dir : malloc failed, errno = %d\n", errno); | 247 | printf("make_uml_dir : malloc failed, errno = %d\n", errno); |
246 | exit(1); | 248 | exit(1); |
247 | } | 249 | } |
@@ -286,6 +288,7 @@ static int __init make_umid(int (*printer)(const char *fmt, ...)) | |||
286 | if(errno == EEXIST){ | 288 | if(errno == EEXIST){ |
287 | if(not_dead_yet(tmp)){ | 289 | if(not_dead_yet(tmp)){ |
288 | (*printer)("umid '%s' is in use\n", umid); | 290 | (*printer)("umid '%s' is in use\n", umid); |
291 | umid_owned = 0; | ||
289 | return(-1); | 292 | return(-1); |
290 | } | 293 | } |
291 | err = mkdir(tmp, 0777); | 294 | err = mkdir(tmp, 0777); |
@@ -296,7 +299,8 @@ static int __init make_umid(int (*printer)(const char *fmt, ...)) | |||
296 | return(-1); | 299 | return(-1); |
297 | } | 300 | } |
298 | 301 | ||
299 | return(0); | 302 | umid_owned = 1; |
303 | return 0; | ||
300 | } | 304 | } |
301 | 305 | ||
302 | __uml_setup("uml_dir=", set_uml_dir, | 306 | __uml_setup("uml_dir=", set_uml_dir, |
@@ -309,7 +313,8 @@ static int __init make_umid_setup(void) | |||
309 | /* one function with the ordering we need ... */ | 313 | /* one function with the ordering we need ... */ |
310 | make_uml_dir(); | 314 | make_uml_dir(); |
311 | make_umid(printf); | 315 | make_umid(printf); |
312 | return create_pid_file(); | 316 | create_pid_file(); |
317 | return 0; | ||
313 | } | 318 | } |
314 | __uml_postsetup(make_umid_setup); | 319 | __uml_postsetup(make_umid_setup); |
315 | 320 | ||
diff --git a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c index a25f3ea11fd7..41d17c71511c 100644 --- a/arch/um/kernel/user_util.c +++ b/arch/um/kernel/user_util.c | |||
@@ -128,6 +128,12 @@ void setup_machinename(char *machine_out) | |||
128 | struct utsname host; | 128 | struct utsname host; |
129 | 129 | ||
130 | uname(&host); | 130 | uname(&host); |
131 | #if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT) | ||
132 | if (!strcmp(host.machine, "x86_64")) { | ||
133 | strcpy(machine_out, "i686"); | ||
134 | return; | ||
135 | } | ||
136 | #endif | ||
131 | strcpy(machine_out, host.machine); | 137 | strcpy(machine_out, host.machine); |
132 | } | 138 | } |
133 | 139 | ||