aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/drivers/mconsole_kern.c15
-rw-r--r--arch/um/drivers/mconsole_user.c4
-rw-r--r--arch/um/drivers/net_kern.c98
-rw-r--r--arch/um/drivers/net_user.c1
-rw-r--r--arch/um/drivers/null.c1
-rw-r--r--arch/um/drivers/random.c4
-rw-r--r--arch/um/drivers/stderr_console.c2
-rw-r--r--arch/um/drivers/stdio_console.c1
-rw-r--r--arch/um/drivers/ubd_kern.c11
-rw-r--r--arch/um/include/net_kern.h14
-rw-r--r--arch/um/include/net_user.h18
-rw-r--r--arch/um/kernel/exitcode.c8
-rw-r--r--arch/um/kernel/skas/mmu.c6
-rw-r--r--arch/um/kernel/skas/process_kern.c484
-rw-r--r--arch/um/kernel/time.c2
-rw-r--r--arch/um/kernel/trap.c2
-rw-r--r--arch/um/os-Linux/mem.c6
17 files changed, 84 insertions, 593 deletions
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 79610b5ce6..773a134e7f 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -598,6 +598,11 @@ out:
598 mconsole_reply(req, err_msg, err, 0); 598 mconsole_reply(req, err_msg, err, 0);
599} 599}
600 600
601struct mconsole_output {
602 struct list_head list;
603 struct mc_request *req;
604};
605
601static DEFINE_SPINLOCK(console_lock); 606static DEFINE_SPINLOCK(console_lock);
602static LIST_HEAD(clients); 607static LIST_HEAD(clients);
603static char console_buf[MCONSOLE_MAX_DATA]; 608static char console_buf[MCONSOLE_MAX_DATA];
@@ -622,10 +627,10 @@ static void console_write(struct console *console, const char *string,
622 return; 627 return;
623 628
624 list_for_each(ele, &clients){ 629 list_for_each(ele, &clients){
625 struct mconsole_entry *entry; 630 struct mconsole_output *entry;
626 631
627 entry = list_entry(ele, struct mconsole_entry, list); 632 entry = list_entry(ele, struct mconsole_output, list);
628 mconsole_reply_len(&entry->request, console_buf, 633 mconsole_reply_len(entry->req, console_buf,
629 console_index, 0, 1); 634 console_index, 0, 1);
630 } 635 }
631 636
@@ -649,10 +654,10 @@ late_initcall(mc_add_console);
649static void with_console(struct mc_request *req, void (*proc)(void *), 654static void with_console(struct mc_request *req, void (*proc)(void *),
650 void *arg) 655 void *arg)
651{ 656{
652 struct mconsole_entry entry; 657 struct mconsole_output entry;
653 unsigned long flags; 658 unsigned long flags;
654 659
655 entry.request = *req; 660 entry.req = req;
656 list_add(&entry.list, &clients); 661 list_add(&entry.list, &clients);
657 spin_lock_irqsave(&console_lock, flags); 662 spin_lock_irqsave(&console_lock, flags);
658 663
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 5b2f5fe9e4..17068eb746 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -131,6 +131,10 @@ int mconsole_get_request(int fd, struct mc_request *req)
131int mconsole_reply_len(struct mc_request *req, const char *str, int total, 131int mconsole_reply_len(struct mc_request *req, const char *str, int total,
132 int err, int more) 132 int err, int more)
133{ 133{
134 /* XXX This is a stack consumption problem. It'd be nice to
135 * make it global and serialize access to it, but there are a
136 * ton of callers to this function.
137 */
134 struct mconsole_reply reply; 138 struct mconsole_reply reply;
135 int len, n; 139 int len, n;
136 140
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 664c2e2fb8..300a54a652 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -119,11 +119,6 @@ static int uml_net_open(struct net_device *dev)
119 goto out; 119 goto out;
120 } 120 }
121 121
122 if(!lp->have_mac){
123 dev_ip_addr(dev, &lp->mac[2]);
124 set_ether_mac(dev, lp->mac);
125 }
126
127 lp->fd = (*lp->open)(&lp->user); 122 lp->fd = (*lp->open)(&lp->user);
128 if(lp->fd < 0){ 123 if(lp->fd < 0){
129 err = lp->fd; 124 err = lp->fd;
@@ -287,6 +282,37 @@ void uml_net_user_timer_expire(unsigned long _conn)
287#endif 282#endif
288} 283}
289 284
285static void setup_etheraddr(char *str, unsigned char *addr)
286{
287 char *end;
288 int i;
289
290 if(str == NULL)
291 goto random;
292
293 for(i=0;i<6;i++){
294 addr[i] = simple_strtoul(str, &end, 16);
295 if((end == str) ||
296 ((*end != ':') && (*end != ',') && (*end != '\0'))){
297 printk(KERN_ERR
298 "setup_etheraddr: failed to parse '%s' "
299 "as an ethernet address\n", str);
300 goto random;
301 }
302 str = end + 1;
303 }
304 if(addr[0] & 1){
305 printk(KERN_ERR
306 "Attempt to assign a broadcast ethernet address to a "
307 "device disallowed\n");
308 goto random;
309 }
310 return;
311
312random:
313 random_ether_addr(addr);
314}
315
290static DEFINE_SPINLOCK(devices_lock); 316static DEFINE_SPINLOCK(devices_lock);
291static LIST_HEAD(devices); 317static LIST_HEAD(devices);
292 318
@@ -322,15 +348,13 @@ static int eth_configure(int n, void *init, char *mac,
322 list_add(&device->list, &devices); 348 list_add(&device->list, &devices);
323 spin_unlock(&devices_lock); 349 spin_unlock(&devices_lock);
324 350
325 if (setup_etheraddr(mac, device->mac)) 351 setup_etheraddr(mac, device->mac);
326 device->have_mac = 1;
327 352
328 printk(KERN_INFO "Netdevice %d ", n); 353 printk(KERN_INFO "Netdevice %d ", n);
329 if (device->have_mac) 354 printk("(%02x:%02x:%02x:%02x:%02x:%02x) ",
330 printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", 355 device->mac[0], device->mac[1],
331 device->mac[0], device->mac[1], 356 device->mac[2], device->mac[3],
332 device->mac[2], device->mac[3], 357 device->mac[4], device->mac[5]);
333 device->mac[4], device->mac[5]);
334 printk(": "); 358 printk(": ");
335 dev = alloc_etherdev(size); 359 dev = alloc_etherdev(size);
336 if (dev == NULL) { 360 if (dev == NULL) {
@@ -396,7 +420,6 @@ static int eth_configure(int n, void *init, char *mac,
396 .dev = dev, 420 .dev = dev,
397 .fd = -1, 421 .fd = -1,
398 .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, 422 .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
399 .have_mac = device->have_mac,
400 .protocol = transport->kern->protocol, 423 .protocol = transport->kern->protocol,
401 .open = transport->user->open, 424 .open = transport->user->open,
402 .close = transport->user->close, 425 .close = transport->user->close,
@@ -411,14 +434,12 @@ static int eth_configure(int n, void *init, char *mac,
411 init_timer(&lp->tl); 434 init_timer(&lp->tl);
412 spin_lock_init(&lp->lock); 435 spin_lock_init(&lp->lock);
413 lp->tl.function = uml_net_user_timer_expire; 436 lp->tl.function = uml_net_user_timer_expire;
414 if (lp->have_mac) 437 memcpy(lp->mac, device->mac, sizeof(lp->mac));
415 memcpy(lp->mac, device->mac, sizeof(lp->mac));
416 438
417 if (transport->user->init) 439 if (transport->user->init)
418 (*transport->user->init)(&lp->user, dev); 440 (*transport->user->init)(&lp->user, dev);
419 441
420 if (device->have_mac) 442 set_ether_mac(dev, device->mac);
421 set_ether_mac(dev, device->mac);
422 443
423 return 0; 444 return 0;
424} 445}
@@ -747,47 +768,6 @@ static void close_devices(void)
747 768
748__uml_exitcall(close_devices); 769__uml_exitcall(close_devices);
749 770
750int setup_etheraddr(char *str, unsigned char *addr)
751{
752 char *end;
753 int i;
754
755 if(str == NULL)
756 return(0);
757 for(i=0;i<6;i++){
758 addr[i] = simple_strtoul(str, &end, 16);
759 if((end == str) ||
760 ((*end != ':') && (*end != ',') && (*end != '\0'))){
761 printk(KERN_ERR
762 "setup_etheraddr: failed to parse '%s' "
763 "as an ethernet address\n", str);
764 return(0);
765 }
766 str = end + 1;
767 }
768 if(addr[0] & 1){
769 printk(KERN_ERR
770 "Attempt to assign a broadcast ethernet address to a "
771 "device disallowed\n");
772 return(0);
773 }
774 return(1);
775}
776
777void dev_ip_addr(void *d, unsigned char *bin_buf)
778{
779 struct net_device *dev = d;
780 struct in_device *ip = dev->ip_ptr;
781 struct in_ifaddr *in;
782
783 if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
784 printk(KERN_WARNING "dev_ip_addr - device not assigned an "
785 "IP address\n");
786 return;
787 }
788 memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
789}
790
791struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra) 771struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
792{ 772{
793 if((skb != NULL) && (skb_tailroom(skb) < extra)){ 773 if((skb != NULL) && (skb_tailroom(skb) < extra)){
@@ -825,7 +805,7 @@ int dev_netmask(void *d, void *m)
825 struct net_device *dev = d; 805 struct net_device *dev = d;
826 struct in_device *ip = dev->ip_ptr; 806 struct in_device *ip = dev->ip_ptr;
827 struct in_ifaddr *in; 807 struct in_ifaddr *in;
828 __u32 *mask_out = m; 808 __be32 *mask_out = m;
829 809
830 if(ip == NULL) 810 if(ip == NULL)
831 return(1); 811 return(1);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 107c5e43fa..f3a3f8a29c 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -12,6 +12,7 @@
12#include <string.h> 12#include <string.h>
13#include <sys/socket.h> 13#include <sys/socket.h>
14#include <sys/wait.h> 14#include <sys/wait.h>
15#include <sys/time.h>
15#include "user.h" 16#include "user.h"
16#include "user_util.h" 17#include "user_util.h"
17#include "kern_util.h" 18#include "kern_util.h"
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 3683ed4431..9016c68bee 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -8,6 +8,7 @@
8#include "chan_user.h" 8#include "chan_user.h"
9#include "os.h" 9#include "os.h"
10 10
11/* This address is used only as a unique identifer */
11static int null_chan; 12static int null_chan;
12 13
13static void *null_init(char *str, int device, const struct chan_opts *opts) 14static void *null_init(char *str, int device, const struct chan_opts *opts)
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index ae9909415b..73b2bdd6d2 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -20,6 +20,10 @@
20 20
21#define RNG_MISCDEV_MINOR 183 /* official */ 21#define RNG_MISCDEV_MINOR 183 /* official */
22 22
23/* Changed at init time, in the non-modular case, and at module load
24 * time, in the module case. Presumably, the module subsystem
25 * protects against a module being loaded twice at the same time.
26 */
23static int random_fd = -1; 27static int random_fd = -1;
24 28
25static int rng_dev_open (struct inode *inode, struct file *filp) 29static int rng_dev_open (struct inode *inode, struct file *filp)
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 6d2cf32a9e..9115392938 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -9,6 +9,8 @@
9/* 9/*
10 * Don't register by default -- as this registeres very early in the 10 * Don't register by default -- as this registeres very early in the
11 * boot process it becomes the default console. 11 * boot process it becomes the default console.
12 *
13 * Initialized at init time.
12 */ 14 */
13static int use_stderr_console = 0; 15static int use_stderr_console = 0;
14 16
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 5e44adb070..e4bfcfe855 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -108,6 +108,7 @@ static int con_open(struct tty_struct *tty, struct file *filp)
108 return line_open(vts, tty); 108 return line_open(vts, tty);
109} 109}
110 110
111/* Set in an initcall, checked in an exitcall */
111static int con_init_done = 0; 112static int con_init_done = 0;
112 113
113static const struct tty_operations console_ops = { 114static const struct tty_operations console_ops = {
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 34085315aa..fda4a39406 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -668,18 +668,15 @@ static int ubd_add(int n)
668 if(dev->file == NULL) 668 if(dev->file == NULL)
669 goto out; 669 goto out;
670 670
671 if (ubd_open_dev(dev))
672 goto out;
673
674 err = ubd_file_size(dev, &dev->size); 671 err = ubd_file_size(dev, &dev->size);
675 if(err < 0) 672 if(err < 0)
676 goto out_close; 673 goto out;
677 674
678 dev->size = ROUND_BLOCK(dev->size); 675 dev->size = ROUND_BLOCK(dev->size);
679 676
680 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); 677 err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
681 if(err) 678 if(err)
682 goto out_close; 679 goto out;
683 680
684 if(fake_major != MAJOR_NR) 681 if(fake_major != MAJOR_NR)
685 ubd_new_disk(fake_major, dev->size, n, 682 ubd_new_disk(fake_major, dev->size, n,
@@ -691,8 +688,6 @@ static int ubd_add(int n)
691 make_ide_entries(ubd_gendisk[n]->disk_name); 688 make_ide_entries(ubd_gendisk[n]->disk_name);
692 689
693 err = 0; 690 err = 0;
694out_close:
695 ubd_close(dev);
696out: 691out:
697 return err; 692 return err;
698} 693}
@@ -986,8 +981,6 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
986 __u64 offset; 981 __u64 offset;
987 int len; 982 int len;
988 983
989 if(req->rq_status == RQ_INACTIVE) return(1);
990
991 /* This should be impossible now */ 984 /* This should be impossible now */
992 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ 985 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
993 printk("Write attempted on readonly ubd device %s\n", 986 printk("Write attempted on readonly ubd device %s\n",
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 769fba43ee..280459fb0b 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -18,7 +18,6 @@ struct uml_net {
18 struct platform_device pdev; 18 struct platform_device pdev;
19 int index; 19 int index;
20 unsigned char mac[ETH_ALEN]; 20 unsigned char mac[ETH_ALEN];
21 int have_mac;
22}; 21};
23 22
24struct uml_net_private { 23struct uml_net_private {
@@ -29,7 +28,6 @@ struct uml_net_private {
29 struct net_device_stats stats; 28 struct net_device_stats stats;
30 int fd; 29 int fd;
31 unsigned char mac[ETH_ALEN]; 30 unsigned char mac[ETH_ALEN];
32 int have_mac;
33 unsigned short (*protocol)(struct sk_buff *); 31 unsigned short (*protocol)(struct sk_buff *);
34 int (*open)(void *); 32 int (*open)(void *);
35 void (*close)(int, void *); 33 void (*close)(int, void *);
@@ -62,7 +60,6 @@ struct transport {
62 60
63extern struct net_device *ether_init(int); 61extern struct net_device *ether_init(int);
64extern unsigned short ether_protocol(struct sk_buff *); 62extern unsigned short ether_protocol(struct sk_buff *);
65extern int setup_etheraddr(char *str, unsigned char *addr);
66extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra); 63extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
67extern int tap_setup_common(char *str, char *type, char **dev_name, 64extern int tap_setup_common(char *str, char *type, char **dev_name,
68 char **mac_out, char **gate_addr); 65 char **mac_out, char **gate_addr);
@@ -70,14 +67,3 @@ extern void register_transport(struct transport *new);
70extern unsigned short eth_protocol(struct sk_buff *skb); 67extern unsigned short eth_protocol(struct sk_buff *skb);
71 68
72#endif 69#endif
73
74/*
75 * Overrides for Emacs so that we follow Linus's tabbing style.
76 * Emacs will notice this stuff at the end of the file and automatically
77 * adjust the settings for this buffer only. This must remain at the end
78 * of the file.
79 * ---------------------------------------------------------------------------
80 * Local variables:
81 * c-file-style: "linux"
82 * End:
83 */
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 47ef7cb49a..19f207cd70 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -25,9 +25,8 @@ struct net_user_info {
25}; 25};
26 26
27extern void ether_user_init(void *data, void *dev); 27extern void ether_user_init(void *data, void *dev);
28extern void dev_ip_addr(void *d, unsigned char *bin_buf); 28extern void iter_addresses(void *d, void (*cb)(unsigned char *,
29extern void iter_addresses(void *d, void (*cb)(unsigned char *, 29 unsigned char *, void *),
30 unsigned char *, void *),
31 void *arg); 30 void *arg);
32 31
33extern void *get_output_buffer(int *len_out); 32extern void *get_output_buffer(int *len_out);
@@ -52,14 +51,3 @@ extern char *split_if_spec(char *str, ...);
52extern int dev_netmask(void *d, void *m); 51extern int dev_netmask(void *d, void *m);
53 52
54#endif 53#endif
55
56/*
57 * Overrides for Emacs so that we follow Linus's tabbing style.
58 * Emacs will notice this stuff at the end of the file and automatically
59 * adjust the settings for this buffer only. This must remain at the end
60 * of the file.
61 * ---------------------------------------------------------------------------
62 * Local variables:
63 * c-file-style: "linux"
64 * End:
65 */
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index d21ebad666..8b7f2cdedf 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -16,9 +16,13 @@ int uml_exitcode = 0;
16static int read_proc_exitcode(char *page, char **start, off_t off, 16static int read_proc_exitcode(char *page, char **start, off_t off,
17 int count, int *eof, void *data) 17 int count, int *eof, void *data)
18{ 18{
19 int len; 19 int len, val;
20 20
21 len = sprintf(page, "%d\n", uml_exitcode); 21 /* Save uml_exitcode in a local so that we don't need to guarantee
22 * that sprintf accesses it atomically.
23 */
24 val = uml_exitcode;
25 len = sprintf(page, "%d\n", val);
22 len -= off; 26 len -= off;
23 if(len <= off+count) *eof = 1; 27 if(len <= off+count) *eof = 1;
24 *start = page + off; 28 *start = page + off;
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 79c22707a6..4cd2ff546e 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -61,8 +61,10 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
61#endif 61#endif
62 62
63 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); 63 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
64 *pte = pte_mkexec(*pte); 64 /* This is wrong for the code page, but it doesn't matter since the
65 *pte = pte_wrprotect(*pte); 65 * stub is mapped by hand with the correct permissions.
66 */
67 *pte = pte_mkwrite(*pte);
66 return(0); 68 return(0);
67 69
68 out_pmd: 70 out_pmd:
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
deleted file mode 100644
index 0f3d5d084d..0000000000
--- a/arch/um/kernel/skas/process_kern.c
+++ /dev/null
@@ -1,484 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
5 */
6
7#include "linux/config.h"
8#include "linux/kernel.h"
9#include "linux/sched.h"
10#include "linux/interrupt.h"
11#include "linux/string.h"
12#include "linux/mm.h"
13#include "linux/slab.h"
14#include "linux/utsname.h"
15#include "linux/fs.h"
16#include "linux/utime.h"
17#include "linux/smp_lock.h"
18#include "linux/module.h"
19#include "linux/init.h"
20#include "linux/capability.h"
21#include "linux/vmalloc.h"
22#include "linux/spinlock.h"
23#include "linux/proc_fs.h"
24#include "linux/ptrace.h"
25#include "linux/random.h"
26#include "linux/personality.h"
27#include "asm/unistd.h"
28#include "asm/mman.h"
29#include "asm/segment.h"
30#include "asm/stat.h"
31#include "asm/pgtable.h"
32#include "asm/processor.h"
33#include "asm/tlbflush.h"
34#include "asm/uaccess.h"
35#include "asm/user.h"
36#include "user_util.h"
37#include "kern_util.h"
38#include "kern.h"
39#include "signal_kern.h"
40#include "init.h"
41#include "irq_user.h"
42#include "mem_user.h"
43#include "tlb.h"
44#include "frame_kern.h"
45#include "sigcontext.h"
46#include "os.h"
47#include "mode.h"
48#include "mode_kern.h"
49#include "choose-mode.h"
50
51/* This is a per-cpu array. A processor only modifies its entry and it only
52 * cares about its entry, so it's OK if another processor is modifying its
53 * entry.
54 */
55struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
56
57int external_pid(void *t)
58{
59 struct task_struct *task = t ? t : current;
60
61 return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task));
62}
63
64int pid_to_processor_id(int pid)
65{
66 int i;
67
68 for(i = 0; i < ncpus; i++){
69 if(cpu_tasks[i].pid == pid) return(i);
70 }
71 return(-1);
72}
73
74void free_stack(unsigned long stack, int order)
75{
76 free_pages(stack, order);
77}
78
79unsigned long alloc_stack(int order, int atomic)
80{
81 unsigned long page;
82 gfp_t flags = GFP_KERNEL;
83
84 if (atomic)
85 flags = GFP_ATOMIC;
86 page = __get_free_pages(flags, order);
87 if(page == 0)
88 return(0);
89 stack_protections(page);
90 return(page);
91}
92
93int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
94{
95 int pid;
96
97 current->thread.request.u.thread.proc = fn;
98 current->thread.request.u.thread.arg = arg;
99 pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0,
100 &current->thread.regs, 0, NULL, NULL);
101 if(pid < 0)
102 panic("do_fork failed in kernel_thread, errno = %d", pid);
103 return(pid);
104}
105
106void set_current(void *t)
107{
108 struct task_struct *task = t;
109
110 cpu_tasks[task_thread_info(task)->cpu] = ((struct cpu_task)
111 { external_pid(task), task });
112}
113
114void *_switch_to(void *prev, void *next, void *last)
115{
116 struct task_struct *from = prev;
117 struct task_struct *to= next;
118
119 to->thread.prev_sched = from;
120 set_current(to);
121
122 do {
123 current->thread.saved_task = NULL ;
124 CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next);
125 if(current->thread.saved_task)
126 show_regs(&(current->thread.regs));
127 next= current->thread.saved_task;
128 prev= current;
129 } while(current->thread.saved_task);
130
131 return(current->thread.prev_sched);
132
133}
134
135void interrupt_end(void)
136{
137 if(need_resched()) schedule();
138 if(test_tsk_thread_flag(current, TIF_SIGPENDING)) do_signal();
139}
140
141void release_thread(struct task_struct *task)
142{
143 CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
144}
145
146void exit_thread(void)
147{
148 unprotect_stack((unsigned long) current_thread);
149}
150
151void *get_current(void)
152{
153 return(current);
154}
155
156int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
157 unsigned long stack_top, struct task_struct * p,
158 struct pt_regs *regs)
159{
160 int ret;
161
162 p->thread = (struct thread_struct) INIT_THREAD;
163 ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
164 clone_flags, sp, stack_top, p, regs);
165
166 if (ret || !current->thread.forking)
167 goto out;
168
169 clear_flushed_tls(p);
170
171 /*
172 * Set a new TLS for the child thread?
173 */
174 if (clone_flags & CLONE_SETTLS)
175 ret = arch_copy_tls(p);
176
177out:
178 return ret;
179}
180
181void initial_thread_cb(void (*proc)(void *), void *arg)
182{
183 int save_kmalloc_ok = kmalloc_ok;
184
185 kmalloc_ok = 0;
186 CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc,
187 arg);
188 kmalloc_ok = save_kmalloc_ok;
189}
190
191unsigned long stack_sp(unsigned long page)
192{
193 return(page + PAGE_SIZE - sizeof(void *));
194}
195
196int current_pid(void)
197{
198 return(current->pid);
199}
200
201void default_idle(void)
202{
203 CHOOSE_MODE(uml_idle_timer(), (void) 0);
204
205 while(1){
206 /* endless idle loop with no priority at all */
207
208 /*
209 * although we are an idle CPU, we do not want to
210 * get into the scheduler unnecessarily.
211 */
212 if(need_resched())
213 schedule();
214
215 idle_sleep(10);
216 }
217}
218
219void cpu_idle(void)
220{
221 CHOOSE_MODE(init_idle_tt(), init_idle_skas());
222}
223
224int page_size(void)
225{
226 return(PAGE_SIZE);
227}
228
229void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
230 pte_t *pte_out)
231{
232 pgd_t *pgd;
233 pud_t *pud;
234 pmd_t *pmd;
235 pte_t *pte;
236 pte_t ptent;
237
238 if(task->mm == NULL)
239 return(ERR_PTR(-EINVAL));
240 pgd = pgd_offset(task->mm, addr);
241 if(!pgd_present(*pgd))
242 return(ERR_PTR(-EINVAL));
243
244 pud = pud_offset(pgd, addr);
245 if(!pud_present(*pud))
246 return(ERR_PTR(-EINVAL));
247
248 pmd = pmd_offset(pud, addr);
249 if(!pmd_present(*pmd))
250 return(ERR_PTR(-EINVAL));
251
252 pte = pte_offset_kernel(pmd, addr);
253 ptent = *pte;
254 if(!pte_present(ptent))
255 return(ERR_PTR(-EINVAL));
256
257 if(pte_out != NULL)
258 *pte_out = ptent;
259 return((void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK));
260}
261
262char *current_cmd(void)
263{
264#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM)
265 return("(Unknown)");
266#else
267 void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL);
268 return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr);
269#endif
270}
271
272void force_sigbus(void)
273{
274 printk(KERN_ERR "Killing pid %d because of a lack of memory\n",
275 current->pid);
276 lock_kernel();
277 sigaddset(&current->pending.signal, SIGBUS);
278 recalc_sigpending();
279 current->flags |= PF_SIGNALED;
280 do_exit(SIGBUS | 0x80);
281}
282
283void dump_thread(struct pt_regs *regs, struct user *u)
284{
285}
286
287void enable_hlt(void)
288{
289 panic("enable_hlt");
290}
291
292EXPORT_SYMBOL(enable_hlt);
293
294void disable_hlt(void)
295{
296 panic("disable_hlt");
297}
298
299EXPORT_SYMBOL(disable_hlt);
300
301void *um_kmalloc(int size)
302{
303 return kmalloc(size, GFP_KERNEL);
304}
305
306void *um_kmalloc_atomic(int size)
307{
308 return kmalloc(size, GFP_ATOMIC);
309}
310
311void *um_vmalloc(int size)
312{
313 return vmalloc(size);
314}
315
316void *um_vmalloc_atomic(int size)
317{
318 return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
319}
320
321int __cant_sleep(void) {
322 return in_atomic() || irqs_disabled() || in_interrupt();
323 /* Is in_interrupt() really needed? */
324}
325
326unsigned long get_fault_addr(void)
327{
328 return((unsigned long) current->thread.fault_addr);
329}
330
331EXPORT_SYMBOL(get_fault_addr);
332
333void not_implemented(void)
334{
335 printk(KERN_DEBUG "Something isn't implemented in here\n");
336}
337
338EXPORT_SYMBOL(not_implemented);
339
340int user_context(unsigned long sp)
341{
342 unsigned long stack;
343
344 stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
345 return(stack != (unsigned long) current_thread);
346}
347
348extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end;
349
350void do_uml_exitcalls(void)
351{
352 exitcall_t *call;
353
354 call = &__uml_exitcall_end;
355 while (--call >= &__uml_exitcall_begin)
356 (*call)();
357}
358
359char *uml_strdup(char *string)
360{
361 return kstrdup(string, GFP_KERNEL);
362}
363
364int copy_to_user_proc(void __user *to, void *from, int size)
365{
366 return(copy_to_user(to, from, size));
367}
368
369int copy_from_user_proc(void *to, void __user *from, int size)
370{
371 return(copy_from_user(to, from, size));
372}
373
374int clear_user_proc(void __user *buf, int size)
375{
376 return(clear_user(buf, size));
377}
378
379int strlen_user_proc(char __user *str)
380{
381 return(strlen_user(str));
382}
383
384int smp_sigio_handler(void)
385{
386#ifdef CONFIG_SMP
387 int cpu = current_thread->cpu;
388 IPI_handler(cpu);
389 if(cpu != 0)
390 return(1);
391#endif
392 return(0);
393}
394
395int cpu(void)
396{
397 return(current_thread->cpu);
398}
399
400static atomic_t using_sysemu = ATOMIC_INIT(0);
401int sysemu_supported;
402
403void set_using_sysemu(int value)
404{
405 if (value > sysemu_supported)
406 return;
407 atomic_set(&using_sysemu, value);
408}
409
410int get_using_sysemu(void)
411{
412 return atomic_read(&using_sysemu);
413}
414
415static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
416{
417 if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/
418 *eof = 1;
419
420 return strlen(buf);
421}
422
423static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data)
424{
425 char tmp[2];
426
427 if (copy_from_user(tmp, buf, 1))
428 return -EFAULT;
429
430 if (tmp[0] >= '0' && tmp[0] <= '2')
431 set_using_sysemu(tmp[0] - '0');
432 return count; /*We use the first char, but pretend to write everything*/
433}
434
435int __init make_proc_sysemu(void)
436{
437 struct proc_dir_entry *ent;
438 if (!sysemu_supported)
439 return 0;
440
441 ent = create_proc_entry("sysemu", 0600, &proc_root);
442
443 if (ent == NULL)
444 {
445 printk(KERN_WARNING "Failed to register /proc/sysemu\n");
446 return(0);
447 }
448
449 ent->read_proc = proc_read_sysemu;
450 ent->write_proc = proc_write_sysemu;
451
452 return 0;
453}
454
455late_initcall(make_proc_sysemu);
456
457int singlestepping(void * t)
458{
459 struct task_struct *task = t ? t : current;
460
461 if ( ! (task->ptrace & PT_DTRACE) )
462 return(0);
463
464 if (task->thread.singlestep_syscall)
465 return(1);
466
467 return 2;
468}
469
470/*
471 * Only x86 and x86_64 have an arch_align_stack().
472 * All other arches have "#define arch_align_stack(x) (x)"
473 * in their asm/system.h
474 * As this is included in UML from asm-um/system-generic.h,
475 * we can use it to behave as the subarch does.
476 */
477#ifndef arch_align_stack
478unsigned long arch_align_stack(unsigned long sp)
479{
480 if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
481 sp -= get_random_int() % 8192;
482 return sp & ~0xf;
483}
484#endif
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 820affbf3e..a92965f8f9 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -93,7 +93,7 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
93 93
94 write_seqlock_irqsave(&xtime_lock, flags); 94 write_seqlock_irqsave(&xtime_lock, flags);
95 95
96 do_timer(regs); 96 do_timer(1);
97 97
98 nsecs = get_time(); 98 nsecs = get_time();
99 xtime.tv_sec = nsecs / NSEC_PER_SEC; 99 xtime.tv_sec = nsecs / NSEC_PER_SEC;
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 61a23fff43..c7b195c7e5 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -120,7 +120,7 @@ out_nosemaphore:
120 * us unable to handle the page fault gracefully. 120 * us unable to handle the page fault gracefully.
121 */ 121 */
122out_of_memory: 122out_of_memory:
123 if (current->pid == 1) { 123 if (is_init(current)) {
124 up_read(&mm->mmap_sem); 124 up_read(&mm->mmap_sem);
125 yield(); 125 yield();
126 down_read(&mm->mmap_sem); 126 down_read(&mm->mmap_sem);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index b170b4704d..4203681e50 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -132,6 +132,9 @@ err:
132 else if(found < 0) 132 else if(found < 0)
133 printf("read returned errno %d\n", -found); 133 printf("read returned errno %d\n", -found);
134 134
135out:
136 close(fd);
137
135 return; 138 return;
136 139
137found: 140found:
@@ -141,11 +144,12 @@ found:
141 144
142 if(strncmp(buf, "tmpfs", strlen("tmpfs"))){ 145 if(strncmp(buf, "tmpfs", strlen("tmpfs"))){
143 printf("not tmpfs\n"); 146 printf("not tmpfs\n");
144 return; 147 goto out;
145 } 148 }
146 149
147 printf("OK\n"); 150 printf("OK\n");
148 default_tmpdir = "/dev/shm"; 151 default_tmpdir = "/dev/shm";
152 goto out;
149} 153}
150 154
151/* 155/*