aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig5
-rw-r--r--arch/um/Kconfig_char6
-rw-r--r--arch/um/Makefile2
-rw-r--r--arch/um/drivers/Makefile6
-rw-r--r--arch/um/drivers/chan_user.c26
-rw-r--r--arch/um/drivers/line.c3
-rw-r--r--arch/um/drivers/mmapper_kern.c24
-rw-r--r--arch/um/drivers/net_kern.c1
-rw-r--r--arch/um/drivers/net_user.c2
-rw-r--r--arch/um/drivers/port_kern.c1
-rw-r--r--arch/um/drivers/slip.h23
-rw-r--r--arch/um/drivers/slip_common.c54
-rw-r--r--arch/um/drivers/slip_common.h (renamed from arch/um/drivers/slip_proto.h)47
-rw-r--r--arch/um/drivers/slip_kern.c12
-rw-r--r--arch/um/drivers/slip_user.c152
-rw-r--r--arch/um/drivers/slirp.h26
-rw-r--r--arch/um/drivers/slirp_kern.c5
-rw-r--r--arch/um/drivers/slirp_user.c104
-rw-r--r--arch/um/drivers/stderr_console.c6
-rw-r--r--arch/um/drivers/xterm_kern.c1
-rw-r--r--arch/um/include/mconsole.h2
-rw-r--r--arch/um/include/net_user.h2
-rw-r--r--arch/um/include/os.h2
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h5
-rw-r--r--arch/um/include/user_util.h3
-rw-r--r--arch/um/kernel/irq.c11
-rw-r--r--arch/um/kernel/irq_user.c2
-rw-r--r--arch/um/kernel/main.c2
-rw-r--r--arch/um/kernel/mem.c1
-rw-r--r--arch/um/kernel/process.c49
-rw-r--r--arch/um/kernel/skas/process_kern.c7
-rw-r--r--arch/um/kernel/tt/Makefile15
-rw-r--r--arch/um/kernel/tt/unmap.c31
-rw-r--r--arch/um/kernel/um_arch.c1
-rw-r--r--arch/um/kernel/uml.lds.S15
-rw-r--r--arch/um/os-Linux/elf_aux.c6
-rw-r--r--arch/um/os-Linux/file.c2
-rw-r--r--arch/um/scripts/Makefile.rules8
-rw-r--r--arch/um/scripts/Makefile.unmap22
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/unmap.c25
-rw-r--r--arch/um/sys-x86_64/Makefile2
-rw-r--r--arch/um/sys-x86_64/unmap.c25
43 files changed, 365 insertions, 381 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index c5292181a6..b8e952c88f 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -35,6 +35,11 @@ config GENERIC_CALIBRATE_DELAY
35 bool 35 bool
36 default y 36 default y
37 37
38# Used in kernel/irq/manage.c and include/linux/irq.h
39config IRQ_RELEASE_METHOD
40 bool
41 default y
42
38menu "UML-specific options" 43menu "UML-specific options"
39 44
40config MODE_TT 45config MODE_TT
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char
index 3e50fdb676..62d87b7117 100644
--- a/arch/um/Kconfig_char
+++ b/arch/um/Kconfig_char
@@ -204,5 +204,11 @@ config UML_RANDOM
204 http://sourceforge.net/projects/gkernel/). rngd periodically reads 204 http://sourceforge.net/projects/gkernel/). rngd periodically reads
205 /dev/hwrng and injects the entropy into /dev/random. 205 /dev/hwrng and injects the entropy into /dev/random.
206 206
207config MMAPPER
208 tristate "iomem emulation driver"
209 help
210 This driver allows a host file to be used as emulated IO memory inside
211 UML.
212
207endmenu 213endmenu
208 214
diff --git a/arch/um/Makefile b/arch/um/Makefile
index f2a0c40a92..3f07390235 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -122,7 +122,7 @@ endif
122CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \ 122CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \
123 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ 123 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
124 -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \ 124 -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \
125 -DKERNEL_STACK_SIZE=$(STACK_SIZE)) 125 -DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH))
126 126
127#The wrappers will select whether using "malloc" or the kernel allocator. 127#The wrappers will select whether using "malloc" or the kernel allocator.
128LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc 128LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 323f72c64c..b2de9916c3 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -22,8 +22,8 @@ obj-y := stdio_console.o fd.o chan_kern.o chan_user.o line.o
22obj-$(CONFIG_SSL) += ssl.o 22obj-$(CONFIG_SSL) += ssl.o
23obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o 23obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
24 24
25obj-$(CONFIG_UML_NET_SLIP) += slip.o 25obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
26obj-$(CONFIG_UML_NET_SLIRP) += slirp.o 26obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
27obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 27obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
28obj-$(CONFIG_UML_NET_MCAST) += mcast.o 28obj-$(CONFIG_UML_NET_MCAST) += mcast.o
29#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP) 29#obj-$(CONFIG_UML_NET_PCAP) += pcap.o $(PCAP)
@@ -41,6 +41,6 @@ obj-$(CONFIG_UML_WATCHDOG) += harddog.o
41obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o 41obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
42obj-$(CONFIG_UML_RANDOM) += random.o 42obj-$(CONFIG_UML_RANDOM) += random.o
43 43
44USER_OBJS := fd.o null.o pty.o tty.o xterm.o 44USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o
45 45
46include arch/um/scripts/Makefile.rules 46include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 583b8e137c..5d3768156c 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -143,22 +143,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
143{ 143{
144 struct winch_data data; 144 struct winch_data data;
145 unsigned long stack; 145 unsigned long stack;
146 int fds[2], pid, n, err; 146 int fds[2], n, err;
147 char c; 147 char c;
148 148
149 err = os_pipe(fds, 1, 1); 149 err = os_pipe(fds, 1, 1);
150 if(err < 0){ 150 if(err < 0){
151 printk("winch_tramp : os_pipe failed, err = %d\n", -err); 151 printk("winch_tramp : os_pipe failed, err = %d\n", -err);
152 return(err); 152 goto out;
153 } 153 }
154 154
155 data = ((struct winch_data) { .pty_fd = fd, 155 data = ((struct winch_data) { .pty_fd = fd,
156 .pipe_fd = fds[1], 156 .pipe_fd = fds[1],
157 .close_me = fds[0] } ); 157 .close_me = fds[0] } );
158 pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); 158 err = run_helper_thread(winch_thread, &data, 0, &stack, 0);
159 if(pid < 0){ 159 if(err < 0){
160 printk("fork of winch_thread failed - errno = %d\n", errno); 160 printk("fork of winch_thread failed - errno = %d\n", errno);
161 return(pid); 161 goto out_close;
162 } 162 }
163 163
164 os_close_file(fds[1]); 164 os_close_file(fds[1]);
@@ -168,14 +168,22 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out)
168 printk("winch_tramp : failed to read synchronization byte\n"); 168 printk("winch_tramp : failed to read synchronization byte\n");
169 printk("read failed, err = %d\n", -n); 169 printk("read failed, err = %d\n", -n);
170 printk("fd %d will not support SIGWINCH\n", fd); 170 printk("fd %d will not support SIGWINCH\n", fd);
171 *fd_out = -1; 171 err = -EINVAL;
172 goto out_close1;
172 } 173 }
173 return(pid); 174 return err ;
175
176 out_close:
177 os_close_file(fds[1]);
178 out_close1:
179 os_close_file(fds[0]);
180 out:
181 return err;
174} 182}
175 183
176void register_winch(int fd, struct tty_struct *tty) 184void register_winch(int fd, struct tty_struct *tty)
177{ 185{
178 int pid, thread, thread_fd; 186 int pid, thread, thread_fd = -1;
179 int count; 187 int count;
180 char c = 1; 188 char c = 1;
181 189
@@ -186,7 +194,7 @@ void register_winch(int fd, struct tty_struct *tty)
186 if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 194 if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd,
187 tty) && (pid == -1)){ 195 tty) && (pid == -1)){
188 thread = winch_tramp(fd, tty, &thread_fd); 196 thread = winch_tramp(fd, tty, &thread_fd);
189 if(fd != -1){ 197 if(thread > 0){
190 register_winch_irq(thread_fd, fd, thread, tty); 198 register_winch_irq(thread_fd, fd, thread, tty);
191 199
192 count = os_write_file(thread_fd, &c, sizeof(c)); 200 count = os_write_file(thread_fd, &c, sizeof(c));
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 025d3be8ac..0f59736db3 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -406,14 +406,12 @@ void line_disable(struct tty_struct *tty, int current_irq)
406 if(line->driver->read_irq == current_irq) 406 if(line->driver->read_irq == current_irq)
407 free_irq_later(line->driver->read_irq, tty); 407 free_irq_later(line->driver->read_irq, tty);
408 else { 408 else {
409 free_irq_by_irq_and_dev(line->driver->read_irq, tty);
410 free_irq(line->driver->read_irq, tty); 409 free_irq(line->driver->read_irq, tty);
411 } 410 }
412 411
413 if(line->driver->write_irq == current_irq) 412 if(line->driver->write_irq == current_irq)
414 free_irq_later(line->driver->write_irq, tty); 413 free_irq_later(line->driver->write_irq, tty);
415 else { 414 else {
416 free_irq_by_irq_and_dev(line->driver->write_irq, tty);
417 free_irq(line->driver->write_irq, tty); 415 free_irq(line->driver->write_irq, tty);
418 } 416 }
419 417
@@ -758,7 +756,6 @@ static void unregister_winch(struct tty_struct *tty)
758 if(winch->pid != -1) 756 if(winch->pid != -1)
759 os_kill_process(winch->pid, 1); 757 os_kill_process(winch->pid, 1);
760 758
761 free_irq_by_irq_and_dev(WINCH_IRQ, winch);
762 free_irq(WINCH_IRQ, winch); 759 free_irq(WINCH_IRQ, winch);
763 list_del(&winch->list); 760 list_del(&winch->list);
764 kfree(winch); 761 kfree(winch);
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index a63231dffe..a37a5ac13c 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -18,6 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/smp_lock.h> 20#include <linux/smp_lock.h>
21#include <linux/miscdevice.h>
21#include <asm/uaccess.h> 22#include <asm/uaccess.h>
22#include <asm/irq.h> 23#include <asm/irq.h>
23#include <asm/pgtable.h> 24#include <asm/pgtable.h>
@@ -117,24 +118,39 @@ static struct file_operations mmapper_fops = {
117 .release = mmapper_release, 118 .release = mmapper_release,
118}; 119};
119 120
121static struct miscdevice mmapper_dev = {
122 .minor = MISC_DYNAMIC_MINOR,
123 .name = "mmapper",
124 .fops = &mmapper_fops
125};
126
120static int __init mmapper_init(void) 127static int __init mmapper_init(void)
121{ 128{
129 int err;
130
122 printk(KERN_INFO "Mapper v0.1\n"); 131 printk(KERN_INFO "Mapper v0.1\n");
123 132
124 v_buf = (char *) find_iomem("mmapper", &mmapper_size); 133 v_buf = (char *) find_iomem("mmapper", &mmapper_size);
125 if(mmapper_size == 0){ 134 if(mmapper_size == 0){
126 printk(KERN_ERR "mmapper_init - find_iomem failed\n"); 135 printk(KERN_ERR "mmapper_init - find_iomem failed\n");
127 return(0); 136 goto out;
128 } 137 }
129 138
130 p_buf = __pa(v_buf); 139 err = misc_register(&mmapper_dev);
140 if(err){
141 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
142 err);
143 goto out;
144 }
131 145
132 devfs_mk_cdev(MKDEV(30, 0), S_IFCHR|S_IRUGO|S_IWUGO, "mmapper"); 146 p_buf = __pa(v_buf);
133 return(0); 147out:
148 return 0;
134} 149}
135 150
136static void mmapper_exit(void) 151static void mmapper_exit(void)
137{ 152{
153 misc_deregister(&mmapper_dev);
138} 154}
139 155
140module_init(mmapper_init); 156module_init(mmapper_init);
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 4eeaf88c1e..5388a74286 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -146,7 +146,6 @@ static int uml_net_close(struct net_device *dev)
146 netif_stop_queue(dev); 146 netif_stop_queue(dev);
147 spin_lock(&lp->lock); 147 spin_lock(&lp->lock);
148 148
149 free_irq_by_irq_and_dev(dev->irq, dev);
150 free_irq(dev->irq, dev); 149 free_irq(dev->irq, dev);
151 if(lp->close != NULL) 150 if(lp->close != NULL)
152 (*lp->close)(lp->fd, &lp->user); 151 (*lp->close)(lp->fd, &lp->user);
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index 47229fe4a8..3730d4f127 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -32,7 +32,7 @@ int tap_open_common(void *dev, char *gate_addr)
32 return(0); 32 return(0);
33} 33}
34 34
35void tap_check_ips(char *gate_addr, char *eth_addr) 35void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
36{ 36{
37 int tap_addr[4]; 37 int tap_addr[4];
38 38
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index b5ee07472f..c41efd207f 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -257,7 +257,6 @@ int port_wait(void *data)
257 * connection. Then we loop here throwing out failed 257 * connection. Then we loop here throwing out failed
258 * connections until a good one is found. 258 * connections until a good one is found.
259 */ 259 */
260 free_irq_by_irq_and_dev(TELNETD_IRQ, conn);
261 free_irq(TELNETD_IRQ, conn); 260 free_irq(TELNETD_IRQ, conn);
262 261
263 if(conn->fd >= 0) break; 262 if(conn->fd >= 0) break;
diff --git a/arch/um/drivers/slip.h b/arch/um/drivers/slip.h
index 495f2f1b14..bb0dab41c2 100644
--- a/arch/um/drivers/slip.h
+++ b/arch/um/drivers/slip.h
@@ -1,10 +1,7 @@
1#ifndef __UM_SLIP_H 1#ifndef __UM_SLIP_H
2#define __UM_SLIP_H 2#define __UM_SLIP_H
3 3
4#define BUF_SIZE 1500 4#include "slip_common.h"
5 /* two bytes each for a (pathological) max packet of escaped chars + *
6 * terminating END char + initial END char */
7#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8 5
9struct slip_data { 6struct slip_data {
10 void *dev; 7 void *dev;
@@ -12,28 +9,12 @@ struct slip_data {
12 char *addr; 9 char *addr;
13 char *gate_addr; 10 char *gate_addr;
14 int slave; 11 int slave;
15 char ibuf[ENC_BUF_SIZE]; 12 struct slip_proto slip;
16 char obuf[ENC_BUF_SIZE];
17 int more; /* more data: do not read fd until ibuf has been drained */
18 int pos;
19 int esc;
20}; 13};
21 14
22extern struct net_user_info slip_user_info; 15extern struct net_user_info slip_user_info;
23 16
24extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
25extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); 17extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri);
26extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); 18extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri);
27 19
28#endif 20#endif
29
30/*
31 * Overrides for Emacs so that we follow Linus's tabbing style.
32 * Emacs will notice this stuff at the end of the file and automatically
33 * adjust the settings for this buffer only. This must remain at the end
34 * of the file.
35 * ---------------------------------------------------------------------------
36 * Local variables:
37 * c-file-style: "linux"
38 * End:
39 */
diff --git a/arch/um/drivers/slip_common.c b/arch/um/drivers/slip_common.c
new file mode 100644
index 0000000000..e89cfc68fc
--- /dev/null
+++ b/arch/um/drivers/slip_common.c
@@ -0,0 +1,54 @@
1#include <string.h>
2#include "slip_common.h"
3#include "net_user.h"
4
5int slip_proto_read(int fd, void *buf, int len, struct slip_proto *slip)
6{
7 int i, n, size, start;
8
9 if(slip->more > 0){
10 i = 0;
11 while(i < slip->more){
12 size = slip_unesc(slip->ibuf[i++], slip->ibuf,
13 &slip->pos, &slip->esc);
14 if(size){
15 memcpy(buf, slip->ibuf, size);
16 memmove(slip->ibuf, &slip->ibuf[i],
17 slip->more - i);
18 slip->more = slip->more - i;
19 return size;
20 }
21 }
22 slip->more = 0;
23 }
24
25 n = net_read(fd, &slip->ibuf[slip->pos],
26 sizeof(slip->ibuf) - slip->pos);
27 if(n <= 0)
28 return n;
29
30 start = slip->pos;
31 for(i = 0; i < n; i++){
32 size = slip_unesc(slip->ibuf[start + i], slip->ibuf,&slip->pos,
33 &slip->esc);
34 if(size){
35 memcpy(buf, slip->ibuf, size);
36 memmove(slip->ibuf, &slip->ibuf[start+i+1],
37 n - (i + 1));
38 slip->more = n - (i + 1);
39 return size;
40 }
41 }
42 return 0;
43}
44
45int slip_proto_write(int fd, void *buf, int len, struct slip_proto *slip)
46{
47 int actual, n;
48
49 actual = slip_esc(buf, slip->obuf, len);
50 n = net_write(fd, slip->obuf, actual);
51 if(n < 0)
52 return n;
53 else return len;
54}
diff --git a/arch/um/drivers/slip_proto.h b/arch/um/drivers/slip_common.h
index 7206361ace..2ae76d8f1b 100644
--- a/arch/um/drivers/slip_proto.h
+++ b/arch/um/drivers/slip_common.h
@@ -1,10 +1,10 @@
1/* 1#ifndef __UM_SLIP_COMMON_H
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2#define __UM_SLIP_COMMON_H
3 * Licensed under the GPL
4 */
5 3
6#ifndef __UM_SLIP_PROTO_H__ 4#define BUF_SIZE 1500
7#define __UM_SLIP_PROTO_H__ 5 /* two bytes each for a (pathological) max packet of escaped chars + *
6 * terminating END char + initial END char */
7#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8 8
9/* SLIP protocol characters. */ 9/* SLIP protocol characters. */
10#define SLIP_END 0300 /* indicates end of frame */ 10#define SLIP_END 0300 /* indicates end of frame */
@@ -12,7 +12,8 @@
12#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ 12#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */
13#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ 13#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
14 14
15static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc) 15static inline int slip_unesc(unsigned char c, unsigned char *buf, int *pos,
16 int *esc)
16{ 17{
17 int ret; 18 int ret;
18 19
@@ -79,15 +80,25 @@ static inline int slip_esc(unsigned char *s, unsigned char *d, int len)
79 return (ptr - d); 80 return (ptr - d);
80} 81}
81 82
82#endif 83struct slip_proto {
84 unsigned char ibuf[ENC_BUF_SIZE];
85 unsigned char obuf[ENC_BUF_SIZE];
86 int more; /* more data: do not read fd until ibuf has been drained */
87 int pos;
88 int esc;
89};
90
91#define SLIP_PROTO_INIT { \
92 .ibuf = { '\0' }, \
93 .obuf = { '\0' }, \
94 .more = 0, \
95 .pos = 0, \
96 .esc = 0 \
97}
83 98
84/* 99extern int slip_proto_read(int fd, void *buf, int len,
85 * Overrides for Emacs so that we follow Linus's tabbing style. 100 struct slip_proto *slip);
86 * Emacs will notice this stuff at the end of the file and automatically 101extern int slip_proto_write(int fd, void *buf, int len,
87 * adjust the settings for this buffer only. This must remain at the end 102 struct slip_proto *slip);
88 * of the file. 103
89 * --------------------------------------------------------------------------- 104#endif
90 * Local variables:
91 * c-file-style: "linux"
92 * End:
93 */
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 0886eedba2..9a6f5c85f9 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -26,16 +26,16 @@ void slip_init(struct net_device *dev, void *data)
26 .addr = NULL, 26 .addr = NULL,
27 .gate_addr = init->gate_addr, 27 .gate_addr = init->gate_addr,
28 .slave = -1, 28 .slave = -1,
29 .ibuf = { '\0' }, 29 .slip = SLIP_PROTO_INIT,
30 .obuf = { '\0' },
31 .pos = 0,
32 .esc = 0,
33 .dev = dev }); 30 .dev = dev });
34 31
35 dev->init = NULL; 32 dev->init = NULL;
33 dev->header_cache_update = NULL;
34 dev->hard_header_cache = NULL;
35 dev->hard_header = NULL;
36 dev->hard_header_len = 0; 36 dev->hard_header_len = 0;
37 dev->addr_len = 4; 37 dev->addr_len = 0;
38 dev->type = ARPHRD_ETHER; 38 dev->type = ARPHRD_SLIP;
39 dev->tx_queue_len = 256; 39 dev->tx_queue_len = 256;
40 dev->flags = IFF_NOARP; 40 dev->flags = IFF_NOARP;
41 printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr); 41 printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr);
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index d94846b1b4..71af444e59 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -13,7 +13,7 @@
13#include "user.h" 13#include "user.h"
14#include "net_user.h" 14#include "net_user.h"
15#include "slip.h" 15#include "slip.h"
16#include "slip_proto.h" 16#include "slip_common.h"
17#include "helper.h" 17#include "helper.h"
18#include "os.h" 18#include "os.h"
19 19
@@ -77,41 +77,51 @@ static int slip_tramp(char **argv, int fd)
77 err = os_pipe(fds, 1, 0); 77 err = os_pipe(fds, 1, 0);
78 if(err < 0){ 78 if(err < 0){
79 printk("slip_tramp : pipe failed, err = %d\n", -err); 79 printk("slip_tramp : pipe failed, err = %d\n", -err);
80 return(err); 80 goto out;
81 } 81 }
82 82
83 err = 0; 83 err = 0;
84 pe_data.stdin = fd; 84 pe_data.stdin = fd;
85 pe_data.stdout = fds[1]; 85 pe_data.stdout = fds[1];
86 pe_data.close_me = fds[0]; 86 pe_data.close_me = fds[0];
87 pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); 87 err = run_helper(slip_pre_exec, &pe_data, argv, NULL);
88 if(err < 0)
89 goto out_close;
90 pid = err;
91
92 output_len = page_size();
93 output = um_kmalloc(output_len);
94 if(output == NULL){
95 printk("slip_tramp : failed to allocate output buffer\n");
96 os_kill_process(pid, 1);
97 err = -ENOMEM;
98 goto out_free;
99 }
88 100
89 if(pid < 0) err = pid; 101 os_close_file(fds[1]);
90 else { 102 read_output(fds[0], output, output_len);
91 output_len = page_size(); 103 printk("%s", output);
92 output = um_kmalloc(output_len); 104
93 if(output == NULL) 105 CATCH_EINTR(err = waitpid(pid, &status, 0));
94 printk("slip_tramp : failed to allocate output " 106 if(err < 0)
95 "buffer\n"); 107 err = errno;
96 108 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
97 os_close_file(fds[1]); 109 printk("'%s' didn't exit with status 0\n", argv[0]);
98 read_output(fds[0], output, output_len); 110 err = -EINVAL;
99 if(output != NULL){
100 printk("%s", output);
101 kfree(output);
102 }
103 CATCH_EINTR(err = waitpid(pid, &status, 0));
104 if(err < 0)
105 err = errno;
106 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
107 printk("'%s' didn't exit with status 0\n", argv[0]);
108 err = -EINVAL;
109 }
110 } 111 }
112 else err = 0;
111 113
112 os_close_file(fds[0]); 114 os_close_file(fds[0]);
113 115
114 return(err); 116out_free:
117 kfree(output);
118 return err;
119
120out_close:
121 os_close_file(fds[0]);
122 os_close_file(fds[1]);
123out:
124 return err;
115} 125}
116 126
117static int slip_open(void *data) 127static int slip_open(void *data)
@@ -123,21 +133,26 @@ static int slip_open(void *data)
123 NULL }; 133 NULL };
124 int sfd, mfd, err; 134 int sfd, mfd, err;
125 135
126 mfd = get_pty(); 136 err = get_pty();
127 if(mfd < 0){ 137 if(err < 0){
128 printk("umn : Failed to open pty, err = %d\n", -mfd); 138 printk("slip-open : Failed to open pty, err = %d\n", -err);
129 return(mfd); 139 goto out;
130 } 140 }
131 sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); 141 mfd = err;
132 if(sfd < 0){ 142
133 printk("Couldn't open tty for slip line, err = %d\n", -sfd); 143 err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
134 os_close_file(mfd); 144 if(err < 0){
135 return(sfd); 145 printk("Couldn't open tty for slip line, err = %d\n", -err);
146 goto out_close;
136 } 147 }
137 if(set_up_tty(sfd)) return(-1); 148 sfd = err;
149
150 if(set_up_tty(sfd))
151 goto out_close2;
152
138 pri->slave = sfd; 153 pri->slave = sfd;
139 pri->pos = 0; 154 pri->slip.pos = 0;
140 pri->esc = 0; 155 pri->slip.esc = 0;
141 if(pri->gate_addr != NULL){ 156 if(pri->gate_addr != NULL){
142 sprintf(version_buf, "%d", UML_NET_VERSION); 157 sprintf(version_buf, "%d", UML_NET_VERSION);
143 strcpy(gate_buf, pri->gate_addr); 158 strcpy(gate_buf, pri->gate_addr);
@@ -146,12 +161,12 @@ static int slip_open(void *data)
146 161
147 if(err < 0){ 162 if(err < 0){
148 printk("slip_tramp failed - err = %d\n", -err); 163 printk("slip_tramp failed - err = %d\n", -err);
149 return(err); 164 goto out_close2;
150 } 165 }
151 err = os_get_ifname(pri->slave, pri->name); 166 err = os_get_ifname(pri->slave, pri->name);
152 if(err < 0){ 167 if(err < 0){
153 printk("get_ifname failed, err = %d\n", -err); 168 printk("get_ifname failed, err = %d\n", -err);
154 return(err); 169 goto out_close2;
155 } 170 }
156 iter_addresses(pri->dev, open_addr, pri->name); 171 iter_addresses(pri->dev, open_addr, pri->name);
157 } 172 }
@@ -160,10 +175,16 @@ static int slip_open(void *data)
160 if(err < 0){ 175 if(err < 0){
161 printk("Failed to set slip discipline encapsulation - " 176 printk("Failed to set slip discipline encapsulation - "
162 "err = %d\n", -err); 177 "err = %d\n", -err);
163 return(err); 178 goto out_close2;
164 } 179 }
165 } 180 }
166 return(mfd); 181 return(mfd);
182out_close2:
183 os_close_file(sfd);
184out_close:
185 os_close_file(mfd);
186out:
187 return err;
167} 188}
168 189
169static void slip_close(int fd, void *data) 190static void slip_close(int fd, void *data)
@@ -190,48 +211,12 @@ static void slip_close(int fd, void *data)
190 211
191int slip_user_read(int fd, void *buf, int len, struct slip_data *pri) 212int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
192{ 213{
193 int i, n, size, start; 214 return slip_proto_read(fd, buf, len, &pri->slip);
194
195 if(pri->more>0) {
196 i = 0;
197 while(i < pri->more) {
198 size = slip_unesc(pri->ibuf[i++],
199 pri->ibuf, &pri->pos, &pri->esc);
200 if(size){
201 memcpy(buf, pri->ibuf, size);
202 memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
203 pri->more=pri->more-i;
204 return(size);
205 }
206 }
207 pri->more=0;
208 }
209
210 n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
211 if(n <= 0) return(n);
212
213 start = pri->pos;
214 for(i = 0; i < n; i++){
215 size = slip_unesc(pri->ibuf[start + i],
216 pri->ibuf, &pri->pos, &pri->esc);
217 if(size){
218 memcpy(buf, pri->ibuf, size);
219 memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
220 pri->more=n-(i+1);
221 return(size);
222 }
223 }
224 return(0);
225} 215}
226 216
227int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) 217int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
228{ 218{
229 int actual, n; 219 return slip_proto_write(fd, buf, len, &pri->slip);
230
231 actual = slip_esc(buf, pri->obuf, len);
232 n = net_write(fd, pri->obuf, actual);
233 if(n < 0) return(n);
234 else return(len);
235} 220}
236 221
237static int slip_set_mtu(int mtu, void *data) 222static int slip_set_mtu(int mtu, void *data)
@@ -267,14 +252,3 @@ struct net_user_info slip_user_info = {
267 .delete_address = slip_del_addr, 252 .delete_address = slip_del_addr,
268 .max_packet = BUF_SIZE 253 .max_packet = BUF_SIZE
269}; 254};
270
271/*
272 * Overrides for Emacs so that we follow Linus's tabbing style.
273 * Emacs will notice this stuff at the end of the file and automatically
274 * adjust the settings for this buffer only. This must remain at the end
275 * of the file.
276 * ---------------------------------------------------------------------------
277 * Local variables:
278 * c-file-style: "linux"
279 * End:
280 */
diff --git a/arch/um/drivers/slirp.h b/arch/um/drivers/slirp.h
index 04e407d1e4..6cf88ab580 100644
--- a/arch/um/drivers/slirp.h
+++ b/arch/um/drivers/slirp.h
@@ -1,10 +1,7 @@
1#ifndef __UM_SLIRP_H 1#ifndef __UM_SLIRP_H
2#define __UM_SLIRP_H 2#define __UM_SLIRP_H
3 3
4#define BUF_SIZE 1500 4#include "slip_common.h"
5 /* two bytes each for a (pathological) max packet of escaped chars + *
6 * terminating END char + initial END char */
7#define ENC_BUF_SIZE (2 * BUF_SIZE + 2)
8 5
9#define SLIRP_MAX_ARGS 100 6#define SLIRP_MAX_ARGS 100
10/* 7/*
@@ -24,28 +21,13 @@ struct slirp_data {
24 struct arg_list_dummy_wrapper argw; 21 struct arg_list_dummy_wrapper argw;
25 int pid; 22 int pid;
26 int slave; 23 int slave;
27 char ibuf[ENC_BUF_SIZE]; 24 struct slip_proto slip;
28 char obuf[ENC_BUF_SIZE];
29 int more; /* more data: do not read fd until ibuf has been drained */
30 int pos;
31 int esc;
32}; 25};
33 26
34extern struct net_user_info slirp_user_info; 27extern struct net_user_info slirp_user_info;
35 28
36extern int set_umn_addr(int fd, char *addr, char *ptp_addr);
37extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); 29extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri);
38extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri); 30extern int slirp_user_write(int fd, void *buf, int len,
31 struct slirp_data *pri);
39 32
40#endif 33#endif
41
42/*
43 * Overrides for Emacs so that we follow Linus's tabbing style.
44 * Emacs will notice this stuff at the end of the file and automatically
45 * adjust the settings for this buffer only. This must remain at the end
46 * of the file.
47 * ---------------------------------------------------------------------------
48 * Local variables:
49 * c-file-style: "linux"
50 * End:
51 */
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index c9d6b52a83..9864d27afd 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -25,10 +25,7 @@ void slirp_init(struct net_device *dev, void *data)
25 { .argw = init->argw, 25 { .argw = init->argw,
26 .pid = -1, 26 .pid = -1,
27 .slave = -1, 27 .slave = -1,
28 .ibuf = { '\0' }, 28 .slip = SLIP_PROTO_INIT,
29 .obuf = { '\0' },
30 .pos = 0,
31 .esc = 0,
32 .dev = dev }); 29 .dev = dev });
33 30
34 dev->init = NULL; 31 dev->init = NULL;
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index c322515c71..8d91f663d8 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -12,7 +12,7 @@
12#include "user.h" 12#include "user.h"
13#include "net_user.h" 13#include "net_user.h"
14#include "slirp.h" 14#include "slirp.h"
15#include "slip_proto.h" 15#include "slip_common.h"
16#include "helper.h" 16#include "helper.h"
17#include "os.h" 17#include "os.h"
18 18
@@ -48,47 +48,32 @@ static int slirp_tramp(char **argv, int fd)
48 return(pid); 48 return(pid);
49} 49}
50 50
51/* XXX This is just a trivial wrapper around os_pipe */
52static int slirp_datachan(int *mfd, int *sfd)
53{
54 int fds[2], err;
55
56 err = os_pipe(fds, 1, 1);
57 if(err < 0){
58 printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
59 return(err);
60 }
61
62 *mfd = fds[0];
63 *sfd = fds[1];
64 return(0);
65}
66
67static int slirp_open(void *data) 51static int slirp_open(void *data)
68{ 52{
69 struct slirp_data *pri = data; 53 struct slirp_data *pri = data;
70 int sfd, mfd, pid, err; 54 int fds[2], pid, err;
71 55
72 err = slirp_datachan(&mfd, &sfd); 56 err = os_pipe(fds, 1, 1);
73 if(err) 57 if(err)
74 return(err); 58 return(err);
75 59
76 pid = slirp_tramp(pri->argw.argv, sfd); 60 err = slirp_tramp(pri->argw.argv, fds[1]);
77 61 if(err < 0){
78 if(pid < 0){ 62 printk("slirp_tramp failed - errno = %d\n", -err);
79 printk("slirp_tramp failed - errno = %d\n", -pid); 63 goto out;
80 os_close_file(sfd);
81 os_close_file(mfd);
82 return(pid);
83 } 64 }
84 65 pid = err;
85 pri->slave = sfd; 66
86 pri->pos = 0; 67 pri->slave = fds[1];
87 pri->esc = 0; 68 pri->slip.pos = 0;
88 69 pri->slip.esc = 0;
89 pri->pid = pid; 70 pri->pid = err;
90 71
91 return(mfd); 72 return(fds[0]);
73out:
74 os_close_file(fds[0]);
75 os_close_file(fds[1]);
76 return err;
92} 77}
93 78
94static void slirp_close(int fd, void *data) 79static void slirp_close(int fd, void *data)
@@ -129,48 +114,12 @@ static void slirp_close(int fd, void *data)
129 114
130int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) 115int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri)
131{ 116{
132 int i, n, size, start; 117 return slip_proto_read(fd, buf, len, &pri->slip);
133
134 if(pri->more>0) {
135 i = 0;
136 while(i < pri->more) {
137 size = slip_unesc(pri->ibuf[i++],
138 pri->ibuf,&pri->pos,&pri->esc);
139 if(size){
140 memcpy(buf, pri->ibuf, size);
141 memmove(pri->ibuf, &pri->ibuf[i], pri->more-i);
142 pri->more=pri->more-i;
143 return(size);
144 }
145 }
146 pri->more=0;
147 }
148
149 n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos);
150 if(n <= 0) return(n);
151
152 start = pri->pos;
153 for(i = 0; i < n; i++){
154 size = slip_unesc(pri->ibuf[start + i],
155 pri->ibuf,&pri->pos,&pri->esc);
156 if(size){
157 memcpy(buf, pri->ibuf, size);
158 memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1));
159 pri->more=n-(i+1);
160 return(size);
161 }
162 }
163 return(0);
164} 118}
165 119
166int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) 120int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
167{ 121{
168 int actual, n; 122 return slip_proto_write(fd, buf, len, &pri->slip);
169
170 actual = slip_esc(buf, pri->obuf, len);
171 n = net_write(fd, pri->obuf, actual);
172 if(n < 0) return(n);
173 else return(len);
174} 123}
175 124
176static int slirp_set_mtu(int mtu, void *data) 125static int slirp_set_mtu(int mtu, void *data)
@@ -188,14 +137,3 @@ struct net_user_info slirp_user_info = {
188 .delete_address = NULL, 137 .delete_address = NULL,
189 .max_packet = BUF_SIZE 138 .max_packet = BUF_SIZE
190}; 139};
191
192/*
193 * Overrides for Emacs so that we follow Linus's tabbing style.
194 * Emacs will notice this stuff at the end of the file and automatically
195 * adjust the settings for this buffer only. This must remain at the end
196 * of the file.
197 * ---------------------------------------------------------------------------
198 * Local variables:
199 * c-file-style: "linux"
200 * End:
201 */
diff --git a/arch/um/drivers/stderr_console.c b/arch/um/drivers/stderr_console.c
index 98565b53d1..429ae8e6c7 100644
--- a/arch/um/drivers/stderr_console.c
+++ b/arch/um/drivers/stderr_console.c
@@ -22,9 +22,9 @@ static void stderr_console_write(struct console *console, const char *string,
22} 22}
23 23
24static struct console stderr_console = { 24static struct console stderr_console = {
25 .name "stderr", 25 .name = "stderr",
26 .write stderr_console_write, 26 .write = stderr_console_write,
27 .flags CON_PRINTBUFFER, 27 .flags = CON_PRINTBUFFER,
28}; 28};
29 29
30static int __init stderr_console_init(void) 30static int __init stderr_console_init(void)
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index a4fdf3584a..d269a80f4b 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -69,7 +69,6 @@ int xterm_fd(int socket, int *pid_out)
69 * isn't set) this will hang... */ 69 * isn't set) this will hang... */
70 wait_for_completion(&data->ready); 70 wait_for_completion(&data->ready);
71 71
72 free_irq_by_irq_and_dev(XTERM_IRQ, data);
73 free_irq(XTERM_IRQ, data); 72 free_irq(XTERM_IRQ, data);
74 73
75 ret = data->new_fd; 74 ret = data->new_fd;
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 9fbe3083fd..cfa368e045 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -56,7 +56,7 @@ struct mc_request
56 int as_interrupt; 56 int as_interrupt;
57 57
58 int originating_fd; 58 int originating_fd;
59 int originlen; 59 unsigned int originlen;
60 unsigned char origin[128]; /* sockaddr_un */ 60 unsigned char origin[128]; /* sockaddr_un */
61 61
62 struct mconsole_request request; 62 struct mconsole_request request;
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 36807b796e..89885a77a7 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -35,7 +35,7 @@ extern void *get_output_buffer(int *len_out);
35extern void free_output_buffer(void *buffer); 35extern void free_output_buffer(void *buffer);
36 36
37extern int tap_open_common(void *dev, char *gate_addr); 37extern int tap_open_common(void *dev, char *gate_addr);
38extern void tap_check_ips(char *gate_addr, char *eth_addr); 38extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr);
39 39
40extern void read_output(int fd, char *output_out, int len); 40extern void read_output(int fd, char *output_out, int len);
41 41
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index d246d5a246..881d2988d2 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -136,7 +136,7 @@ extern int os_seek_file(int fd, __u64 offset);
136extern int os_open_file(char *file, struct openflags flags, int mode); 136extern int os_open_file(char *file, struct openflags flags, int mode);
137extern int os_read_file(int fd, void *buf, int len); 137extern int os_read_file(int fd, void *buf, int len);
138extern int os_write_file(int fd, const void *buf, int count); 138extern int os_write_file(int fd, const void *buf, int count);
139extern int os_file_size(char *file, long long *size_out); 139extern int os_file_size(char *file, unsigned long long *size_out);
140extern int os_file_modtime(char *file, unsigned long *modtime); 140extern int os_file_modtime(char *file, unsigned long *modtime);
141extern int os_pipe(int *fd, int stream, int close_on_exec); 141extern int os_pipe(int *fd, int stream, int close_on_exec);
142extern int os_set_fd_async(int fd, int owner); 142extern int os_set_fd_async(int fd, int owner);
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 6eaeb99199..c8ee9559f3 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -8,6 +8,8 @@
8 8
9#include "uml-config.h" 9#include "uml-config.h"
10#include "user_constants.h" 10#include "user_constants.h"
11#include "sysdep/faultinfo.h"
12#include "choose-mode.h"
11 13
12#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) 14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
13#define MAX_REG_OFFSET (UM_FRAME_SIZE) 15#define MAX_REG_OFFSET (UM_FRAME_SIZE)
@@ -58,9 +60,6 @@ extern int sysemu_supported;
58#define PTRACE_SYSEMU_SINGLESTEP 32 60#define PTRACE_SYSEMU_SINGLESTEP 32
59#endif 61#endif
60 62
61#include "sysdep/faultinfo.h"
62#include "choose-mode.h"
63
64union uml_pt_regs { 63union uml_pt_regs {
65#ifdef UML_CONFIG_MODE_TT 64#ifdef UML_CONFIG_MODE_TT
66 struct tt_regs { 65 struct tt_regs {
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index b8c5b8a952..7b6a24dfd3 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -41,9 +41,6 @@ extern unsigned long highmem;
41extern char host_info[]; 41extern char host_info[];
42 42
43extern char saved_command_line[]; 43extern char saved_command_line[];
44extern char command_line[];
45
46extern char *tempdir;
47 44
48extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; 45extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
49extern unsigned long _unprotected_end; 46extern unsigned long _unprotected_end;
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index d44fb52825..9f18061ef4 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -124,14 +124,16 @@ void irq_unlock(unsigned long flags)
124 spin_unlock_irqrestore(&irq_spinlock, flags); 124 spin_unlock_irqrestore(&irq_spinlock, flags);
125} 125}
126 126
127/* presently hw_interrupt_type must define (startup || enable) && 127/* hw_interrupt_type must define (startup || enable) &&
128 * disable && end */ 128 * (shutdown || disable) && end */
129static void dummy(unsigned int irq) 129static void dummy(unsigned int irq)
130{ 130{
131} 131}
132 132
133static struct hw_interrupt_type SIGIO_irq_type = { 133/* This is used for everything else than the timer. */
134static struct hw_interrupt_type normal_irq_type = {
134 .typename = "SIGIO", 135 .typename = "SIGIO",
136 .release = free_irq_by_irq_and_dev,
135 .disable = dummy, 137 .disable = dummy,
136 .enable = dummy, 138 .enable = dummy,
137 .ack = dummy, 139 .ack = dummy,
@@ -140,6 +142,7 @@ static struct hw_interrupt_type SIGIO_irq_type = {
140 142
141static struct hw_interrupt_type SIGVTALRM_irq_type = { 143static struct hw_interrupt_type SIGVTALRM_irq_type = {
142 .typename = "SIGVTALRM", 144 .typename = "SIGVTALRM",
145 .release = free_irq_by_irq_and_dev,
143 .shutdown = dummy, /* never called */ 146 .shutdown = dummy, /* never called */
144 .disable = dummy, 147 .disable = dummy,
145 .enable = dummy, 148 .enable = dummy,
@@ -160,7 +163,7 @@ void __init init_IRQ(void)
160 irq_desc[i].status = IRQ_DISABLED; 163 irq_desc[i].status = IRQ_DISABLED;
161 irq_desc[i].action = NULL; 164 irq_desc[i].action = NULL;
162 irq_desc[i].depth = 1; 165 irq_desc[i].depth = 1;
163 irq_desc[i].handler = &SIGIO_irq_type; 166 irq_desc[i].handler = &normal_irq_type;
164 enable_irq(i); 167 enable_irq(i);
165 } 168 }
166} 169}
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
index b3074cbaa4..c3ccaf24f3 100644
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -85,8 +85,6 @@ void sigio_handler(int sig, union uml_pt_regs *regs)
85 next = irq_fd->next; 85 next = irq_fd->next;
86 if(irq_fd->freed){ 86 if(irq_fd->freed){
87 free_irq(irq_fd->irq, irq_fd->id); 87 free_irq(irq_fd->irq, irq_fd->id);
88 free_irq_by_irq_and_dev(irq_fd->irq,
89 irq_fd->id);
90 } 88 }
91 } 89 }
92 } 90 }
diff --git a/arch/um/kernel/main.c b/arch/um/kernel/main.c
index e42e6364ca..e59f581526 100644
--- a/arch/um/kernel/main.c
+++ b/arch/um/kernel/main.c
@@ -24,8 +24,6 @@
24#include "mode.h" 24#include "mode.h"
25#include "choose-mode.h" 25#include "choose-mode.h"
26#include "uml-config.h" 26#include "uml-config.h"
27#include "irq_user.h"
28#include "time_user.h"
29#include "os.h" 27#include "os.h"
30 28
31/* Set in set_stklim, which is called from main and __wrap_malloc. 29/* Set in set_stklim, which is called from main and __wrap_malloc.
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index c22825f13e..5597bd39e6 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -53,7 +53,6 @@ static void setup_highmem(unsigned long highmem_start,
53 for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){ 53 for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
54 page = &mem_map[highmem_pfn + i]; 54 page = &mem_map[highmem_pfn + i];
55 ClearPageReserved(page); 55 ClearPageReserved(page);
56 set_bit(PG_highmem, &page->flags);
57 set_page_count(page, 1); 56 set_page_count(page, 1);
58 __free_page(page); 57 __free_page(page);
59 } 58 }
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 51f8e5a8ac..1b5ef3e96c 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -30,7 +30,6 @@
30#include "init.h" 30#include "init.h"
31#include "os.h" 31#include "os.h"
32#include "uml-config.h" 32#include "uml-config.h"
33#include "ptrace_user.h"
34#include "choose-mode.h" 33#include "choose-mode.h"
35#include "mode.h" 34#include "mode.h"
36#ifdef UML_CONFIG_MODE_SKAS 35#ifdef UML_CONFIG_MODE_SKAS
@@ -131,7 +130,7 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
131 return(arg.pid); 130 return(arg.pid);
132} 131}
133 132
134static int ptrace_child(void *arg) 133static int ptrace_child(void)
135{ 134{
136 int ret; 135 int ret;
137 int pid = os_getpid(), ppid = getppid(); 136 int pid = os_getpid(), ppid = getppid();
@@ -160,20 +159,16 @@ static int ptrace_child(void *arg)
160 _exit(ret); 159 _exit(ret);
161} 160}
162 161
163static int start_ptraced_child(void **stack_out) 162static int start_ptraced_child(void)
164{ 163{
165 void *stack;
166 unsigned long sp;
167 int pid, n, status; 164 int pid, n, status;
168 165
169 stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, 166 pid = fork();
170 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 167 if(pid == 0)
171 if(stack == MAP_FAILED) 168 ptrace_child();
172 panic("check_ptrace : mmap failed, errno = %d", errno); 169
173 sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
174 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
175 if(pid < 0) 170 if(pid < 0)
176 panic("check_ptrace : clone failed, errno = %d", errno); 171 panic("check_ptrace : fork failed, errno = %d", errno);
177 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 172 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
178 if(n < 0) 173 if(n < 0)
179 panic("check_ptrace : wait failed, errno = %d", errno); 174 panic("check_ptrace : wait failed, errno = %d", errno);
@@ -181,7 +176,6 @@ static int start_ptraced_child(void **stack_out)
181 panic("check_ptrace : expected SIGSTOP, got status = %d", 176 panic("check_ptrace : expected SIGSTOP, got status = %d",
182 status); 177 status);
183 178
184 *stack_out = stack;
185 return(pid); 179 return(pid);
186} 180}
187 181
@@ -189,12 +183,12 @@ static int start_ptraced_child(void **stack_out)
189 * just avoid using sysemu, not panic, but only if SYSEMU features are broken. 183 * just avoid using sysemu, not panic, but only if SYSEMU features are broken.
190 * So only for SYSEMU features we test mustpanic, while normal host features 184 * So only for SYSEMU features we test mustpanic, while normal host features
191 * must work anyway!*/ 185 * must work anyway!*/
192static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic) 186static int stop_ptraced_child(int pid, int exitcode, int mustexit)
193{ 187{
194 int status, n, ret = 0; 188 int status, n, ret = 0;
195 189
196 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 190 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
197 panic("check_ptrace : ptrace failed, errno = %d", errno); 191 panic("stop_ptraced_child : ptrace failed, errno = %d", errno);
198 CATCH_EINTR(n = waitpid(pid, &status, 0)); 192 CATCH_EINTR(n = waitpid(pid, &status, 0));
199 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 193 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
200 int exit_with = WEXITSTATUS(status); 194 int exit_with = WEXITSTATUS(status);
@@ -205,15 +199,13 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode, int mustpanic)
205 printk("check_ptrace : child exited with exitcode %d, while " 199 printk("check_ptrace : child exited with exitcode %d, while "
206 "expecting %d; status 0x%x", exit_with, 200 "expecting %d; status 0x%x", exit_with,
207 exitcode, status); 201 exitcode, status);
208 if (mustpanic) 202 if (mustexit)
209 panic("\n"); 203 panic("\n");
210 else 204 else
211 printk("\n"); 205 printk("\n");
212 ret = -1; 206 ret = -1;
213 } 207 }
214 208
215 if(munmap(stack, PAGE_SIZE) < 0)
216 panic("check_ptrace : munmap failed, errno = %d", errno);
217 return ret; 209 return ret;
218} 210}
219 211
@@ -235,12 +227,11 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
235 227
236static void __init check_sysemu(void) 228static void __init check_sysemu(void)
237{ 229{
238 void *stack;
239 int pid, syscall, n, status, count=0; 230 int pid, syscall, n, status, count=0;
240 231
241 printk("Checking syscall emulation patch for ptrace..."); 232 printk("Checking syscall emulation patch for ptrace...");
242 sysemu_supported = 0; 233 sysemu_supported = 0;
243 pid = start_ptraced_child(&stack); 234 pid = start_ptraced_child();
244 235
245 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) 236 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
246 goto fail; 237 goto fail;
@@ -258,7 +249,7 @@ static void __init check_sysemu(void)
258 panic("check_sysemu : failed to modify system " 249 panic("check_sysemu : failed to modify system "
259 "call return, errno = %d", errno); 250 "call return, errno = %d", errno);
260 251
261 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 252 if (stop_ptraced_child(pid, 0, 0) < 0)
262 goto fail_stopped; 253 goto fail_stopped;
263 254
264 sysemu_supported = 1; 255 sysemu_supported = 1;
@@ -266,7 +257,7 @@ static void __init check_sysemu(void)
266 set_using_sysemu(!force_sysemu_disabled); 257 set_using_sysemu(!force_sysemu_disabled);
267 258
268 printk("Checking advanced syscall emulation patch for ptrace..."); 259 printk("Checking advanced syscall emulation patch for ptrace...");
269 pid = start_ptraced_child(&stack); 260 pid = start_ptraced_child();
270 while(1){ 261 while(1){
271 count++; 262 count++;
272 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) 263 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
@@ -291,7 +282,7 @@ static void __init check_sysemu(void)
291 break; 282 break;
292 } 283 }
293 } 284 }
294 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 285 if (stop_ptraced_child(pid, 0, 0) < 0)
295 goto fail_stopped; 286 goto fail_stopped;
296 287
297 sysemu_supported = 2; 288 sysemu_supported = 2;
@@ -302,18 +293,17 @@ static void __init check_sysemu(void)
302 return; 293 return;
303 294
304fail: 295fail:
305 stop_ptraced_child(pid, stack, 1, 0); 296 stop_ptraced_child(pid, 1, 0);
306fail_stopped: 297fail_stopped:
307 printk("missing\n"); 298 printk("missing\n");
308} 299}
309 300
310void __init check_ptrace(void) 301void __init check_ptrace(void)
311{ 302{
312 void *stack;
313 int pid, syscall, n, status; 303 int pid, syscall, n, status;
314 304
315 printk("Checking that ptrace can change system call numbers..."); 305 printk("Checking that ptrace can change system call numbers...");
316 pid = start_ptraced_child(&stack); 306 pid = start_ptraced_child();
317 307
318 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) 308 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
319 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno); 309 panic("check_ptrace: PTRACE_SETOPTIONS failed, errno = %d", errno);
@@ -340,7 +330,7 @@ void __init check_ptrace(void)
340 break; 330 break;
341 } 331 }
342 } 332 }
343 stop_ptraced_child(pid, stack, 0, 1); 333 stop_ptraced_child(pid, 0, 1);
344 printk("OK\n"); 334 printk("OK\n");
345 check_sysemu(); 335 check_sysemu();
346} 336}
@@ -372,11 +362,10 @@ void forward_pending_sigio(int target)
372static inline int check_skas3_ptrace_support(void) 362static inline int check_skas3_ptrace_support(void)
373{ 363{
374 struct ptrace_faultinfo fi; 364 struct ptrace_faultinfo fi;
375 void *stack;
376 int pid, n, ret = 1; 365 int pid, n, ret = 1;
377 366
378 printf("Checking for the skas3 patch in the host..."); 367 printf("Checking for the skas3 patch in the host...");
379 pid = start_ptraced_child(&stack); 368 pid = start_ptraced_child();
380 369
381 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 370 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
382 if (n < 0) { 371 if (n < 0) {
@@ -391,7 +380,7 @@ static inline int check_skas3_ptrace_support(void)
391 } 380 }
392 381
393 init_registers(pid); 382 init_registers(pid);
394 stop_ptraced_child(pid, stack, 1, 1); 383 stop_ptraced_child(pid, 1, 1);
395 384
396 return(ret); 385 return(ret);
397} 386}
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index ab5d3271da..fc71ef2957 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -68,8 +68,11 @@ void new_thread_handler(int sig)
68 * 0 if it just exits 68 * 0 if it just exits
69 */ 69 */
70 n = run_kernel_thread(fn, arg, &current->thread.exec_buf); 70 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
71 if(n == 1) 71 if(n == 1){
72 /* Handle any immediate reschedules or signals */
73 interrupt_end();
72 userspace(&current->thread.regs.regs); 74 userspace(&current->thread.regs.regs);
75 }
73 else do_exit(0); 76 else do_exit(0);
74} 77}
75 78
@@ -96,6 +99,8 @@ void fork_handler(int sig)
96 schedule_tail(current->thread.prev_sched); 99 schedule_tail(current->thread.prev_sched);
97 current->thread.prev_sched = NULL; 100 current->thread.prev_sched = NULL;
98 101
102 /* Handle any immediate reschedules or signals */
103 interrupt_end();
99 userspace(&current->thread.regs.regs); 104 userspace(&current->thread.regs.regs);
100} 105}
101 106
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
index c3faea21a9..3fd2554e60 100644
--- a/arch/um/kernel/tt/Makefile
+++ b/arch/um/kernel/tt/Makefile
@@ -3,10 +3,6 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6extra-y := unmap_fin.o
7targets := unmap.o
8clean-files := unmap_tmp.o
9
10obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ 6obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
11 syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ 7 syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
12 uaccess.o uaccess_user.o 8 uaccess.o uaccess_user.o
@@ -16,14 +12,3 @@ obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
16USER_OBJS := gdb.o time.o tracer.o 12USER_OBJS := gdb.o time.o tracer.o
17 13
18include arch/um/scripts/Makefile.rules 14include arch/um/scripts/Makefile.rules
19
20UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS))
21UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS))
22
23#XXX: partially copied from arch/um/scripts/Makefile.rules
24$(obj)/unmap.o: c_flags = -Wp,-MD,$(depfile) $(UNMAP_CFLAGS)
25
26$(obj)/unmap_fin.o : $(obj)/unmap.o
27 $(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a)
28 $(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo
29
diff --git a/arch/um/kernel/tt/unmap.c b/arch/um/kernel/tt/unmap.c
deleted file mode 100644
index 3f7aecdbe5..0000000000
--- a/arch/um/kernel/tt/unmap.c
+++ /dev/null
@@ -1,31 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <sys/mman.h>
7
8int switcheroo(int fd, int prot, void *from, void *to, int size)
9{
10 if(munmap(to, size) < 0){
11 return(-1);
12 }
13 if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
14 return(-1);
15 }
16 if(munmap(from, size) < 0){
17 return(-1);
18 }
19 return(0);
20}
21
22/*
23 * Overrides for Emacs so that we follow Linus's tabbing style.
24 * Emacs will notice this stuff at the end of the file and automatically
25 * adjust the settings for this buffer only. This must remain at the end
26 * of the file.
27 * ---------------------------------------------------------------------------
28 * Local variables:
29 * c-file-style: "linux"
30 * End:
31 */
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 418427107b..8736d098f0 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -26,7 +26,6 @@
26#include "asm/setup.h" 26#include "asm/setup.h"
27#include "ubd_user.h" 27#include "ubd_user.h"
28#include "asm/current.h" 28#include "asm/current.h"
29#include "asm/setup.h"
30#include "user_util.h" 29#include "user_util.h"
31#include "kern_util.h" 30#include "kern_util.h"
32#include "kern.h" 31#include "kern.h"
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index dd5355500b..61dfd4fef7 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -14,19 +14,10 @@ SECTIONS
14 /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start 14 /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
15 * is remapped.*/ 15 * is remapped.*/
16 __binary_start = .; 16 __binary_start = .;
17#ifdef MODE_TT
18 .thread_private : {
19 __start_thread_private = .;
20 errno = .;
21 . += 4;
22 arch/um/kernel/tt/unmap_fin.o (.data)
23 __end_thread_private = .;
24 }
25 . = ALIGN(4096);
26 .remap : { arch/um/kernel/tt/unmap_fin.o (.text) }
27 17
28 /* We want it only if we are in MODE_TT. In both cases, however, when MODE_TT 18#ifdef MODE_TT
29 * is off the resulting binary segfaults.*/ 19 .remap_data : { arch/um/sys-SUBARCH/unmap_fin.o (.data .bss) }
20 .remap : { arch/um/sys-SUBARCH/unmap_fin.o (.text) }
30 21
31 . = ALIGN(4096); /* Init code and data */ 22 . = ALIGN(4096); /* Init code and data */
32#endif 23#endif
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 9aee0b62eb..f0d6060e3e 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -45,7 +45,11 @@ __init void scan_elf_aux( char **envp)
45 elf_aux_hwcap = auxv->a_un.a_val; 45 elf_aux_hwcap = auxv->a_un.a_val;
46 break; 46 break;
47 case AT_PLATFORM: 47 case AT_PLATFORM:
48 elf_aux_platform = auxv->a_un.a_ptr; 48 /* elf.h removed the pointer elements from
49 * a_un, so we have to use a_val, which is
50 * all that's left.
51 */
52 elf_aux_platform = (char *) auxv->a_un.a_val;
49 break; 53 break;
50 case AT_PAGESZ: 54 case AT_PAGESZ:
51 page_size = auxv->a_un.a_val; 55 page_size = auxv->a_un.a_val;
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 77d4066d1a..fd45bb2609 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -363,7 +363,7 @@ int os_write_file(int fd, const void *buf, int len)
363 (int (*)(int, void *, int)) write, copy_to_user_proc)); 363 (int (*)(int, void *, int)) write, copy_to_user_proc));
364} 364}
365 365
366int os_file_size(char *file, long long *size_out) 366int os_file_size(char *file, unsigned long long *size_out)
367{ 367{
368 struct uml_stat buf; 368 struct uml_stat buf;
369 int err; 369 int err;
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index 0b2491883d..7459d09c23 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -10,11 +10,17 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
10$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \ 10$(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \
11 $(CFLAGS_$(notdir $@)) 11 $(CFLAGS_$(notdir $@))
12 12
13# The stubs and unmap.o can't try to call mcount or update basic block data
14define unprofile
15 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
16endef
17
18
13quiet_cmd_make_link = SYMLINK $@ 19quiet_cmd_make_link = SYMLINK $@
14cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ 20cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@
15 21
16# this needs to be before the foreach, because targets does not accept 22# this needs to be before the foreach, because targets does not accept
17# complete paths like $(obj)/$(f). To make sure this works, use a := assignment, 23# complete paths like $(obj)/$(f). To make sure this works, use a := assignment
18# or we will get $(obj)/$(f) in the "targets" value. 24# or we will get $(obj)/$(f) in the "targets" value.
19# Also, this forces you to use the := syntax when assigning to targets. 25# Also, this forces you to use the := syntax when assigning to targets.
20# Otherwise the line below will cause an infinite loop (if you don't know why, 26# Otherwise the line below will cause an infinite loop (if you don't know why,
diff --git a/arch/um/scripts/Makefile.unmap b/arch/um/scripts/Makefile.unmap
new file mode 100644
index 0000000000..37a8f97652
--- /dev/null
+++ b/arch/um/scripts/Makefile.unmap
@@ -0,0 +1,22 @@
1clean-files += unmap_tmp.o unmap_fin.o unmap.o
2
3ifdef CONFIG_MODE_TT
4
5#Always build unmap_fin.o
6extra-y += unmap_fin.o
7#Do dependency tracking for unmap.o (it will be always built, but won't get the tracking unless we use this).
8targets += unmap.o
9
10#XXX: partially copied from arch/um/scripts/Makefile.rules
11$(obj)/unmap.o: _c_flags = $(call unprofile,$(CFLAGS))
12
13quiet_cmd_wrapld = LD $@
14define cmd_wrapld
15 $(LD) -r -o $(obj)/unmap_tmp.o $< $(shell $(CC) -print-file-name=libc.a); \
16 $(OBJCOPY) $(obj)/unmap_tmp.o $@ -G switcheroo
17endef
18
19$(obj)/unmap_fin.o : $(obj)/unmap.o FORCE
20 $(call if_changed,wrapld)
21
22endif
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 4351e56055..095bcdb0b9 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -17,3 +17,5 @@ highmem.c-dir = mm
17module.c-dir = kernel 17module.c-dir = kernel
18 18
19subdir- := util 19subdir- := util
20
21include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
new file mode 100644
index 0000000000..136875263d
--- /dev/null
+++ b/arch/um/sys-i386/unmap.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/mman.h>
7#include <asm/unistd.h>
8
9static int errno;
10
11static inline _syscall2(int,munmap,void *,start,size_t,len)
12static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
13int switcheroo(int fd, int prot, void *from, void *to, int size)
14{
15 if(munmap(to, size) < 0){
16 return(-1);
17 }
18 if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
19 return(-1);
20 }
21 if(munmap(from, size) < 0){
22 return(-1);
23 }
24 return(0);
25}
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 608466ad6b..2bc6f68490 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -29,3 +29,5 @@ thunk.S-dir = lib
29module.c-dir = kernel 29module.c-dir = kernel
30 30
31subdir- := util 31subdir- := util
32
33include arch/um/scripts/Makefile.unmap
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
new file mode 100644
index 0000000000..bc7094cce4
--- /dev/null
+++ b/arch/um/sys-x86_64/unmap.c
@@ -0,0 +1,25 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/mman.h>
7#include <asm/unistd.h>
8
9static int errno;
10
11static inline _syscall2(int,munmap,void *,start,size_t,len)
12static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
13int switcheroo(int fd, int prot, void *from, void *to, int size)
14{
15 if(munmap(to, size) < 0){
16 return(-1);
17 }
18 if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){
19 return(-1);
20 }
21 if(munmap(from, size) < 0){
22 return(-1);
23 }
24 return(0);
25}