diff options
author | Kyle McMartin <kyle@parisc-linux.org> | 2006-08-27 11:12:13 -0400 |
---|---|---|
committer | Matthew Wilcox <willy@parisc-linux.org> | 2006-10-04 08:46:53 -0400 |
commit | 75a4958154f5d0028d5464f2479b4297d55cf4a3 (patch) | |
tree | 54121490e3a1f423b18e78d7f216dfc32bc71b64 /arch/parisc/kernel/sys_parisc.c | |
parent | df570b9c284701d08b22aa00cbfcf870b7f1b7c1 (diff) |
[PARISC] Allow overriding personality with sys_personality
And now suddenly, linux32 works on parisc...
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Diffstat (limited to 'arch/parisc/kernel/sys_parisc.c')
-rw-r--r-- | arch/parisc/kernel/sys_parisc.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 8b5df98e2b31..1db5588ceacf 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/shm.h> | 31 | #include <linux/shm.h> |
32 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
33 | #include <linux/syscalls.h> | 33 | #include <linux/syscalls.h> |
34 | #include <linux/utsname.h> | ||
35 | #include <linux/personality.h> | ||
34 | 36 | ||
35 | int sys_pipe(int __user *fildes) | 37 | int sys_pipe(int __user *fildes) |
36 | { | 38 | { |
@@ -248,3 +250,46 @@ asmlinkage int sys_free_hugepages(unsigned long addr) | |||
248 | { | 250 | { |
249 | return -EINVAL; | 251 | return -EINVAL; |
250 | } | 252 | } |
253 | |||
254 | long parisc_personality(unsigned long personality) | ||
255 | { | ||
256 | long err; | ||
257 | |||
258 | if (personality(current->personality) == PER_LINUX32 | ||
259 | && personality == PER_LINUX) | ||
260 | personality = PER_LINUX32; | ||
261 | |||
262 | err = sys_personality(personality); | ||
263 | if (err == PER_LINUX32) | ||
264 | err = PER_LINUX; | ||
265 | |||
266 | return err; | ||
267 | } | ||
268 | |||
269 | static inline int override_machine(char __user *mach) { | ||
270 | #ifdef CONFIG_COMPAT | ||
271 | if (personality(current->personality) == PER_LINUX32) { | ||
272 | if (__put_user(0, mach + 6) || | ||
273 | __put_user(0, mach + 7)) | ||
274 | return -EFAULT; | ||
275 | } | ||
276 | |||
277 | return 0; | ||
278 | #else /*!CONFIG_COMPAT*/ | ||
279 | return 0; | ||
280 | #endif /*CONFIG_COMPAT*/ | ||
281 | } | ||
282 | |||
283 | long parisc_newuname(struct new_utsname __user *utsname) | ||
284 | { | ||
285 | int err = 0; | ||
286 | |||
287 | down_read(&uts_sem); | ||
288 | if (copy_to_user(utsname, &system_utsname, sizeof(*utsname))) | ||
289 | err = -EFAULT; | ||
290 | up_read(&uts_sem); | ||
291 | |||
292 | err = override_machine(utsname->machine); | ||
293 | |||
294 | return (long)err; | ||
295 | } | ||