aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2005-09-25 08:51:50 -0400
committerPaul Mackerras <paulus@samba.org>2005-09-25 08:51:50 -0400
commite5baa396af7560382d2cf3f0871d616b61fc284c (patch)
tree6afc166894b8c8b3b2cf6add72a726be14ae2443 /arch/um/kernel
parentd6a4c847e43c851cc0ddf73087a730227223f989 (diff)
parentef6bd6eb90ad72ee8ee7ba8b271f27102e9a90c1 (diff)
Merge from Linus' tree.
Diffstat (limited to 'arch/um/kernel')
-rw-r--r--arch/um/kernel/process_kern.c3
-rw-r--r--arch/um/kernel/sigio_user.c2
-rw-r--r--arch/um/kernel/skas/include/uaccess-skas.h6
-rw-r--r--arch/um/kernel/tlb.c12
-rw-r--r--arch/um/kernel/trap_kern.c18
-rw-r--r--arch/um/kernel/tt/include/uaccess-tt.h6
-rw-r--r--arch/um/kernel/tt/process_kern.c3
-rw-r--r--arch/um/kernel/tt/uaccess_user.c11
-rw-r--r--arch/um/kernel/umid.c41
-rw-r--r--arch/um/kernel/user_util.c6
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
21static 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
27extern int copy_from_user_skas(void *to, const void __user *from, int n); 21extern int copy_from_user_skas(void *to, const void __user *from, int n);
28extern int copy_to_user_skas(void __user *to, const void *from, int n); 22extern int copy_to_user_skas(void __user *to, const void *from, int n);
29extern int strncpy_from_user_skas(char *dst, const char __user *src, int count); 23extern 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);
90out: 97out:
91 up_read(&mm->mmap_sem); 98 up_read(&mm->mmap_sem);
99out_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
36static 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
42extern unsigned long get_fault_addr(void); 36extern unsigned long get_fault_addr(void);
43 37
44extern int __do_copy_from_user(void *to, const void *from, int n, 38extern 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
29int switch_to_tt(void *prev, void *next, void *last) 30void 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
29static void __do_strncpy(void *dst, const void *src, int count) 36static 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 */
32static int umid_is_random = 1; 32static int umid_is_random = 1;
33static int umid_inited = 0; 33static int umid_inited = 0;
34/* Have we created the files? Should we remove them? */
35static int umid_owned = 0;
34 36
35static int make_umid(int (*printer)(const char *fmt, ...)); 37static 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
83extern int tracing_pid; 85extern int tracing_pid;
84 86
85static int __init create_pid_file(void) 87static 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
109static int actually_do_remove(char *dir) 111static int actually_do_remove(char *dir)
@@ -147,7 +149,8 @@ static int actually_do_remove(char *dir)
147void remove_umid_dir(void) 149void 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
156char *get_umid(int only_if_set) 159char *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
162int not_dead_yet(char *dir) 166static 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