diff options
author | Paul Mackerras <paulus@samba.org> | 2006-07-31 20:37:25 -0400 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-07-31 20:37:25 -0400 |
commit | 57cad8084e0837e0f2c97da789ec9b3f36809be9 (patch) | |
tree | e9c790afb4286f78cb08d9664f58baa7e876fe55 /arch/um | |
parent | cb18bd40030c879cd93fef02fd579f74dbab473d (diff) | |
parent | 49b1e3ea19b1c95c2f012b8331ffb3b169e4c042 (diff) |
Merge branch 'merge'
Diffstat (limited to 'arch/um')
45 files changed, 487 insertions, 713 deletions
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug index bab51d619173..09c1aca6339f 100644 --- a/arch/um/Kconfig.debug +++ b/arch/um/Kconfig.debug | |||
@@ -47,13 +47,4 @@ config GCOV | |||
47 | If you're involved in UML kernel development and want to use gcov, | 47 | If you're involved in UML kernel development and want to use gcov, |
48 | say Y. If you're unsure, say N. | 48 | say Y. If you're unsure, say N. |
49 | 49 | ||
50 | config SYSCALL_DEBUG | ||
51 | bool "Enable system call debugging" | ||
52 | depends on DEBUG_INFO | ||
53 | help | ||
54 | This adds some system debugging to UML, including keeping a ring buffer | ||
55 | with recent system calls and some global and per-task statistics. | ||
56 | |||
57 | If unsure, say N | ||
58 | |||
59 | endmenu | 50 | endmenu |
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index dffd1184c956..9558a7cf34d5 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 | |||
@@ -11,6 +11,7 @@ USER_CFLAGS += -fno-builtin -m64 | |||
11 | CHECKFLAGS += -m64 | 11 | CHECKFLAGS += -m64 |
12 | AFLAGS += -m64 | 12 | AFLAGS += -m64 |
13 | LDFLAGS += -m elf_x86_64 | 13 | LDFLAGS += -m elf_x86_64 |
14 | CPPFLAGS += -m64 | ||
14 | 15 | ||
15 | ELF_ARCH := i386:x86-64 | 16 | ELF_ARCH := i386:x86-64 |
16 | ELF_FORMAT := elf64-x86-64 | 17 | ELF_FORMAT := elf64-x86-64 |
diff --git a/arch/um/defconfig b/arch/um/defconfig index 402a74dc5026..780cc0a4a128 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig | |||
@@ -526,4 +526,3 @@ CONFIG_FORCED_INLINING=y | |||
526 | # CONFIG_RCU_TORTURE_TEST is not set | 526 | # CONFIG_RCU_TORTURE_TEST is not set |
527 | # CONFIG_GPROF is not set | 527 | # CONFIG_GPROF is not set |
528 | # CONFIG_GCOV is not set | 528 | # CONFIG_GCOV is not set |
529 | # CONFIG_SYSCALL_DEBUG is not set | ||
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c index 4b109fe7fff8..9bfd405c3bd8 100644 --- a/arch/um/drivers/mconsole_user.c +++ b/arch/um/drivers/mconsole_user.c | |||
@@ -18,7 +18,12 @@ | |||
18 | #include "umid.h" | 18 | #include "umid.h" |
19 | 19 | ||
20 | static struct mconsole_command commands[] = { | 20 | static struct mconsole_command commands[] = { |
21 | { "version", mconsole_version, MCONSOLE_INTR }, | 21 | /* With uts namespaces, uts information becomes process-specific, so |
22 | * we need a process context. If we try handling this in interrupt | ||
23 | * context, we may hit an exiting process without a valid uts | ||
24 | * namespace. | ||
25 | */ | ||
26 | { "version", mconsole_version, MCONSOLE_PROC }, | ||
22 | { "halt", mconsole_halt, MCONSOLE_PROC }, | 27 | { "halt", mconsole_halt, MCONSOLE_PROC }, |
23 | { "reboot", mconsole_reboot, MCONSOLE_PROC }, | 28 | { "reboot", mconsole_reboot, MCONSOLE_PROC }, |
24 | { "config", mconsole_config, MCONSOLE_PROC }, | 29 | { "config", mconsole_config, MCONSOLE_PROC }, |
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c index 0a7786e00cfb..107c5e43fa00 100644 --- a/arch/um/drivers/net_user.c +++ b/arch/um/drivers/net_user.c | |||
@@ -22,13 +22,14 @@ int tap_open_common(void *dev, char *gate_addr) | |||
22 | { | 22 | { |
23 | int tap_addr[4]; | 23 | int tap_addr[4]; |
24 | 24 | ||
25 | if(gate_addr == NULL) return(0); | 25 | if(gate_addr == NULL) |
26 | return 0; | ||
26 | if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], | 27 | if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], |
27 | &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){ | 28 | &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){ |
28 | printk("Invalid tap IP address - '%s'\n", gate_addr); | 29 | printk("Invalid tap IP address - '%s'\n", gate_addr); |
29 | return(-EINVAL); | 30 | return -EINVAL; |
30 | } | 31 | } |
31 | return(0); | 32 | return 0; |
32 | } | 33 | } |
33 | 34 | ||
34 | void tap_check_ips(char *gate_addr, unsigned char *eth_addr) | 35 | void tap_check_ips(char *gate_addr, unsigned char *eth_addr) |
@@ -94,25 +95,25 @@ int net_read(int fd, void *buf, int len) | |||
94 | n = os_read_file(fd, buf, len); | 95 | n = os_read_file(fd, buf, len); |
95 | 96 | ||
96 | if(n == -EAGAIN) | 97 | if(n == -EAGAIN) |
97 | return(0); | 98 | return 0; |
98 | else if(n == 0) | 99 | else if(n == 0) |
99 | return(-ENOTCONN); | 100 | return -ENOTCONN; |
100 | return(n); | 101 | return n; |
101 | } | 102 | } |
102 | 103 | ||
103 | int net_recvfrom(int fd, void *buf, int len) | 104 | int net_recvfrom(int fd, void *buf, int len) |
104 | { | 105 | { |
105 | int n; | 106 | int n; |
106 | 107 | ||
107 | while(((n = recvfrom(fd, buf, len, 0, NULL, NULL)) < 0) && | 108 | CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL)); |
108 | (errno == EINTR)) ; | ||
109 | |||
110 | if(n < 0){ | 109 | if(n < 0){ |
111 | if(errno == EAGAIN) return(0); | 110 | if(errno == EAGAIN) |
112 | return(-errno); | 111 | return 0; |
112 | return -errno; | ||
113 | } | 113 | } |
114 | else if(n == 0) return(-ENOTCONN); | 114 | else if(n == 0) |
115 | return(n); | 115 | return -ENOTCONN; |
116 | return n; | ||
116 | } | 117 | } |
117 | 118 | ||
118 | int net_write(int fd, void *buf, int len) | 119 | int net_write(int fd, void *buf, int len) |
@@ -122,37 +123,41 @@ int net_write(int fd, void *buf, int len) | |||
122 | n = os_write_file(fd, buf, len); | 123 | n = os_write_file(fd, buf, len); |
123 | 124 | ||
124 | if(n == -EAGAIN) | 125 | if(n == -EAGAIN) |
125 | return(0); | 126 | return 0; |
126 | else if(n == 0) | 127 | else if(n == 0) |
127 | return(-ENOTCONN); | 128 | return -ENOTCONN; |
128 | return(n); | 129 | return n; |
129 | } | 130 | } |
130 | 131 | ||
131 | int net_send(int fd, void *buf, int len) | 132 | int net_send(int fd, void *buf, int len) |
132 | { | 133 | { |
133 | int n; | 134 | int n; |
134 | 135 | ||
135 | while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ; | 136 | CATCH_EINTR(n = send(fd, buf, len, 0)); |
136 | if(n < 0){ | 137 | if(n < 0){ |
137 | if(errno == EAGAIN) return(0); | 138 | if(errno == EAGAIN) |
138 | return(-errno); | 139 | return 0; |
140 | return -errno; | ||
139 | } | 141 | } |
140 | else if(n == 0) return(-ENOTCONN); | 142 | else if(n == 0) |
141 | return(n); | 143 | return -ENOTCONN; |
144 | return n; | ||
142 | } | 145 | } |
143 | 146 | ||
144 | int net_sendto(int fd, void *buf, int len, void *to, int sock_len) | 147 | int net_sendto(int fd, void *buf, int len, void *to, int sock_len) |
145 | { | 148 | { |
146 | int n; | 149 | int n; |
147 | 150 | ||
148 | while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to, | 151 | CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to, |
149 | sock_len)) < 0) && (errno == EINTR)) ; | 152 | sock_len)); |
150 | if(n < 0){ | 153 | if(n < 0){ |
151 | if(errno == EAGAIN) return(0); | 154 | if(errno == EAGAIN) |
152 | return(-errno); | 155 | return 0; |
156 | return -errno; | ||
153 | } | 157 | } |
154 | else if(n == 0) return(-ENOTCONN); | 158 | else if(n == 0) |
155 | return(n); | 159 | return -ENOTCONN; |
160 | return n; | ||
156 | } | 161 | } |
157 | 162 | ||
158 | struct change_pre_exec_data { | 163 | struct change_pre_exec_data { |
@@ -176,7 +181,7 @@ static int change_tramp(char **argv, char *output, int output_len) | |||
176 | err = os_pipe(fds, 1, 0); | 181 | err = os_pipe(fds, 1, 0); |
177 | if(err < 0){ | 182 | if(err < 0){ |
178 | printk("change_tramp - pipe failed, err = %d\n", -err); | 183 | printk("change_tramp - pipe failed, err = %d\n", -err); |
179 | return(err); | 184 | return err; |
180 | } | 185 | } |
181 | pe_data.close_me = fds[0]; | 186 | pe_data.close_me = fds[0]; |
182 | pe_data.stdout = fds[1]; | 187 | pe_data.stdout = fds[1]; |
@@ -190,7 +195,7 @@ static int change_tramp(char **argv, char *output, int output_len) | |||
190 | 195 | ||
191 | if (pid > 0) | 196 | if (pid > 0) |
192 | CATCH_EINTR(err = waitpid(pid, NULL, 0)); | 197 | CATCH_EINTR(err = waitpid(pid, NULL, 0)); |
193 | return(pid); | 198 | return pid; |
194 | } | 199 | } |
195 | 200 | ||
196 | static void change(char *dev, char *what, unsigned char *addr, | 201 | static void change(char *dev, char *what, unsigned char *addr, |
@@ -241,26 +246,15 @@ char *split_if_spec(char *str, ...) | |||
241 | va_start(ap, str); | 246 | va_start(ap, str); |
242 | while((arg = va_arg(ap, char **)) != NULL){ | 247 | while((arg = va_arg(ap, char **)) != NULL){ |
243 | if(*str == '\0') | 248 | if(*str == '\0') |
244 | return(NULL); | 249 | return NULL; |
245 | end = strchr(str, ','); | 250 | end = strchr(str, ','); |
246 | if(end != str) | 251 | if(end != str) |
247 | *arg = str; | 252 | *arg = str; |
248 | if(end == NULL) | 253 | if(end == NULL) |
249 | return(NULL); | 254 | return NULL; |
250 | *end++ = '\0'; | 255 | *end++ = '\0'; |
251 | str = end; | 256 | str = end; |
252 | } | 257 | } |
253 | va_end(ap); | 258 | va_end(ap); |
254 | return(str); | 259 | return str; |
255 | } | 260 | } |
256 | |||
257 | /* | ||
258 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
259 | * Emacs will notice this stuff at the end of the file and automatically | ||
260 | * adjust the settings for this buffer only. This must remain at the end | ||
261 | * of the file. | ||
262 | * --------------------------------------------------------------------------- | ||
263 | * Local variables: | ||
264 | * c-file-style: "linux" | ||
265 | * End: | ||
266 | */ | ||
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c index 94c9265a4f2c..9f70edf5d8ef 100644 --- a/arch/um/drivers/tty.c +++ b/arch/um/drivers/tty.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
@@ -25,17 +25,17 @@ static void *tty_chan_init(char *str, int device, struct chan_opts *opts) | |||
25 | if(*str != ':'){ | 25 | if(*str != ':'){ |
26 | printk("tty_init : channel type 'tty' must specify " | 26 | printk("tty_init : channel type 'tty' must specify " |
27 | "a device\n"); | 27 | "a device\n"); |
28 | return(NULL); | 28 | return NULL; |
29 | } | 29 | } |
30 | str++; | 30 | str++; |
31 | 31 | ||
32 | data = um_kmalloc(sizeof(*data)); | 32 | data = um_kmalloc(sizeof(*data)); |
33 | if(data == NULL) | 33 | if(data == NULL) |
34 | return(NULL); | 34 | return NULL; |
35 | *data = ((struct tty_chan) { .dev = str, | 35 | *data = ((struct tty_chan) { .dev = str, |
36 | .raw = opts->raw }); | 36 | .raw = opts->raw }); |
37 | 37 | ||
38 | return(data); | 38 | return data; |
39 | } | 39 | } |
40 | 40 | ||
41 | static int tty_open(int input, int output, int primary, void *d, | 41 | static int tty_open(int input, int output, int primary, void *d, |
@@ -45,19 +45,21 @@ static int tty_open(int input, int output, int primary, void *d, | |||
45 | int fd, err; | 45 | int fd, err; |
46 | 46 | ||
47 | fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); | 47 | fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); |
48 | if(fd < 0) return(fd); | 48 | if(fd < 0) |
49 | return fd; | ||
50 | |||
49 | if(data->raw){ | 51 | if(data->raw){ |
50 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); | 52 | CATCH_EINTR(err = tcgetattr(fd, &data->tt)); |
51 | if(err) | 53 | if(err) |
52 | return(err); | 54 | return err; |
53 | 55 | ||
54 | err = raw(fd); | 56 | err = raw(fd); |
55 | if(err) | 57 | if(err) |
56 | return(err); | 58 | return err; |
57 | } | 59 | } |
58 | 60 | ||
59 | *dev_out = data->dev; | 61 | *dev_out = data->dev; |
60 | return(fd); | 62 | return fd; |
61 | } | 63 | } |
62 | 64 | ||
63 | struct chan_ops tty_ops = { | 65 | struct chan_ops tty_ops = { |
@@ -72,14 +74,3 @@ struct chan_ops tty_ops = { | |||
72 | .free = generic_free, | 74 | .free = generic_free, |
73 | .winch = 0, | 75 | .winch = 0, |
74 | }; | 76 | }; |
75 | |||
76 | /* | ||
77 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
78 | * Emacs will notice this stuff at the end of the file and automatically | ||
79 | * adjust the settings for this buffer only. This must remain at the end | ||
80 | * of the file. | ||
81 | * --------------------------------------------------------------------------- | ||
82 | * Local variables: | ||
83 | * c-file-style: "linux" | ||
84 | * End: | ||
85 | */ | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 602d7286b9e0..34085315aa57 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -627,7 +627,6 @@ static int ubd_new_disk(int major, u64 size, int unit, | |||
627 | 627 | ||
628 | { | 628 | { |
629 | struct gendisk *disk; | 629 | struct gendisk *disk; |
630 | int err; | ||
631 | 630 | ||
632 | disk = alloc_disk(1 << UBD_SHIFT); | 631 | disk = alloc_disk(1 << UBD_SHIFT); |
633 | if(disk == NULL) | 632 | if(disk == NULL) |
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h index 69a93c804f0e..15d311b9be9e 100644 --- a/arch/um/include/irq_user.h +++ b/arch/um/include/irq_user.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #ifndef __IRQ_USER_H__ | 6 | #ifndef __IRQ_USER_H__ |
7 | #define __IRQ_USER_H__ | 7 | #define __IRQ_USER_H__ |
8 | 8 | ||
9 | #include "uml-config.h" | ||
10 | |||
9 | struct irq_fd { | 11 | struct irq_fd { |
10 | struct irq_fd *next; | 12 | struct irq_fd *next; |
11 | void *id; | 13 | void *id; |
@@ -26,9 +28,10 @@ extern void free_irq_by_fd(int fd); | |||
26 | extern void reactivate_fd(int fd, int irqnum); | 28 | extern void reactivate_fd(int fd, int irqnum); |
27 | extern void deactivate_fd(int fd, int irqnum); | 29 | extern void deactivate_fd(int fd, int irqnum); |
28 | extern int deactivate_all_fds(void); | 30 | extern int deactivate_all_fds(void); |
29 | extern void forward_interrupts(int pid); | ||
30 | extern int activate_ipi(int fd, int pid); | 31 | extern int activate_ipi(int fd, int pid); |
31 | extern unsigned long irq_lock(void); | 32 | |
32 | extern void irq_unlock(unsigned long flags); | 33 | #ifdef CONFIG_MODE_TT |
34 | extern void forward_interrupts(int pid); | ||
35 | #endif | ||
33 | 36 | ||
34 | #endif | 37 | #endif |
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 310980b32173..b98bdd8e052a 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
@@ -72,10 +72,8 @@ extern void init_flush_vm(void); | |||
72 | extern void *syscall_sp(void *t); | 72 | extern void *syscall_sp(void *t); |
73 | extern void syscall_trace(union uml_pt_regs *regs, int entryexit); | 73 | extern void syscall_trace(union uml_pt_regs *regs, int entryexit); |
74 | extern int hz(void); | 74 | extern int hz(void); |
75 | extern void uml_idle_timer(void); | ||
76 | extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); | 75 | extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); |
77 | extern int external_pid(void *t); | 76 | extern int external_pid(void *t); |
78 | extern void boot_timer_handler(int sig); | ||
79 | extern void interrupt_end(void); | 77 | extern void interrupt_end(void); |
80 | extern void initial_thread_cb(void (*proc)(void *), void *arg); | 78 | extern void initial_thread_cb(void (*proc)(void *), void *arg); |
81 | extern int debugger_signal(int status, int pid); | 79 | extern int debugger_signal(int status, int pid); |
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h index 8e7053013f7b..1b5c0131a12e 100644 --- a/arch/um/include/longjmp.h +++ b/arch/um/include/longjmp.h | |||
@@ -8,8 +8,8 @@ | |||
8 | longjmp(*buf, val); \ | 8 | longjmp(*buf, val); \ |
9 | } while(0) | 9 | } while(0) |
10 | 10 | ||
11 | #define UML_SETJMP(buf, enable) ({ \ | 11 | #define UML_SETJMP(buf) ({ \ |
12 | int n; \ | 12 | int n, enable; \ |
13 | enable = get_signals(); \ | 13 | enable = get_signals(); \ |
14 | n = setjmp(*buf); \ | 14 | n = setjmp(*buf); \ |
15 | if(n != 0) \ | 15 | if(n != 0) \ |
diff --git a/arch/um/include/os.h b/arch/um/include/os.h index f88856c28a66..5316e8a4a4fd 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.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 | */ |
@@ -15,9 +15,9 @@ | |||
15 | #include "irq_user.h" | 15 | #include "irq_user.h" |
16 | #include "sysdep/tls.h" | 16 | #include "sysdep/tls.h" |
17 | 17 | ||
18 | #define OS_TYPE_FILE 1 | 18 | #define OS_TYPE_FILE 1 |
19 | #define OS_TYPE_DIR 2 | 19 | #define OS_TYPE_DIR 2 |
20 | #define OS_TYPE_SYMLINK 3 | 20 | #define OS_TYPE_SYMLINK 3 |
21 | #define OS_TYPE_CHARDEV 4 | 21 | #define OS_TYPE_CHARDEV 4 |
22 | #define OS_TYPE_BLOCKDEV 5 | 22 | #define OS_TYPE_BLOCKDEV 5 |
23 | #define OS_TYPE_FIFO 6 | 23 | #define OS_TYPE_FIFO 6 |
@@ -61,68 +61,68 @@ struct openflags { | |||
61 | }; | 61 | }; |
62 | 62 | ||
63 | #define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \ | 63 | #define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \ |
64 | .t = 0, .a = 0, .e = 0, .cl = 0 }) | 64 | .t = 0, .a = 0, .e = 0, .cl = 0 }) |
65 | 65 | ||
66 | static inline struct openflags of_read(struct openflags flags) | 66 | static inline struct openflags of_read(struct openflags flags) |
67 | { | 67 | { |
68 | flags.r = 1; | 68 | flags.r = 1; |
69 | return(flags); | 69 | return flags; |
70 | } | 70 | } |
71 | 71 | ||
72 | static inline struct openflags of_write(struct openflags flags) | 72 | static inline struct openflags of_write(struct openflags flags) |
73 | { | 73 | { |
74 | flags.w = 1; | 74 | flags.w = 1; |
75 | return(flags); | 75 | return flags; |
76 | } | 76 | } |
77 | 77 | ||
78 | static inline struct openflags of_rdwr(struct openflags flags) | 78 | static inline struct openflags of_rdwr(struct openflags flags) |
79 | { | 79 | { |
80 | return(of_read(of_write(flags))); | 80 | return of_read(of_write(flags)); |
81 | } | 81 | } |
82 | 82 | ||
83 | static inline struct openflags of_set_rw(struct openflags flags, int r, int w) | 83 | static inline struct openflags of_set_rw(struct openflags flags, int r, int w) |
84 | { | 84 | { |
85 | flags.r = r; | 85 | flags.r = r; |
86 | flags.w = w; | 86 | flags.w = w; |
87 | return(flags); | 87 | return flags; |
88 | } | 88 | } |
89 | 89 | ||
90 | static inline struct openflags of_sync(struct openflags flags) | 90 | static inline struct openflags of_sync(struct openflags flags) |
91 | { | 91 | { |
92 | flags.s = 1; | 92 | flags.s = 1; |
93 | return(flags); | 93 | return flags; |
94 | } | 94 | } |
95 | 95 | ||
96 | static inline struct openflags of_create(struct openflags flags) | 96 | static inline struct openflags of_create(struct openflags flags) |
97 | { | 97 | { |
98 | flags.c = 1; | 98 | flags.c = 1; |
99 | return(flags); | 99 | return flags; |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline struct openflags of_trunc(struct openflags flags) | 102 | static inline struct openflags of_trunc(struct openflags flags) |
103 | { | 103 | { |
104 | flags.t = 1; | 104 | flags.t = 1; |
105 | return(flags); | 105 | return flags; |
106 | } | 106 | } |
107 | 107 | ||
108 | static inline struct openflags of_append(struct openflags flags) | 108 | static inline struct openflags of_append(struct openflags flags) |
109 | { | 109 | { |
110 | flags.a = 1; | 110 | flags.a = 1; |
111 | return(flags); | 111 | return flags; |
112 | } | 112 | } |
113 | 113 | ||
114 | static inline struct openflags of_excl(struct openflags flags) | 114 | static inline struct openflags of_excl(struct openflags flags) |
115 | { | 115 | { |
116 | flags.e = 1; | 116 | flags.e = 1; |
117 | return(flags); | 117 | return flags; |
118 | } | 118 | } |
119 | 119 | ||
120 | static inline struct openflags of_cloexec(struct openflags flags) | 120 | static inline struct openflags of_cloexec(struct openflags flags) |
121 | { | 121 | { |
122 | flags.cl = 1; | 122 | flags.cl = 1; |
123 | return(flags); | 123 | return flags; |
124 | } | 124 | } |
125 | 125 | ||
126 | /* file.c */ | 126 | /* file.c */ |
127 | extern int os_stat_file(const char *file_name, struct uml_stat *buf); | 127 | extern int os_stat_file(const char *file_name, struct uml_stat *buf); |
128 | extern int os_stat_fd(const int fd, struct uml_stat *buf); | 128 | extern int os_stat_fd(const int fd, struct uml_stat *buf); |
@@ -199,12 +199,12 @@ extern int os_getpid(void); | |||
199 | extern int os_getpgrp(void); | 199 | extern int os_getpgrp(void); |
200 | 200 | ||
201 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); | 201 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); |
202 | extern void init_new_thread_signals(int altstack); | 202 | extern void init_new_thread_signals(void); |
203 | extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); | 203 | extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); |
204 | 204 | ||
205 | extern int os_map_memory(void *virt, int fd, unsigned long long off, | 205 | extern int os_map_memory(void *virt, int fd, unsigned long long off, |
206 | unsigned long len, int r, int w, int x); | 206 | unsigned long len, int r, int w, int x); |
207 | extern int os_protect_memory(void *addr, unsigned long len, | 207 | extern int os_protect_memory(void *addr, unsigned long len, |
208 | int r, int w, int x); | 208 | int r, int w, int x); |
209 | extern int os_unmap_memory(void *addr, int len); | 209 | extern int os_unmap_memory(void *addr, int len); |
210 | extern int os_drop_memory(void *addr, int length); | 210 | extern int os_drop_memory(void *addr, int length); |
@@ -318,7 +318,6 @@ extern void reboot_skas(void); | |||
318 | 318 | ||
319 | /* irq.c */ | 319 | /* irq.c */ |
320 | extern int os_waiting_for_events(struct irq_fd *active_fds); | 320 | extern int os_waiting_for_events(struct irq_fd *active_fds); |
321 | extern int os_isatty(int fd); | ||
322 | extern int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds); | 321 | extern int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds); |
323 | extern void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, | 322 | extern void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg, |
324 | struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2); | 323 | struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2); |
@@ -330,9 +329,8 @@ extern void os_set_ioignore(void); | |||
330 | extern void init_irq_signals(int on_sigstack); | 329 | extern void init_irq_signals(int on_sigstack); |
331 | 330 | ||
332 | /* sigio.c */ | 331 | /* sigio.c */ |
333 | extern void write_sigio_workaround(void); | ||
334 | extern int add_sigio_fd(int fd, int read); | ||
335 | extern int ignore_sigio_fd(int fd); | 332 | extern int ignore_sigio_fd(int fd); |
333 | extern void maybe_sigio_broken(int fd, int read); | ||
336 | 334 | ||
337 | /* skas/trap */ | 335 | /* skas/trap */ |
338 | extern void sig_handler_common_skas(int sig, void *sc_ptr); | 336 | extern void sig_handler_common_skas(int sig, void *sc_ptr); |
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h index 63c58739bde0..9cd9c6ec9a63 100644 --- a/arch/um/include/skas/mode_kern_skas.h +++ b/arch/um/include/skas/mode_kern_skas.h | |||
@@ -29,8 +29,7 @@ extern void flush_tlb_mm_skas(struct mm_struct *mm); | |||
29 | extern void force_flush_all_skas(void); | 29 | extern void force_flush_all_skas(void); |
30 | extern long execute_syscall_skas(void *r); | 30 | extern long execute_syscall_skas(void *r); |
31 | extern void before_mem_skas(unsigned long unused); | 31 | extern void before_mem_skas(unsigned long unused); |
32 | extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, | 32 | extern unsigned long set_task_sizes_skas(unsigned long *task_size_out); |
33 | unsigned long *task_size_out); | ||
34 | extern int start_uml_skas(void); | 33 | extern int start_uml_skas(void); |
35 | extern int external_pid_skas(struct task_struct *task); | 34 | extern int external_pid_skas(struct task_struct *task); |
36 | extern int thread_pid_skas(struct task_struct *task); | 35 | extern int thread_pid_skas(struct task_struct *task); |
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h index efa0012550d0..a4fc63057195 100644 --- a/arch/um/include/tt/mode_kern_tt.h +++ b/arch/um/include/tt/mode_kern_tt.h | |||
@@ -30,8 +30,7 @@ extern void flush_tlb_mm_tt(struct mm_struct *mm); | |||
30 | extern void force_flush_all_tt(void); | 30 | extern void force_flush_all_tt(void); |
31 | extern long execute_syscall_tt(void *r); | 31 | extern long execute_syscall_tt(void *r); |
32 | extern void before_mem_tt(unsigned long brk_start); | 32 | extern void before_mem_tt(unsigned long brk_start); |
33 | extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, | 33 | extern unsigned long set_task_sizes_tt(unsigned long *task_size_out); |
34 | unsigned long *task_size_out); | ||
35 | extern int start_uml_tt(void); | 34 | extern int start_uml_tt(void); |
36 | extern int external_pid_tt(struct task_struct *task); | 35 | extern int external_pid_tt(struct task_struct *task); |
37 | extern int thread_pid_tt(struct task_struct *task); | 36 | extern int thread_pid_tt(struct task_struct *task); |
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index fe08971b64cf..a2d93065b2d0 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -6,16 +6,14 @@ | |||
6 | extra-y := vmlinux.lds | 6 | extra-y := vmlinux.lds |
7 | clean-files := | 7 | clean-files := |
8 | 8 | ||
9 | obj-y = config.o exec_kern.o exitcode.o \ | 9 | obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ |
10 | init_task.o irq.o ksyms.o mem.o physmem.o \ | 10 | physmem.o process_kern.o ptrace.o reboot.o resource.o sigio.o \ |
11 | process_kern.o ptrace.o reboot.o resource.o sigio_kern.o \ | 11 | signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ |
12 | signal_kern.o smp.o syscall_kern.o sysrq.o \ | 12 | um_arch.o umid.o |
13 | time_kern.o tlb.o trap_kern.o uaccess.o um_arch.o umid.o | ||
14 | 13 | ||
15 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o | 14 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
16 | obj-$(CONFIG_GPROF) += gprof_syms.o | 15 | obj-$(CONFIG_GPROF) += gprof_syms.o |
17 | obj-$(CONFIG_GCOV) += gmon_syms.o | 16 | obj-$(CONFIG_GCOV) += gmon_syms.o |
18 | obj-$(CONFIG_SYSCALL_DEBUG) += syscall.o | ||
19 | 17 | ||
20 | obj-$(CONFIG_MODE_TT) += tt/ | 18 | obj-$(CONFIG_MODE_TT) += tt/ |
21 | obj-$(CONFIG_MODE_SKAS) += skas/ | 19 | obj-$(CONFIG_MODE_SKAS) += skas/ |
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 2517ecb8bf27..68ed24df5c8f 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S | |||
@@ -26,6 +26,7 @@ SECTIONS | |||
26 | 26 | ||
27 | /* Read-only sections, merged into text segment: */ | 27 | /* Read-only sections, merged into text segment: */ |
28 | .hash : { *(.hash) } | 28 | .hash : { *(.hash) } |
29 | .gnu.hash : { *(.gnu.hash) } | ||
29 | .dynsym : { *(.dynsym) } | 30 | .dynsym : { *(.dynsym) } |
30 | .dynstr : { *(.dynstr) } | 31 | .dynstr : { *(.dynstr) } |
31 | .gnu.version : { *(.gnu.version) } | 32 | .gnu.version : { *(.gnu.version) } |
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec.c index c0cb627bf594..fc38a6d5906d 100644 --- a/arch/um/kernel/exec_kern.c +++ b/arch/um/kernel/exec.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
@@ -31,18 +31,27 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) | |||
31 | CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); | 31 | CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); |
32 | } | 32 | } |
33 | 33 | ||
34 | #ifdef CONFIG_TTY_LOG | ||
35 | extern void log_exec(char **argv, void *tty); | ||
36 | #endif | ||
37 | |||
34 | static long execve1(char *file, char __user * __user *argv, | 38 | static long execve1(char *file, char __user * __user *argv, |
35 | char __user *__user *env) | 39 | char __user *__user *env) |
36 | { | 40 | { |
37 | long error; | 41 | long error; |
38 | 42 | ||
39 | #ifdef CONFIG_TTY_LOG | 43 | #ifdef CONFIG_TTY_LOG |
40 | log_exec(argv, current->tty); | 44 | task_lock(current); |
45 | log_exec(argv, current->signal->tty); | ||
46 | task_unlock(current); | ||
41 | #endif | 47 | #endif |
42 | error = do_execve(file, argv, env, ¤t->thread.regs); | 48 | error = do_execve(file, argv, env, ¤t->thread.regs); |
43 | if (error == 0){ | 49 | if (error == 0){ |
44 | task_lock(current); | 50 | task_lock(current); |
45 | current->ptrace &= ~PT_DTRACE; | 51 | current->ptrace &= ~PT_DTRACE; |
52 | #ifdef SUBARCH_EXECVE1 | ||
53 | SUBARCH_EXECVE1(¤t->thread.regs.regs); | ||
54 | #endif | ||
46 | task_unlock(current); | 55 | task_unlock(current); |
47 | set_cmdline(current_cmd()); | 56 | set_cmdline(current_cmd()); |
48 | } | 57 | } |
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index bfd0bdc8cd40..589c69a75043 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -110,18 +110,7 @@ void sigio_handler(int sig, union uml_pt_regs *regs) | |||
110 | free_irqs(); | 110 | free_irqs(); |
111 | } | 111 | } |
112 | 112 | ||
113 | static void maybe_sigio_broken(int fd, int type) | 113 | static DEFINE_SPINLOCK(irq_lock); |
114 | { | ||
115 | if (os_isatty(fd)) { | ||
116 | if ((type == IRQ_WRITE) && !pty_output_sigio) { | ||
117 | write_sigio_workaround(); | ||
118 | add_sigio_fd(fd, 0); | ||
119 | } else if ((type == IRQ_READ) && !pty_close_sigio) { | ||
120 | write_sigio_workaround(); | ||
121 | add_sigio_fd(fd, 1); | ||
122 | } | ||
123 | } | ||
124 | } | ||
125 | 114 | ||
126 | int activate_fd(int irq, int fd, int type, void *dev_id) | 115 | int activate_fd(int irq, int fd, int type, void *dev_id) |
127 | { | 116 | { |
@@ -166,7 +155,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
166 | * this is called only from process context, and can be locked with | 155 | * this is called only from process context, and can be locked with |
167 | * a semaphore. | 156 | * a semaphore. |
168 | */ | 157 | */ |
169 | flags = irq_lock(); | 158 | spin_lock_irqsave(&irq_lock, flags); |
170 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { | 159 | for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { |
171 | if ((irq_fd->fd == fd) && (irq_fd->type == type)) { | 160 | if ((irq_fd->fd == fd) && (irq_fd->type == type)) { |
172 | printk("Registering fd %d twice\n", fd); | 161 | printk("Registering fd %d twice\n", fd); |
@@ -199,7 +188,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
199 | * so we will not be able to put new pollfd struct to pollfds | 188 | * so we will not be able to put new pollfd struct to pollfds |
200 | * then we free the buffer tmp_fds and try again. | 189 | * then we free the buffer tmp_fds and try again. |
201 | */ | 190 | */ |
202 | irq_unlock(flags); | 191 | spin_unlock_irqrestore(&irq_lock, flags); |
203 | kfree(tmp_pfd); | 192 | kfree(tmp_pfd); |
204 | tmp_pfd = NULL; | 193 | tmp_pfd = NULL; |
205 | 194 | ||
@@ -207,24 +196,24 @@ int activate_fd(int irq, int fd, int type, void *dev_id) | |||
207 | if (tmp_pfd == NULL) | 196 | if (tmp_pfd == NULL) |
208 | goto out_kfree; | 197 | goto out_kfree; |
209 | 198 | ||
210 | flags = irq_lock(); | 199 | spin_lock_irqsave(&irq_lock, flags); |
211 | } | 200 | } |
212 | /*-------------*/ | 201 | /*-------------*/ |
213 | 202 | ||
214 | *last_irq_ptr = new_fd; | 203 | *last_irq_ptr = new_fd; |
215 | last_irq_ptr = &new_fd->next; | 204 | last_irq_ptr = &new_fd->next; |
216 | 205 | ||
217 | irq_unlock(flags); | 206 | spin_unlock_irqrestore(&irq_lock, flags); |
218 | 207 | ||
219 | /* This calls activate_fd, so it has to be outside the critical | 208 | /* This calls activate_fd, so it has to be outside the critical |
220 | * section. | 209 | * section. |
221 | */ | 210 | */ |
222 | maybe_sigio_broken(fd, type); | 211 | maybe_sigio_broken(fd, (type == IRQ_READ)); |
223 | 212 | ||
224 | return(0); | 213 | return(0); |
225 | 214 | ||
226 | out_unlock: | 215 | out_unlock: |
227 | irq_unlock(flags); | 216 | spin_unlock_irqrestore(&irq_lock, flags); |
228 | out_kfree: | 217 | out_kfree: |
229 | kfree(new_fd); | 218 | kfree(new_fd); |
230 | out: | 219 | out: |
@@ -235,9 +224,9 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) | |||
235 | { | 224 | { |
236 | unsigned long flags; | 225 | unsigned long flags; |
237 | 226 | ||
238 | flags = irq_lock(); | 227 | spin_lock_irqsave(&irq_lock, flags); |
239 | os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr); | 228 | os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr); |
240 | irq_unlock(flags); | 229 | spin_unlock_irqrestore(&irq_lock, flags); |
241 | } | 230 | } |
242 | 231 | ||
243 | struct irq_and_dev { | 232 | struct irq_and_dev { |
@@ -304,19 +293,19 @@ void reactivate_fd(int fd, int irqnum) | |||
304 | unsigned long flags; | 293 | unsigned long flags; |
305 | int i; | 294 | int i; |
306 | 295 | ||
307 | flags = irq_lock(); | 296 | spin_lock_irqsave(&irq_lock, flags); |
308 | irq = find_irq_by_fd(fd, irqnum, &i); | 297 | irq = find_irq_by_fd(fd, irqnum, &i); |
309 | if (irq == NULL) { | 298 | if (irq == NULL) { |
310 | irq_unlock(flags); | 299 | spin_unlock_irqrestore(&irq_lock, flags); |
311 | return; | 300 | return; |
312 | } | 301 | } |
313 | os_set_pollfd(i, irq->fd); | 302 | os_set_pollfd(i, irq->fd); |
314 | irq_unlock(flags); | 303 | spin_unlock_irqrestore(&irq_lock, flags); |
315 | 304 | ||
316 | /* This calls activate_fd, so it has to be outside the critical | 305 | /* This calls activate_fd, so it has to be outside the critical |
317 | * section. | 306 | * section. |
318 | */ | 307 | */ |
319 | maybe_sigio_broken(fd, irq->type); | 308 | maybe_sigio_broken(fd, (irq->type == IRQ_READ)); |
320 | } | 309 | } |
321 | 310 | ||
322 | void deactivate_fd(int fd, int irqnum) | 311 | void deactivate_fd(int fd, int irqnum) |
@@ -325,13 +314,13 @@ void deactivate_fd(int fd, int irqnum) | |||
325 | unsigned long flags; | 314 | unsigned long flags; |
326 | int i; | 315 | int i; |
327 | 316 | ||
328 | flags = irq_lock(); | 317 | spin_lock_irqsave(&irq_lock, flags); |
329 | irq = find_irq_by_fd(fd, irqnum, &i); | 318 | irq = find_irq_by_fd(fd, irqnum, &i); |
330 | if (irq == NULL) | 319 | if (irq == NULL) |
331 | goto out; | 320 | goto out; |
332 | os_set_pollfd(i, -1); | 321 | os_set_pollfd(i, -1); |
333 | out: | 322 | out: |
334 | irq_unlock(flags); | 323 | spin_unlock_irqrestore(&irq_lock, flags); |
335 | } | 324 | } |
336 | 325 | ||
337 | int deactivate_all_fds(void) | 326 | int deactivate_all_fds(void) |
@@ -350,13 +339,14 @@ int deactivate_all_fds(void) | |||
350 | return 0; | 339 | return 0; |
351 | } | 340 | } |
352 | 341 | ||
342 | #ifdef CONFIG_MODE_TT | ||
353 | void forward_interrupts(int pid) | 343 | void forward_interrupts(int pid) |
354 | { | 344 | { |
355 | struct irq_fd *irq; | 345 | struct irq_fd *irq; |
356 | unsigned long flags; | 346 | unsigned long flags; |
357 | int err; | 347 | int err; |
358 | 348 | ||
359 | flags = irq_lock(); | 349 | spin_lock_irqsave(&irq_lock, flags); |
360 | for (irq = active_fds; irq != NULL; irq = irq->next) { | 350 | for (irq = active_fds; irq != NULL; irq = irq->next) { |
361 | err = os_set_owner(irq->fd, pid); | 351 | err = os_set_owner(irq->fd, pid); |
362 | if (err < 0) { | 352 | if (err < 0) { |
@@ -369,8 +359,9 @@ void forward_interrupts(int pid) | |||
369 | 359 | ||
370 | irq->pid = pid; | 360 | irq->pid = pid; |
371 | } | 361 | } |
372 | irq_unlock(flags); | 362 | spin_unlock_irqrestore(&irq_lock, flags); |
373 | } | 363 | } |
364 | #endif | ||
374 | 365 | ||
375 | /* | 366 | /* |
376 | * do_IRQ handles all normal device IRQ's (the special | 367 | * do_IRQ handles all normal device IRQ's (the special |
@@ -403,21 +394,6 @@ int um_request_irq(unsigned int irq, int fd, int type, | |||
403 | EXPORT_SYMBOL(um_request_irq); | 394 | EXPORT_SYMBOL(um_request_irq); |
404 | EXPORT_SYMBOL(reactivate_fd); | 395 | EXPORT_SYMBOL(reactivate_fd); |
405 | 396 | ||
406 | static DEFINE_SPINLOCK(irq_spinlock); | ||
407 | |||
408 | unsigned long irq_lock(void) | ||
409 | { | ||
410 | unsigned long flags; | ||
411 | |||
412 | spin_lock_irqsave(&irq_spinlock, flags); | ||
413 | return flags; | ||
414 | } | ||
415 | |||
416 | void irq_unlock(unsigned long flags) | ||
417 | { | ||
418 | spin_unlock_irqrestore(&irq_spinlock, flags); | ||
419 | } | ||
420 | |||
421 | /* hw_interrupt_type must define (startup || enable) && | 397 | /* hw_interrupt_type must define (startup || enable) && |
422 | * (shutdown || disable) && end */ | 398 | * (shutdown || disable) && end */ |
423 | static void dummy(unsigned int irq) | 399 | static void dummy(unsigned int irq) |
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index 432cf0b97a13..c97045d6d89f 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c | |||
@@ -88,12 +88,6 @@ EXPORT_SYMBOL(dump_thread); | |||
88 | EXPORT_SYMBOL(do_gettimeofday); | 88 | EXPORT_SYMBOL(do_gettimeofday); |
89 | EXPORT_SYMBOL(do_settimeofday); | 89 | EXPORT_SYMBOL(do_settimeofday); |
90 | 90 | ||
91 | /* This is here because UML expands lseek to sys_lseek, not to a system | ||
92 | * call instruction. | ||
93 | */ | ||
94 | EXPORT_SYMBOL(sys_lseek); | ||
95 | EXPORT_SYMBOL(sys_wait4); | ||
96 | |||
97 | #ifdef CONFIG_SMP | 91 | #ifdef CONFIG_SMP |
98 | 92 | ||
99 | /* required for SMP */ | 93 | /* required for SMP */ |
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 44e41a35f000..61280167c560 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c | |||
@@ -24,8 +24,6 @@ | |||
24 | #include "init.h" | 24 | #include "init.h" |
25 | #include "kern_constants.h" | 25 | #include "kern_constants.h" |
26 | 26 | ||
27 | extern char __binary_start; | ||
28 | |||
29 | /* Changed during early boot */ | 27 | /* Changed during early boot */ |
30 | unsigned long *empty_zero_page = NULL; | 28 | unsigned long *empty_zero_page = NULL; |
31 | unsigned long *empty_bad_page = NULL; | 29 | unsigned long *empty_bad_page = NULL; |
@@ -65,8 +63,6 @@ static void setup_highmem(unsigned long highmem_start, | |||
65 | 63 | ||
66 | void mem_init(void) | 64 | void mem_init(void) |
67 | { | 65 | { |
68 | unsigned long start; | ||
69 | |||
70 | max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT; | 66 | max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT; |
71 | 67 | ||
72 | /* clear the zero-page */ | 68 | /* clear the zero-page */ |
@@ -81,13 +77,6 @@ void mem_init(void) | |||
81 | free_bootmem(__pa(brk_end), uml_reserved - brk_end); | 77 | free_bootmem(__pa(brk_end), uml_reserved - brk_end); |
82 | uml_reserved = brk_end; | 78 | uml_reserved = brk_end; |
83 | 79 | ||
84 | /* Fill in any hole at the start of the binary */ | ||
85 | start = (unsigned long) &__binary_start & PAGE_MASK; | ||
86 | if(uml_physmem != start){ | ||
87 | map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem, | ||
88 | 1, 1, 0); | ||
89 | } | ||
90 | |||
91 | /* this will put all low memory onto the freelists */ | 80 | /* this will put all low memory onto the freelists */ |
92 | totalram_pages = free_all_bootmem(); | 81 | totalram_pages = free_all_bootmem(); |
93 | totalhigh_pages = highmem >> PAGE_SHIFT; | 82 | totalhigh_pages = highmem >> PAGE_SHIFT; |
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 166cb09cae4c..abafa64b8727 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c | |||
@@ -317,7 +317,7 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, | |||
317 | } | 317 | } |
318 | } | 318 | } |
319 | 319 | ||
320 | extern int __syscall_stub_start, __binary_start; | 320 | extern int __syscall_stub_start; |
321 | 321 | ||
322 | void setup_physmem(unsigned long start, unsigned long reserve_end, | 322 | void setup_physmem(unsigned long start, unsigned long reserve_end, |
323 | unsigned long len, unsigned long long highmem) | 323 | unsigned long len, unsigned long long highmem) |
diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio.c index 51b677083948..0ad755ceb212 100644 --- a/arch/um/kernel/sigio_kern.c +++ b/arch/um/kernel/sigio.c | |||
@@ -31,7 +31,7 @@ int write_sigio_irq(int fd) | |||
31 | int err; | 31 | int err; |
32 | 32 | ||
33 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, | 33 | err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, |
34 | IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "write sigio", | 34 | IRQF_DISABLED|IRQF_SAMPLE_RANDOM, "write sigio", |
35 | NULL); | 35 | NULL); |
36 | if(err){ | 36 | if(err){ |
37 | printk("write_sigio_irq : um_request_irq failed, err = %d\n", | 37 | printk("write_sigio_irq : um_request_irq failed, err = %d\n", |
@@ -53,17 +53,3 @@ void sigio_unlock(void) | |||
53 | { | 53 | { |
54 | spin_unlock(&sigio_spinlock); | 54 | spin_unlock(&sigio_spinlock); |
55 | } | 55 | } |
56 | |||
57 | extern void sigio_cleanup(void); | ||
58 | __uml_exitcall(sigio_cleanup); | ||
59 | |||
60 | /* | ||
61 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
62 | * Emacs will notice this stuff at the end of the file and automatically | ||
63 | * adjust the settings for this buffer only. This must remain at the end | ||
64 | * of the file. | ||
65 | * --------------------------------------------------------------------------- | ||
66 | * Local variables: | ||
67 | * c-file-style: "linux" | ||
68 | * End: | ||
69 | */ | ||
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal.c index da17b7541e08..4aa9808ba264 100644 --- a/arch/um/kernel/signal_kern.c +++ b/arch/um/kernel/signal.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(unblock_signals); | |||
36 | 36 | ||
37 | /* | 37 | /* |
38 | * OK, we're invoking a handler | 38 | * OK, we're invoking a handler |
39 | */ | 39 | */ |
40 | static int handle_signal(struct pt_regs *regs, unsigned long signr, | 40 | static int handle_signal(struct pt_regs *regs, unsigned long signr, |
41 | struct k_sigaction *ka, siginfo_t *info, | 41 | struct k_sigaction *ka, siginfo_t *info, |
42 | sigset_t *oldset) | 42 | sigset_t *oldset) |
@@ -88,7 +88,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, | |||
88 | force_sigsegv(signr, current); | 88 | force_sigsegv(signr, current); |
89 | } else { | 89 | } else { |
90 | spin_lock_irq(¤t->sighand->siglock); | 90 | spin_lock_irq(¤t->sighand->siglock); |
91 | sigorsets(¤t->blocked, ¤t->blocked, | 91 | sigorsets(¤t->blocked, ¤t->blocked, |
92 | &ka->sa.sa_mask); | 92 | &ka->sa.sa_mask); |
93 | if(!(ka->sa.sa_flags & SA_NODEFER)) | 93 | if(!(ka->sa.sa_flags & SA_NODEFER)) |
94 | sigaddset(¤t->blocked, signr); | 94 | sigaddset(¤t->blocked, signr); |
@@ -136,7 +136,7 @@ static int kern_do_signal(struct pt_regs *regs) | |||
136 | PT_REGS_RESTART_SYSCALL(regs); | 136 | PT_REGS_RESTART_SYSCALL(regs); |
137 | break; | 137 | break; |
138 | case -ERESTART_RESTARTBLOCK: | 138 | case -ERESTART_RESTARTBLOCK: |
139 | PT_REGS_SYSCALL_RET(regs) = __NR_restart_syscall; | 139 | PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; |
140 | PT_REGS_RESTART_SYSCALL(regs); | 140 | PT_REGS_RESTART_SYSCALL(regs); |
141 | break; | 141 | break; |
142 | } | 142 | } |
@@ -146,7 +146,7 @@ static int kern_do_signal(struct pt_regs *regs) | |||
146 | * you set a breakpoint on a system call instruction and singlestep | 146 | * you set a breakpoint on a system call instruction and singlestep |
147 | * from it, the tracing thread used to PTRACE_SINGLESTEP the process | 147 | * from it, the tracing thread used to PTRACE_SINGLESTEP the process |
148 | * rather than PTRACE_SYSCALL it, allowing the system call to execute | 148 | * rather than PTRACE_SYSCALL it, allowing the system call to execute |
149 | * on the host. The tracing thread will check this flag and | 149 | * on the host. The tracing thread will check this flag and |
150 | * PTRACE_SYSCALL if necessary. | 150 | * PTRACE_SYSCALL if necessary. |
151 | */ | 151 | */ |
152 | if(current->ptrace & PT_DTRACE) | 152 | if(current->ptrace & PT_DTRACE) |
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c index 88ab96c609ce..27bbf54b1e52 100644 --- a/arch/um/kernel/skas/mem.c +++ b/arch/um/kernel/skas/mem.c | |||
@@ -9,31 +9,19 @@ | |||
9 | #include "mem_user.h" | 9 | #include "mem_user.h" |
10 | #include "skas.h" | 10 | #include "skas.h" |
11 | 11 | ||
12 | unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, | 12 | unsigned long set_task_sizes_skas(unsigned long *task_size_out) |
13 | unsigned long *task_size_out) | ||
14 | { | 13 | { |
15 | /* Round up to the nearest 4M */ | 14 | /* Round up to the nearest 4M */ |
16 | unsigned long top = ROUND_4M((unsigned long) &arg); | 15 | unsigned long host_task_size = ROUND_4M((unsigned long) |
16 | &host_task_size); | ||
17 | 17 | ||
18 | #ifdef CONFIG_HOST_TASK_SIZE | 18 | #ifdef CONFIG_HOST_TASK_SIZE |
19 | *host_size_out = CONFIG_HOST_TASK_SIZE; | 19 | *host_size_out = ROUND_4M(CONFIG_HOST_TASK_SIZE); |
20 | *task_size_out = CONFIG_HOST_TASK_SIZE; | 20 | *task_size_out = CONFIG_HOST_TASK_SIZE; |
21 | #else | 21 | #else |
22 | *host_size_out = top; | ||
23 | if (!skas_needs_stub) | 22 | if (!skas_needs_stub) |
24 | *task_size_out = top; | 23 | *task_size_out = host_task_size; |
25 | else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; | 24 | else *task_size_out = CONFIG_STUB_START & PGDIR_MASK; |
26 | #endif | 25 | #endif |
27 | return(((unsigned long) set_task_sizes_skas) & ~0xffffff); | 26 | return host_task_size; |
28 | } | 27 | } |
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/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 2135eaf98a93..55caeec8b257 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -177,7 +177,7 @@ int start_uml_skas(void) | |||
177 | if(proc_mm) | 177 | if(proc_mm) |
178 | userspace_pid[0] = start_userspace(0); | 178 | userspace_pid[0] = start_userspace(0); |
179 | 179 | ||
180 | init_new_thread_signals(1); | 180 | init_new_thread_signals(); |
181 | 181 | ||
182 | init_task.thread.request.u.thread.proc = start_kernel_proc; | 182 | init_task.thread.request.u.thread.proc = start_kernel_proc; |
183 | init_task.thread.request.u.thread.arg = NULL; | 183 | init_task.thread.request.u.thread.arg = NULL; |
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index 51fb94076fcf..0ae4eea21be4 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c | |||
@@ -18,11 +18,7 @@ void handle_syscall(union uml_pt_regs *r) | |||
18 | struct pt_regs *regs = container_of(r, struct pt_regs, regs); | 18 | struct pt_regs *regs = container_of(r, struct pt_regs, regs); |
19 | long result; | 19 | long result; |
20 | int syscall; | 20 | int syscall; |
21 | #ifdef UML_CONFIG_SYSCALL_DEBUG | ||
22 | int index; | ||
23 | 21 | ||
24 | index = record_syscall_start(UPT_SYSCALL_NR(r)); | ||
25 | #endif | ||
26 | syscall_trace(r, 0); | 22 | syscall_trace(r, 0); |
27 | 23 | ||
28 | current->thread.nsyscalls++; | 24 | current->thread.nsyscalls++; |
@@ -44,7 +40,4 @@ void handle_syscall(union uml_pt_regs *r) | |||
44 | REGS_SET_SYSCALL_RETURN(r->skas.regs, result); | 40 | REGS_SET_SYSCALL_RETURN(r->skas.regs, result); |
45 | 41 | ||
46 | syscall_trace(r, 1); | 42 | syscall_trace(r, 1); |
47 | #ifdef UML_CONFIG_SYSCALL_DEBUG | ||
48 | record_syscall_end(index, result); | ||
49 | #endif | ||
50 | } | 43 | } |
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 1731d90e6850..48cf88dd02d4 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c | |||
@@ -1,36 +1,166 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | 2 | * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) |
3 | * Licensed under the GPL | 3 | * Licensed under the GPL |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include "linux/sched.h" | ||
7 | #include "linux/file.h" | ||
8 | #include "linux/smp_lock.h" | ||
9 | #include "linux/mm.h" | ||
10 | #include "linux/utsname.h" | ||
11 | #include "linux/msg.h" | ||
12 | #include "linux/shm.h" | ||
13 | #include "linux/sys.h" | ||
14 | #include "linux/syscalls.h" | ||
15 | #include "linux/unistd.h" | ||
16 | #include "linux/slab.h" | ||
17 | #include "linux/utime.h" | ||
18 | #include "asm/mman.h" | ||
19 | #include "asm/uaccess.h" | ||
6 | #include "kern_util.h" | 20 | #include "kern_util.h" |
7 | #include "syscall.h" | 21 | #include "user_util.h" |
8 | #include "os.h" | 22 | #include "sysdep/syscalls.h" |
23 | #include "mode_kern.h" | ||
24 | #include "choose-mode.h" | ||
9 | 25 | ||
10 | struct { | 26 | /* Unlocked, I don't care if this is a bit off */ |
11 | int syscall; | 27 | int nsyscalls = 0; |
12 | int pid; | ||
13 | long result; | ||
14 | unsigned long long start; | ||
15 | unsigned long long end; | ||
16 | } syscall_record[1024]; | ||
17 | 28 | ||
18 | int record_syscall_start(int syscall) | 29 | long sys_fork(void) |
19 | { | 30 | { |
20 | int max, index; | 31 | long ret; |
21 | 32 | ||
22 | max = sizeof(syscall_record)/sizeof(syscall_record[0]); | 33 | current->thread.forking = 1; |
23 | index = next_syscall_index(max); | 34 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), |
35 | ¤t->thread.regs, 0, NULL, NULL); | ||
36 | current->thread.forking = 0; | ||
37 | return(ret); | ||
38 | } | ||
39 | |||
40 | long sys_vfork(void) | ||
41 | { | ||
42 | long ret; | ||
43 | |||
44 | current->thread.forking = 1; | ||
45 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, | ||
46 | UPT_SP(¤t->thread.regs.regs), | ||
47 | ¤t->thread.regs, 0, NULL, NULL); | ||
48 | current->thread.forking = 0; | ||
49 | return(ret); | ||
50 | } | ||
51 | |||
52 | /* common code for old and new mmaps */ | ||
53 | long sys_mmap2(unsigned long addr, unsigned long len, | ||
54 | unsigned long prot, unsigned long flags, | ||
55 | unsigned long fd, unsigned long pgoff) | ||
56 | { | ||
57 | long error = -EBADF; | ||
58 | struct file * file = NULL; | ||
59 | |||
60 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
61 | if (!(flags & MAP_ANONYMOUS)) { | ||
62 | file = fget(fd); | ||
63 | if (!file) | ||
64 | goto out; | ||
65 | } | ||
66 | |||
67 | down_write(¤t->mm->mmap_sem); | ||
68 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
69 | up_write(¤t->mm->mmap_sem); | ||
70 | |||
71 | if (file) | ||
72 | fput(file); | ||
73 | out: | ||
74 | return error; | ||
75 | } | ||
76 | |||
77 | long old_mmap(unsigned long addr, unsigned long len, | ||
78 | unsigned long prot, unsigned long flags, | ||
79 | unsigned long fd, unsigned long offset) | ||
80 | { | ||
81 | long err = -EINVAL; | ||
82 | if (offset & ~PAGE_MASK) | ||
83 | goto out; | ||
84 | |||
85 | err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | ||
86 | out: | ||
87 | return err; | ||
88 | } | ||
89 | /* | ||
90 | * sys_pipe() is the normal C calling standard for creating | ||
91 | * a pipe. It's not the way unix traditionally does this, though. | ||
92 | */ | ||
93 | long sys_pipe(unsigned long __user * fildes) | ||
94 | { | ||
95 | int fd[2]; | ||
96 | long error; | ||
97 | |||
98 | error = do_pipe(fd); | ||
99 | if (!error) { | ||
100 | if (copy_to_user(fildes, fd, sizeof(fd))) | ||
101 | error = -EFAULT; | ||
102 | } | ||
103 | return error; | ||
104 | } | ||
24 | 105 | ||
25 | syscall_record[index].syscall = syscall; | 106 | |
26 | syscall_record[index].pid = current_pid(); | 107 | long sys_uname(struct old_utsname __user * name) |
27 | syscall_record[index].result = 0xdeadbeef; | 108 | { |
28 | syscall_record[index].start = os_nsecs(); | 109 | long err; |
29 | return(index); | 110 | if (!name) |
111 | return -EFAULT; | ||
112 | down_read(&uts_sem); | ||
113 | err = copy_to_user(name, &system_utsname, sizeof (*name)); | ||
114 | up_read(&uts_sem); | ||
115 | return err?-EFAULT:0; | ||
30 | } | 116 | } |
31 | 117 | ||
32 | void record_syscall_end(int index, long result) | 118 | long sys_olduname(struct oldold_utsname __user * name) |
33 | { | 119 | { |
34 | syscall_record[index].result = result; | 120 | long error; |
35 | syscall_record[index].end = os_nsecs(); | 121 | |
122 | if (!name) | ||
123 | return -EFAULT; | ||
124 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) | ||
125 | return -EFAULT; | ||
126 | |||
127 | down_read(&uts_sem); | ||
128 | |||
129 | error = __copy_to_user(&name->sysname,&system_utsname.sysname, | ||
130 | __OLD_UTS_LEN); | ||
131 | error |= __put_user(0,name->sysname+__OLD_UTS_LEN); | ||
132 | error |= __copy_to_user(&name->nodename,&system_utsname.nodename, | ||
133 | __OLD_UTS_LEN); | ||
134 | error |= __put_user(0,name->nodename+__OLD_UTS_LEN); | ||
135 | error |= __copy_to_user(&name->release,&system_utsname.release, | ||
136 | __OLD_UTS_LEN); | ||
137 | error |= __put_user(0,name->release+__OLD_UTS_LEN); | ||
138 | error |= __copy_to_user(&name->version,&system_utsname.version, | ||
139 | __OLD_UTS_LEN); | ||
140 | error |= __put_user(0,name->version+__OLD_UTS_LEN); | ||
141 | error |= __copy_to_user(&name->machine,&system_utsname.machine, | ||
142 | __OLD_UTS_LEN); | ||
143 | error |= __put_user(0,name->machine+__OLD_UTS_LEN); | ||
144 | |||
145 | up_read(&uts_sem); | ||
146 | |||
147 | error = error ? -EFAULT : 0; | ||
148 | |||
149 | return error; | ||
150 | } | ||
151 | |||
152 | DEFINE_SPINLOCK(syscall_lock); | ||
153 | |||
154 | static int syscall_index = 0; | ||
155 | |||
156 | int next_syscall_index(int limit) | ||
157 | { | ||
158 | int ret; | ||
159 | |||
160 | spin_lock(&syscall_lock); | ||
161 | ret = syscall_index; | ||
162 | if(++syscall_index == limit) | ||
163 | syscall_index = 0; | ||
164 | spin_unlock(&syscall_lock); | ||
165 | return(ret); | ||
36 | } | 166 | } |
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c deleted file mode 100644 index 37d3978337d8..000000000000 --- a/arch/um/kernel/syscall_kern.c +++ /dev/null | |||
@@ -1,166 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include "linux/sched.h" | ||
7 | #include "linux/file.h" | ||
8 | #include "linux/smp_lock.h" | ||
9 | #include "linux/mm.h" | ||
10 | #include "linux/utsname.h" | ||
11 | #include "linux/msg.h" | ||
12 | #include "linux/shm.h" | ||
13 | #include "linux/sys.h" | ||
14 | #include "linux/syscalls.h" | ||
15 | #include "linux/unistd.h" | ||
16 | #include "linux/slab.h" | ||
17 | #include "linux/utime.h" | ||
18 | #include "asm/mman.h" | ||
19 | #include "asm/uaccess.h" | ||
20 | #include "kern_util.h" | ||
21 | #include "user_util.h" | ||
22 | #include "sysdep/syscalls.h" | ||
23 | #include "mode_kern.h" | ||
24 | #include "choose-mode.h" | ||
25 | |||
26 | /* Unlocked, I don't care if this is a bit off */ | ||
27 | int nsyscalls = 0; | ||
28 | |||
29 | long sys_fork(void) | ||
30 | { | ||
31 | long ret; | ||
32 | |||
33 | current->thread.forking = 1; | ||
34 | ret = do_fork(SIGCHLD, UPT_SP(¤t->thread.regs.regs), | ||
35 | ¤t->thread.regs, 0, NULL, NULL); | ||
36 | current->thread.forking = 0; | ||
37 | return(ret); | ||
38 | } | ||
39 | |||
40 | long sys_vfork(void) | ||
41 | { | ||
42 | long ret; | ||
43 | |||
44 | current->thread.forking = 1; | ||
45 | ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, | ||
46 | UPT_SP(¤t->thread.regs.regs), | ||
47 | ¤t->thread.regs, 0, NULL, NULL); | ||
48 | current->thread.forking = 0; | ||
49 | return(ret); | ||
50 | } | ||
51 | |||
52 | /* common code for old and new mmaps */ | ||
53 | long sys_mmap2(unsigned long addr, unsigned long len, | ||
54 | unsigned long prot, unsigned long flags, | ||
55 | unsigned long fd, unsigned long pgoff) | ||
56 | { | ||
57 | long error = -EBADF; | ||
58 | struct file * file = NULL; | ||
59 | |||
60 | flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); | ||
61 | if (!(flags & MAP_ANONYMOUS)) { | ||
62 | file = fget(fd); | ||
63 | if (!file) | ||
64 | goto out; | ||
65 | } | ||
66 | |||
67 | down_write(¤t->mm->mmap_sem); | ||
68 | error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); | ||
69 | up_write(¤t->mm->mmap_sem); | ||
70 | |||
71 | if (file) | ||
72 | fput(file); | ||
73 | out: | ||
74 | return error; | ||
75 | } | ||
76 | |||
77 | long old_mmap(unsigned long addr, unsigned long len, | ||
78 | unsigned long prot, unsigned long flags, | ||
79 | unsigned long fd, unsigned long offset) | ||
80 | { | ||
81 | long err = -EINVAL; | ||
82 | if (offset & ~PAGE_MASK) | ||
83 | goto out; | ||
84 | |||
85 | err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); | ||
86 | out: | ||
87 | return err; | ||
88 | } | ||
89 | /* | ||
90 | * sys_pipe() is the normal C calling standard for creating | ||
91 | * a pipe. It's not the way unix traditionally does this, though. | ||
92 | */ | ||
93 | long sys_pipe(unsigned long __user * fildes) | ||
94 | { | ||
95 | int fd[2]; | ||
96 | long error; | ||
97 | |||
98 | error = do_pipe(fd); | ||
99 | if (!error) { | ||
100 | if (copy_to_user(fildes, fd, sizeof(fd))) | ||
101 | error = -EFAULT; | ||
102 | } | ||
103 | return error; | ||
104 | } | ||
105 | |||
106 | |||
107 | long sys_uname(struct old_utsname __user * name) | ||
108 | { | ||
109 | long err; | ||
110 | if (!name) | ||
111 | return -EFAULT; | ||
112 | down_read(&uts_sem); | ||
113 | err=copy_to_user(name, &system_utsname, sizeof (*name)); | ||
114 | up_read(&uts_sem); | ||
115 | return err?-EFAULT:0; | ||
116 | } | ||
117 | |||
118 | long sys_olduname(struct oldold_utsname __user * name) | ||
119 | { | ||
120 | long error; | ||
121 | |||
122 | if (!name) | ||
123 | return -EFAULT; | ||
124 | if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) | ||
125 | return -EFAULT; | ||
126 | |||
127 | down_read(&uts_sem); | ||
128 | |||
129 | error = __copy_to_user(&name->sysname,&system_utsname.sysname, | ||
130 | __OLD_UTS_LEN); | ||
131 | error |= __put_user(0,name->sysname+__OLD_UTS_LEN); | ||
132 | error |= __copy_to_user(&name->nodename,&system_utsname.nodename, | ||
133 | __OLD_UTS_LEN); | ||
134 | error |= __put_user(0,name->nodename+__OLD_UTS_LEN); | ||
135 | error |= __copy_to_user(&name->release,&system_utsname.release, | ||
136 | __OLD_UTS_LEN); | ||
137 | error |= __put_user(0,name->release+__OLD_UTS_LEN); | ||
138 | error |= __copy_to_user(&name->version,&system_utsname.version, | ||
139 | __OLD_UTS_LEN); | ||
140 | error |= __put_user(0,name->version+__OLD_UTS_LEN); | ||
141 | error |= __copy_to_user(&name->machine,&system_utsname.machine, | ||
142 | __OLD_UTS_LEN); | ||
143 | error |= __put_user(0,name->machine+__OLD_UTS_LEN); | ||
144 | |||
145 | up_read(&uts_sem); | ||
146 | |||
147 | error = error ? -EFAULT : 0; | ||
148 | |||
149 | return error; | ||
150 | } | ||
151 | |||
152 | DEFINE_SPINLOCK(syscall_lock); | ||
153 | |||
154 | static int syscall_index = 0; | ||
155 | |||
156 | int next_syscall_index(int limit) | ||
157 | { | ||
158 | int ret; | ||
159 | |||
160 | spin_lock(&syscall_lock); | ||
161 | ret = syscall_index; | ||
162 | if(++syscall_index == limit) | ||
163 | syscall_index = 0; | ||
164 | spin_unlock(&syscall_lock); | ||
165 | return(ret); | ||
166 | } | ||
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time.c index d7e044b5e5ee..552ca1cb9847 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time.c | |||
@@ -38,7 +38,6 @@ unsigned long long sched_clock(void) | |||
38 | /* Changed at early boot */ | 38 | /* Changed at early boot */ |
39 | int timer_irq_inited = 0; | 39 | int timer_irq_inited = 0; |
40 | 40 | ||
41 | static int first_tick; | ||
42 | static unsigned long long prev_nsecs; | 41 | static unsigned long long prev_nsecs; |
43 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | 42 | #ifdef CONFIG_UML_REAL_TIME_CLOCK |
44 | static long long delta; /* Deviation per interval */ | 43 | static long long delta; /* Deviation per interval */ |
@@ -48,15 +47,8 @@ void timer_irq(union uml_pt_regs *regs) | |||
48 | { | 47 | { |
49 | unsigned long long ticks = 0; | 48 | unsigned long long ticks = 0; |
50 | 49 | ||
51 | if(!timer_irq_inited){ | ||
52 | /* This is to ensure that ticks don't pile up when | ||
53 | * the timer handler is suspended */ | ||
54 | first_tick = 0; | ||
55 | return; | ||
56 | } | ||
57 | |||
58 | if(first_tick){ | ||
59 | #ifdef CONFIG_UML_REAL_TIME_CLOCK | 50 | #ifdef CONFIG_UML_REAL_TIME_CLOCK |
51 | if(prev_nsecs){ | ||
60 | /* We've had 1 tick */ | 52 | /* We've had 1 tick */ |
61 | unsigned long long nsecs = os_nsecs(); | 53 | unsigned long long nsecs = os_nsecs(); |
62 | 54 | ||
@@ -69,44 +61,17 @@ void timer_irq(union uml_pt_regs *regs) | |||
69 | 61 | ||
70 | ticks += (delta * HZ) / BILLION; | 62 | ticks += (delta * HZ) / BILLION; |
71 | delta -= (ticks * BILLION) / HZ; | 63 | delta -= (ticks * BILLION) / HZ; |
64 | } | ||
65 | else prev_nsecs = os_nsecs(); | ||
72 | #else | 66 | #else |
73 | ticks = 1; | 67 | ticks = 1; |
74 | #endif | 68 | #endif |
75 | } | ||
76 | else { | ||
77 | prev_nsecs = os_nsecs(); | ||
78 | first_tick = 1; | ||
79 | } | ||
80 | |||
81 | while(ticks > 0){ | 69 | while(ticks > 0){ |
82 | do_IRQ(TIMER_IRQ, regs); | 70 | do_IRQ(TIMER_IRQ, regs); |
83 | ticks--; | 71 | ticks--; |
84 | } | 72 | } |
85 | } | 73 | } |
86 | 74 | ||
87 | |||
88 | void time_init_kern(void) | ||
89 | { | ||
90 | long long nsecs; | ||
91 | |||
92 | nsecs = os_nsecs(); | ||
93 | set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, | ||
94 | -nsecs % BILLION); | ||
95 | } | ||
96 | |||
97 | void do_boot_timer_handler(struct sigcontext * sc) | ||
98 | { | ||
99 | unsigned long flags; | ||
100 | struct pt_regs regs; | ||
101 | |||
102 | CHOOSE_MODE((void) (UPT_SC(®s.regs) = sc), | ||
103 | (void) (regs.regs.skas.is_user = 0)); | ||
104 | |||
105 | write_seqlock_irqsave(&xtime_lock, flags); | ||
106 | do_timer(®s); | ||
107 | write_sequnlock_irqrestore(&xtime_lock, flags); | ||
108 | } | ||
109 | |||
110 | static DEFINE_SPINLOCK(timer_spinlock); | 75 | static DEFINE_SPINLOCK(timer_spinlock); |
111 | 76 | ||
112 | static unsigned long long local_offset = 0; | 77 | static unsigned long long local_offset = 0; |
@@ -142,6 +107,32 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs) | |||
142 | return IRQ_HANDLED; | 107 | return IRQ_HANDLED; |
143 | } | 108 | } |
144 | 109 | ||
110 | static void register_timer(void) | ||
111 | { | ||
112 | int err; | ||
113 | |||
114 | err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); | ||
115 | if(err != 0) | ||
116 | printk(KERN_ERR "timer_init : request_irq failed - " | ||
117 | "errno = %d\n", -err); | ||
118 | |||
119 | timer_irq_inited = 1; | ||
120 | |||
121 | user_time_init(); | ||
122 | } | ||
123 | |||
124 | extern void (*late_time_init)(void); | ||
125 | |||
126 | void time_init(void) | ||
127 | { | ||
128 | long long nsecs; | ||
129 | |||
130 | nsecs = os_nsecs(); | ||
131 | set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, | ||
132 | -nsecs % BILLION); | ||
133 | late_time_init = register_timer; | ||
134 | } | ||
135 | |||
145 | void do_gettimeofday(struct timeval *tv) | 136 | void do_gettimeofday(struct timeval *tv) |
146 | { | 137 | { |
147 | unsigned long long nsecs = get_time(); | 138 | unsigned long long nsecs = get_time(); |
@@ -189,18 +180,3 @@ void timer_handler(int sig, union uml_pt_regs *regs) | |||
189 | if(current_thread->cpu == 0) | 180 | if(current_thread->cpu == 0) |
190 | timer_irq(regs); | 181 | timer_irq(regs); |
191 | } | 182 | } |
192 | |||
193 | int __init timer_init(void) | ||
194 | { | ||
195 | int err; | ||
196 | |||
197 | user_time_init(); | ||
198 | err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); | ||
199 | if(err != 0) | ||
200 | printk(KERN_ERR "timer_init : request_irq failed - " | ||
201 | "errno = %d\n", -err); | ||
202 | timer_irq_inited = 1; | ||
203 | return(0); | ||
204 | } | ||
205 | |||
206 | arch_initcall(timer_init); | ||
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap.c index 02f6d4d8dc3a..ac70fa5a2e2a 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include "os.h" | 35 | #include "os.h" |
36 | 36 | ||
37 | /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ | 37 | /* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ |
38 | int handle_page_fault(unsigned long address, unsigned long ip, | 38 | int handle_page_fault(unsigned long address, unsigned long ip, |
39 | int is_write, int is_user, int *code_out) | 39 | int is_write, int is_user, int *code_out) |
40 | { | 40 | { |
41 | struct mm_struct *mm = current->mm; | 41 | struct mm_struct *mm = current->mm; |
@@ -55,20 +55,20 @@ int handle_page_fault(unsigned long address, unsigned long ip, | |||
55 | 55 | ||
56 | down_read(&mm->mmap_sem); | 56 | down_read(&mm->mmap_sem); |
57 | vma = find_vma(mm, address); | 57 | vma = find_vma(mm, address); |
58 | if(!vma) | 58 | if(!vma) |
59 | goto out; | 59 | goto out; |
60 | else if(vma->vm_start <= address) | 60 | else if(vma->vm_start <= address) |
61 | goto good_area; | 61 | goto good_area; |
62 | else if(!(vma->vm_flags & VM_GROWSDOWN)) | 62 | else if(!(vma->vm_flags & VM_GROWSDOWN)) |
63 | goto out; | 63 | goto out; |
64 | else if(is_user && !ARCH_IS_STACKGROW(address)) | 64 | else if(is_user && !ARCH_IS_STACKGROW(address)) |
65 | goto out; | 65 | goto out; |
66 | else if(expand_stack(vma, address)) | 66 | else if(expand_stack(vma, address)) |
67 | goto out; | 67 | goto out; |
68 | 68 | ||
69 | good_area: | 69 | good_area: |
70 | *code_out = SEGV_ACCERR; | 70 | *code_out = SEGV_ACCERR; |
71 | if(is_write && !(vma->vm_flags & VM_WRITE)) | 71 | if(is_write && !(vma->vm_flags & VM_WRITE)) |
72 | goto out; | 72 | goto out; |
73 | 73 | ||
74 | /* Don't require VM_READ|VM_EXEC for write faults! */ | 74 | /* Don't require VM_READ|VM_EXEC for write faults! */ |
@@ -184,14 +184,14 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |||
184 | else if(catcher != NULL){ | 184 | else if(catcher != NULL){ |
185 | current->thread.fault_addr = (void *) address; | 185 | current->thread.fault_addr = (void *) address; |
186 | do_longjmp(catcher, 1); | 186 | do_longjmp(catcher, 1); |
187 | } | 187 | } |
188 | else if(current->thread.fault_addr != NULL) | 188 | else if(current->thread.fault_addr != NULL) |
189 | panic("fault_addr set but no fault catcher"); | 189 | panic("fault_addr set but no fault catcher"); |
190 | else if(!is_user && arch_fixup(ip, sc)) | 190 | else if(!is_user && arch_fixup(ip, sc)) |
191 | return(0); | 191 | return(0); |
192 | 192 | ||
193 | if(!is_user) | 193 | if(!is_user) |
194 | panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", | 194 | panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", |
195 | address, ip); | 195 | address, ip); |
196 | 196 | ||
197 | if (err == -EACCES) { | 197 | if (err == -EACCES) { |
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c index 5c1e4cc1c049..ad66df17d9d7 100644 --- a/arch/um/kernel/tt/exec_kern.c +++ b/arch/um/kernel/tt/exec_kern.c | |||
@@ -21,7 +21,7 @@ | |||
21 | static int exec_tramp(void *sig_stack) | 21 | static int exec_tramp(void *sig_stack) |
22 | { | 22 | { |
23 | init_new_thread_stack(sig_stack, NULL); | 23 | init_new_thread_stack(sig_stack, NULL); |
24 | init_new_thread_signals(1); | 24 | init_new_thread_signals(); |
25 | os_stop_process(os_getpid()); | 25 | os_stop_process(os_getpid()); |
26 | return(0); | 26 | return(0); |
27 | } | 27 | } |
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c index bcb8796c3cb1..84a23b14f770 100644 --- a/arch/um/kernel/tt/mem.c +++ b/arch/um/kernel/tt/mem.c | |||
@@ -24,22 +24,13 @@ void before_mem_tt(unsigned long brk_start) | |||
24 | #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) | 24 | #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) |
25 | #define START (CONFIG_TOP_ADDR - SIZE) | 25 | #define START (CONFIG_TOP_ADDR - SIZE) |
26 | 26 | ||
27 | unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, | 27 | unsigned long set_task_sizes_tt(unsigned long *task_size_out) |
28 | unsigned long *task_size_out) | ||
29 | { | 28 | { |
29 | unsigned long host_task_size; | ||
30 | |||
30 | /* Round up to the nearest 4M */ | 31 | /* Round up to the nearest 4M */ |
31 | *host_size_out = ROUND_4M((unsigned long) &arg); | 32 | host_task_size = ROUND_4M((unsigned long) &host_task_size); |
32 | *task_size_out = START; | 33 | *task_size_out = START; |
33 | return(START); | ||
34 | } | ||
35 | 34 | ||
36 | /* | 35 | return host_task_size; |
37 | * Overrides for Emacs so that we follow Linus's tabbing style. | 36 | } |
38 | * Emacs will notice this stuff at the end of the file and automatically | ||
39 | * adjust the settings for this buffer only. This must remain at the end | ||
40 | * of the file. | ||
41 | * --------------------------------------------------------------------------- | ||
42 | * Local variables: | ||
43 | * c-file-style: "linux" | ||
44 | * End: | ||
45 | */ | ||
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index 8368c2dbe635..1e86f0bfef72 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -142,7 +142,7 @@ static void new_thread_handler(int sig) | |||
142 | schedule_tail(current->thread.prev_sched); | 142 | schedule_tail(current->thread.prev_sched); |
143 | current->thread.prev_sched = NULL; | 143 | current->thread.prev_sched = NULL; |
144 | 144 | ||
145 | init_new_thread_signals(1); | 145 | init_new_thread_signals(); |
146 | enable_timer(); | 146 | enable_timer(); |
147 | free_page(current->thread.temp_stack); | 147 | free_page(current->thread.temp_stack); |
148 | set_cmdline("(kernel thread)"); | 148 | set_cmdline("(kernel thread)"); |
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c index 3fda9a03c59a..293caa6d0c2d 100644 --- a/arch/um/kernel/tt/syscall_kern.c +++ b/arch/um/kernel/tt/syscall_kern.c | |||
@@ -21,18 +21,11 @@ void syscall_handler_tt(int sig, struct pt_regs *regs) | |||
21 | void *sc; | 21 | void *sc; |
22 | long result; | 22 | long result; |
23 | int syscall; | 23 | int syscall; |
24 | #ifdef CONFIG_SYSCALL_DEBUG | 24 | |
25 | int index; | ||
26 | #endif | ||
27 | sc = UPT_SC(®s->regs); | 25 | sc = UPT_SC(®s->regs); |
28 | SC_START_SYSCALL(sc); | 26 | SC_START_SYSCALL(sc); |
29 | 27 | ||
30 | syscall = UPT_SYSCALL_NR(®s->regs); | 28 | syscall = UPT_SYSCALL_NR(®s->regs); |
31 | |||
32 | #ifdef CONFIG_SYSCALL_DEBUG | ||
33 | index = record_syscall_start(syscall); | ||
34 | #endif | ||
35 | |||
36 | syscall_trace(®s->regs, 0); | 29 | syscall_trace(®s->regs, 0); |
37 | 30 | ||
38 | current->thread.nsyscalls++; | 31 | current->thread.nsyscalls++; |
@@ -50,7 +43,4 @@ void syscall_handler_tt(int sig, struct pt_regs *regs) | |||
50 | SC_SET_SYSCALL_RETURN(sc, result); | 43 | SC_SET_SYSCALL_RETURN(sc, result); |
51 | 44 | ||
52 | syscall_trace(®s->regs, 1); | 45 | syscall_trace(®s->regs, 1); |
53 | #ifdef CONFIG_SYSCALL_DEBUG | ||
54 | record_syscall_end(index, result); | ||
55 | #endif | ||
56 | } | 46 | } |
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 71daae24e48a..9882342206ec 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c | |||
@@ -188,10 +188,7 @@ int tracer(int (*init_proc)(void *), void *sp) | |||
188 | int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; | 188 | int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; |
189 | int proc_id = 0, n, err, old_tracing = 0, strace = 0; | 189 | int proc_id = 0, n, err, old_tracing = 0, strace = 0; |
190 | int local_using_sysemu = 0; | 190 | int local_using_sysemu = 0; |
191 | #ifdef UML_CONFIG_SYSCALL_DEBUG | 191 | |
192 | unsigned long eip = 0; | ||
193 | int last_index; | ||
194 | #endif | ||
195 | signal(SIGPIPE, SIG_IGN); | 192 | signal(SIGPIPE, SIG_IGN); |
196 | setup_tracer_winch(); | 193 | setup_tracer_winch(); |
197 | tracing_pid = os_getpid(); | 194 | tracing_pid = os_getpid(); |
@@ -282,23 +279,6 @@ int tracer(int (*init_proc)(void *), void *sp) | |||
282 | else if(WIFSTOPPED(status)){ | 279 | else if(WIFSTOPPED(status)){ |
283 | proc_id = pid_to_processor_id(pid); | 280 | proc_id = pid_to_processor_id(pid); |
284 | sig = WSTOPSIG(status); | 281 | sig = WSTOPSIG(status); |
285 | #ifdef UML_CONFIG_SYSCALL_DEBUG | ||
286 | if(signal_index[proc_id] == 1024){ | ||
287 | signal_index[proc_id] = 0; | ||
288 | last_index = 1023; | ||
289 | } | ||
290 | else last_index = signal_index[proc_id] - 1; | ||
291 | if(((sig == SIGPROF) || (sig == SIGVTALRM) || | ||
292 | (sig == SIGALRM)) && | ||
293 | (signal_record[proc_id][last_index].signal == sig)&& | ||
294 | (signal_record[proc_id][last_index].pid == pid)) | ||
295 | signal_index[proc_id] = last_index; | ||
296 | signal_record[proc_id][signal_index[proc_id]].pid = pid; | ||
297 | gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL); | ||
298 | eip = ptrace(PTRACE_PEEKUSR, pid, PT_IP_OFFSET, 0); | ||
299 | signal_record[proc_id][signal_index[proc_id]].addr = eip; | ||
300 | signal_record[proc_id][signal_index[proc_id]++].signal = sig; | ||
301 | #endif | ||
302 | if(proc_id == -1){ | 282 | if(proc_id == -1){ |
303 | sleeping_process_signal(pid, sig); | 283 | sleeping_process_signal(pid, sig); |
304 | continue; | 284 | continue; |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 37cfe7701f06..7896cf98232d 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -330,6 +330,8 @@ EXPORT_SYMBOL(end_iomem); | |||
330 | 330 | ||
331 | #define MIN_VMALLOC (32 * 1024 * 1024) | 331 | #define MIN_VMALLOC (32 * 1024 * 1024) |
332 | 332 | ||
333 | extern char __binary_start; | ||
334 | |||
333 | int linux_main(int argc, char **argv) | 335 | int linux_main(int argc, char **argv) |
334 | { | 336 | { |
335 | unsigned long avail, diff; | 337 | unsigned long avail, diff; |
@@ -374,8 +376,9 @@ int linux_main(int argc, char **argv) | |||
374 | 376 | ||
375 | printf("UML running in %s mode\n", mode); | 377 | printf("UML running in %s mode\n", mode); |
376 | 378 | ||
377 | uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, | 379 | uml_start = (unsigned long) &__binary_start; |
378 | &host_task_size, &task_size); | 380 | host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, |
381 | set_task_sizes_skas, &task_size); | ||
379 | 382 | ||
380 | /* | 383 | /* |
381 | * Setting up handlers to 'sig_info' struct | 384 | * Setting up handlers to 'sig_info' struct |
@@ -395,7 +398,7 @@ int linux_main(int argc, char **argv) | |||
395 | physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); | 398 | physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); |
396 | } | 399 | } |
397 | 400 | ||
398 | uml_physmem = uml_start; | 401 | uml_physmem = uml_start & PAGE_MASK; |
399 | 402 | ||
400 | /* Reserve up to 4M after the current brk */ | 403 | /* Reserve up to 4M after the current brk */ |
401 | uml_reserved = ROUND_4M(brk_start) + (1 << 22); | 404 | uml_reserved = ROUND_4M(brk_start) + (1 << 22); |
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index af11915ce0a8..8eca47a6ff08 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S | |||
@@ -7,13 +7,16 @@ jiffies = jiffies_64; | |||
7 | 7 | ||
8 | SECTIONS | 8 | SECTIONS |
9 | { | 9 | { |
10 | /*This must contain the right address - not quite the default ELF one.*/ | 10 | /* This must contain the right address - not quite the default ELF one.*/ |
11 | PROVIDE (__executable_start = START); | 11 | PROVIDE (__executable_start = START); |
12 | . = START + SIZEOF_HEADERS; | 12 | /* Static binaries stick stuff here, like the sigreturn trampoline, |
13 | * invisibly to objdump. So, just make __binary_start equal to the very | ||
14 | * beginning of the executable, and if there are unmapped pages after this, | ||
15 | * they are forever unusable. | ||
16 | */ | ||
17 | __binary_start = START; | ||
13 | 18 | ||
14 | /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start | 19 | . = START + SIZEOF_HEADERS; |
15 | * is remapped.*/ | ||
16 | __binary_start = .; | ||
17 | 20 | ||
18 | #ifdef MODE_TT | 21 | #ifdef MODE_TT |
19 | .remap_data : { UNMAP_PATH (.data .bss) } | 22 | .remap_data : { UNMAP_PATH (.data .bss) } |
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index 72acdce205e0..f8aeb448aab6 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S | |||
@@ -1,5 +1,3 @@ | |||
1 | /* in case the preprocessor is a 32bit one */ | ||
2 | #undef i386 | ||
3 | #ifdef CONFIG_LD_SCRIPT_STATIC | 1 | #ifdef CONFIG_LD_SCRIPT_STATIC |
4 | #include "uml.lds.S" | 2 | #include "uml.lds.S" |
5 | #else | 3 | #else |
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 09251338d99e..189fa677085a 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c | |||
@@ -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 | */ |
@@ -18,6 +18,7 @@ | |||
18 | #include "os.h" | 18 | #include "os.h" |
19 | #include "user.h" | 19 | #include "user.h" |
20 | #include "kern_util.h" | 20 | #include "kern_util.h" |
21 | #include "user_util.h" | ||
21 | 22 | ||
22 | static void copy_stat(struct uml_stat *dst, struct stat64 *src) | 23 | static void copy_stat(struct uml_stat *dst, struct stat64 *src) |
23 | { | 24 | { |
@@ -42,16 +43,13 @@ int os_stat_fd(const int fd, struct uml_stat *ubuf) | |||
42 | struct stat64 sbuf; | 43 | struct stat64 sbuf; |
43 | int err; | 44 | int err; |
44 | 45 | ||
45 | do { | 46 | CATCH_EINTR(err = fstat64(fd, &sbuf)); |
46 | err = fstat64(fd, &sbuf); | ||
47 | } while((err < 0) && (errno == EINTR)) ; | ||
48 | |||
49 | if(err < 0) | 47 | if(err < 0) |
50 | return(-errno); | 48 | return -errno; |
51 | 49 | ||
52 | if(ubuf != NULL) | 50 | if(ubuf != NULL) |
53 | copy_stat(ubuf, &sbuf); | 51 | copy_stat(ubuf, &sbuf); |
54 | return(err); | 52 | return err; |
55 | } | 53 | } |
56 | 54 | ||
57 | int os_stat_file(const char *file_name, struct uml_stat *ubuf) | 55 | int os_stat_file(const char *file_name, struct uml_stat *ubuf) |
@@ -64,11 +62,11 @@ int os_stat_file(const char *file_name, struct uml_stat *ubuf) | |||
64 | } while((err < 0) && (errno == EINTR)) ; | 62 | } while((err < 0) && (errno == EINTR)) ; |
65 | 63 | ||
66 | if(err < 0) | 64 | if(err < 0) |
67 | return(-errno); | 65 | return -errno; |
68 | 66 | ||
69 | if(ubuf != NULL) | 67 | if(ubuf != NULL) |
70 | copy_stat(ubuf, &sbuf); | 68 | copy_stat(ubuf, &sbuf); |
71 | return(err); | 69 | return err; |
72 | } | 70 | } |
73 | 71 | ||
74 | int os_access(const char* file, int mode) | 72 | int os_access(const char* file, int mode) |
@@ -80,9 +78,9 @@ int os_access(const char* file, int mode) | |||
80 | 78 | ||
81 | err = access(file, amode); | 79 | err = access(file, amode); |
82 | if(err < 0) | 80 | if(err < 0) |
83 | return(-errno); | 81 | return -errno; |
84 | 82 | ||
85 | return(0); | 83 | return 0; |
86 | } | 84 | } |
87 | 85 | ||
88 | void os_print_error(int error, const char* str) | 86 | void os_print_error(int error, const char* str) |
@@ -99,9 +97,9 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) | |||
99 | 97 | ||
100 | err = ioctl(fd, cmd, arg); | 98 | err = ioctl(fd, cmd, arg); |
101 | if(err < 0) | 99 | if(err < 0) |
102 | return(-errno); | 100 | return -errno; |
103 | 101 | ||
104 | return(err); | 102 | return err; |
105 | } | 103 | } |
106 | 104 | ||
107 | int os_window_size(int fd, int *rows, int *cols) | 105 | int os_window_size(int fd, int *rows, int *cols) |
@@ -109,12 +107,12 @@ int os_window_size(int fd, int *rows, int *cols) | |||
109 | struct winsize size; | 107 | struct winsize size; |
110 | 108 | ||
111 | if(ioctl(fd, TIOCGWINSZ, &size) < 0) | 109 | if(ioctl(fd, TIOCGWINSZ, &size) < 0) |
112 | return(-errno); | 110 | return -errno; |
113 | 111 | ||
114 | *rows = size.ws_row; | 112 | *rows = size.ws_row; |
115 | *cols = size.ws_col; | 113 | *cols = size.ws_col; |
116 | 114 | ||
117 | return(0); | 115 | return 0; |
118 | } | 116 | } |
119 | 117 | ||
120 | int os_new_tty_pgrp(int fd, int pid) | 118 | int os_new_tty_pgrp(int fd, int pid) |
@@ -125,16 +123,16 @@ int os_new_tty_pgrp(int fd, int pid) | |||
125 | if(tcsetpgrp(fd, pid) < 0) | 123 | if(tcsetpgrp(fd, pid) < 0) |
126 | return -errno; | 124 | return -errno; |
127 | 125 | ||
128 | return(0); | 126 | return 0; |
129 | } | 127 | } |
130 | 128 | ||
131 | /* FIXME: ensure namebuf in os_get_if_name is big enough */ | 129 | /* FIXME: ensure namebuf in os_get_if_name is big enough */ |
132 | int os_get_ifname(int fd, char* namebuf) | 130 | int os_get_ifname(int fd, char* namebuf) |
133 | { | 131 | { |
134 | if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) | 132 | if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) |
135 | return(-errno); | 133 | return -errno; |
136 | 134 | ||
137 | return(0); | 135 | return 0; |
138 | } | 136 | } |
139 | 137 | ||
140 | int os_set_slip(int fd) | 138 | int os_set_slip(int fd) |
@@ -149,7 +147,7 @@ int os_set_slip(int fd) | |||
149 | if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0) | 147 | if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0) |
150 | return -errno; | 148 | return -errno; |
151 | 149 | ||
152 | return(0); | 150 | return 0; |
153 | } | 151 | } |
154 | 152 | ||
155 | int os_set_owner(int fd, int pid) | 153 | int os_set_owner(int fd, int pid) |
@@ -158,10 +156,10 @@ int os_set_owner(int fd, int pid) | |||
158 | int save_errno = errno; | 156 | int save_errno = errno; |
159 | 157 | ||
160 | if(fcntl(fd, F_GETOWN, 0) != pid) | 158 | if(fcntl(fd, F_GETOWN, 0) != pid) |
161 | return(-save_errno); | 159 | return -save_errno; |
162 | } | 160 | } |
163 | 161 | ||
164 | return(0); | 162 | return 0; |
165 | } | 163 | } |
166 | 164 | ||
167 | /* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ | 165 | /* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ |
@@ -192,9 +190,9 @@ int os_mode_fd(int fd, int mode) | |||
192 | } while((err < 0) && (errno==EINTR)) ; | 190 | } while((err < 0) && (errno==EINTR)) ; |
193 | 191 | ||
194 | if(err < 0) | 192 | if(err < 0) |
195 | return(-errno); | 193 | return -errno; |
196 | 194 | ||
197 | return(0); | 195 | return 0; |
198 | } | 196 | } |
199 | 197 | ||
200 | int os_file_type(char *file) | 198 | int os_file_type(char *file) |
@@ -204,15 +202,21 @@ int os_file_type(char *file) | |||
204 | 202 | ||
205 | err = os_stat_file(file, &buf); | 203 | err = os_stat_file(file, &buf); |
206 | if(err < 0) | 204 | if(err < 0) |
207 | return(err); | 205 | return err; |
208 | 206 | ||
209 | if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR); | 207 | if(S_ISDIR(buf.ust_mode)) |
210 | else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK); | 208 | return OS_TYPE_DIR; |
211 | else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV); | 209 | else if(S_ISLNK(buf.ust_mode)) |
212 | else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV); | 210 | return OS_TYPE_SYMLINK; |
213 | else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO); | 211 | else if(S_ISCHR(buf.ust_mode)) |
214 | else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK); | 212 | return OS_TYPE_CHARDEV; |
215 | else return(OS_TYPE_FILE); | 213 | else if(S_ISBLK(buf.ust_mode)) |
214 | return OS_TYPE_BLOCKDEV; | ||
215 | else if(S_ISFIFO(buf.ust_mode)) | ||
216 | return OS_TYPE_FIFO; | ||
217 | else if(S_ISSOCK(buf.ust_mode)) | ||
218 | return OS_TYPE_SOCK; | ||
219 | else return OS_TYPE_FILE; | ||
216 | } | 220 | } |
217 | 221 | ||
218 | int os_file_mode(char *file, struct openflags *mode_out) | 222 | int os_file_mode(char *file, struct openflags *mode_out) |
@@ -302,8 +306,8 @@ int os_seek_file(int fd, __u64 offset) | |||
302 | 306 | ||
303 | actual = lseek64(fd, offset, SEEK_SET); | 307 | actual = lseek64(fd, offset, SEEK_SET); |
304 | if(actual != offset) | 308 | if(actual != offset) |
305 | return(-errno); | 309 | return -errno; |
306 | return(0); | 310 | return 0; |
307 | } | 311 | } |
308 | 312 | ||
309 | static int fault_buffer(void *start, int len, | 313 | static int fault_buffer(void *start, int len, |
@@ -314,13 +318,13 @@ static int fault_buffer(void *start, int len, | |||
314 | 318 | ||
315 | for(i = 0; i < len; i += page){ | 319 | for(i = 0; i < len; i += page){ |
316 | if((*copy_proc)(start + i, &c, sizeof(c))) | 320 | if((*copy_proc)(start + i, &c, sizeof(c))) |
317 | return(-EFAULT); | 321 | return -EFAULT; |
318 | } | 322 | } |
319 | if((len % page) != 0){ | 323 | if((len % page) != 0){ |
320 | if((*copy_proc)(start + len - 1, &c, sizeof(c))) | 324 | if((*copy_proc)(start + len - 1, &c, sizeof(c))) |
321 | return(-EFAULT); | 325 | return -EFAULT; |
322 | } | 326 | } |
323 | return(0); | 327 | return 0; |
324 | } | 328 | } |
325 | 329 | ||
326 | static int file_io(int fd, void *buf, int len, | 330 | static int file_io(int fd, void *buf, int len, |
@@ -334,26 +338,26 @@ static int file_io(int fd, void *buf, int len, | |||
334 | if((n < 0) && (errno == EFAULT)){ | 338 | if((n < 0) && (errno == EFAULT)){ |
335 | err = fault_buffer(buf, len, copy_user_proc); | 339 | err = fault_buffer(buf, len, copy_user_proc); |
336 | if(err) | 340 | if(err) |
337 | return(err); | 341 | return err; |
338 | n = (*io_proc)(fd, buf, len); | 342 | n = (*io_proc)(fd, buf, len); |
339 | } | 343 | } |
340 | } while((n < 0) && (errno == EINTR)); | 344 | } while((n < 0) && (errno == EINTR)); |
341 | 345 | ||
342 | if(n < 0) | 346 | if(n < 0) |
343 | return(-errno); | 347 | return -errno; |
344 | return(n); | 348 | return n; |
345 | } | 349 | } |
346 | 350 | ||
347 | int os_read_file(int fd, void *buf, int len) | 351 | int os_read_file(int fd, void *buf, int len) |
348 | { | 352 | { |
349 | return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, | 353 | return file_io(fd, buf, len, (int (*)(int, void *, int)) read, |
350 | copy_from_user_proc)); | 354 | copy_from_user_proc); |
351 | } | 355 | } |
352 | 356 | ||
353 | int os_write_file(int fd, const void *buf, int len) | 357 | int os_write_file(int fd, const void *buf, int len) |
354 | { | 358 | { |
355 | return(file_io(fd, (void *) buf, len, | 359 | return file_io(fd, (void *) buf, len, |
356 | (int (*)(int, void *, int)) write, copy_to_user_proc)); | 360 | (int (*)(int, void *, int)) write, copy_to_user_proc); |
357 | } | 361 | } |
358 | 362 | ||
359 | int os_file_size(char *file, unsigned long long *size_out) | 363 | int os_file_size(char *file, unsigned long long *size_out) |
@@ -398,11 +402,11 @@ int os_file_modtime(char *file, unsigned long *modtime) | |||
398 | err = os_stat_file(file, &buf); | 402 | err = os_stat_file(file, &buf); |
399 | if(err < 0){ | 403 | if(err < 0){ |
400 | printk("Couldn't stat \"%s\" : err = %d\n", file, -err); | 404 | printk("Couldn't stat \"%s\" : err = %d\n", file, -err); |
401 | return(err); | 405 | return err; |
402 | } | 406 | } |
403 | 407 | ||
404 | *modtime = buf.ust_mtime; | 408 | *modtime = buf.ust_mtime; |
405 | return(0); | 409 | return 0; |
406 | } | 410 | } |
407 | 411 | ||
408 | int os_get_exec_close(int fd, int* close_on_exec) | 412 | int os_get_exec_close(int fd, int* close_on_exec) |
@@ -455,7 +459,7 @@ int os_pipe(int *fds, int stream, int close_on_exec) | |||
455 | if(err < 0) | 459 | if(err < 0) |
456 | goto error; | 460 | goto error; |
457 | 461 | ||
458 | return(0); | 462 | return 0; |
459 | 463 | ||
460 | error: | 464 | error: |
461 | printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); | 465 | printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); |
@@ -486,12 +490,12 @@ int os_set_fd_async(int fd, int owner) | |||
486 | (fcntl(fd, F_SETOWN, owner) < 0)){ | 490 | (fcntl(fd, F_SETOWN, owner) < 0)){ |
487 | err = -errno; | 491 | err = -errno; |
488 | printk("os_set_fd_async : Failed to fcntl F_SETOWN " | 492 | printk("os_set_fd_async : Failed to fcntl F_SETOWN " |
489 | "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, | 493 | "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, |
490 | owner, errno); | 494 | owner, errno); |
491 | return err; | 495 | return err; |
492 | } | 496 | } |
493 | 497 | ||
494 | return(0); | 498 | return 0; |
495 | } | 499 | } |
496 | 500 | ||
497 | int os_clear_fd_async(int fd) | 501 | int os_clear_fd_async(int fd) |
@@ -500,8 +504,8 @@ int os_clear_fd_async(int fd) | |||
500 | 504 | ||
501 | flags &= ~(O_ASYNC | O_NONBLOCK); | 505 | flags &= ~(O_ASYNC | O_NONBLOCK); |
502 | if(fcntl(fd, F_SETFL, flags) < 0) | 506 | if(fcntl(fd, F_SETFL, flags) < 0) |
503 | return(-errno); | 507 | return -errno; |
504 | return(0); | 508 | return 0; |
505 | } | 509 | } |
506 | 510 | ||
507 | int os_set_fd_block(int fd, int blocking) | 511 | int os_set_fd_block(int fd, int blocking) |
@@ -516,7 +520,7 @@ int os_set_fd_block(int fd, int blocking) | |||
516 | if(fcntl(fd, F_SETFL, flags) < 0) | 520 | if(fcntl(fd, F_SETFL, flags) < 0) |
517 | return -errno; | 521 | return -errno; |
518 | 522 | ||
519 | return(0); | 523 | return 0; |
520 | } | 524 | } |
521 | 525 | ||
522 | int os_accept_connection(int fd) | 526 | int os_accept_connection(int fd) |
@@ -524,9 +528,9 @@ int os_accept_connection(int fd) | |||
524 | int new; | 528 | int new; |
525 | 529 | ||
526 | new = accept(fd, NULL, 0); | 530 | new = accept(fd, NULL, 0); |
527 | if(new < 0) | 531 | if(new < 0) |
528 | return(-errno); | 532 | return -errno; |
529 | return(new); | 533 | return new; |
530 | } | 534 | } |
531 | 535 | ||
532 | #ifndef SHUT_RD | 536 | #ifndef SHUT_RD |
@@ -550,12 +554,12 @@ int os_shutdown_socket(int fd, int r, int w) | |||
550 | else if(w) what = SHUT_WR; | 554 | else if(w) what = SHUT_WR; |
551 | else { | 555 | else { |
552 | printk("os_shutdown_socket : neither r or w was set\n"); | 556 | printk("os_shutdown_socket : neither r or w was set\n"); |
553 | return(-EINVAL); | 557 | return -EINVAL; |
554 | } | 558 | } |
555 | err = shutdown(fd, what); | 559 | err = shutdown(fd, what); |
556 | if(err < 0) | 560 | if(err < 0) |
557 | return(-errno); | 561 | return -errno; |
558 | return(0); | 562 | return 0; |
559 | } | 563 | } |
560 | 564 | ||
561 | int os_rcv_fd(int fd, int *helper_pid_out) | 565 | int os_rcv_fd(int fd, int *helper_pid_out) |
@@ -578,7 +582,7 @@ int os_rcv_fd(int fd, int *helper_pid_out) | |||
578 | 582 | ||
579 | n = recvmsg(fd, &msg, 0); | 583 | n = recvmsg(fd, &msg, 0); |
580 | if(n < 0) | 584 | if(n < 0) |
581 | return(-errno); | 585 | return -errno; |
582 | 586 | ||
583 | else if(n != sizeof(iov.iov_len)) | 587 | else if(n != sizeof(iov.iov_len)) |
584 | *helper_pid_out = -1; | 588 | *helper_pid_out = -1; |
@@ -586,16 +590,16 @@ int os_rcv_fd(int fd, int *helper_pid_out) | |||
586 | cmsg = CMSG_FIRSTHDR(&msg); | 590 | cmsg = CMSG_FIRSTHDR(&msg); |
587 | if(cmsg == NULL){ | 591 | if(cmsg == NULL){ |
588 | printk("rcv_fd didn't receive anything, error = %d\n", errno); | 592 | printk("rcv_fd didn't receive anything, error = %d\n", errno); |
589 | return(-1); | 593 | return -1; |
590 | } | 594 | } |
591 | if((cmsg->cmsg_level != SOL_SOCKET) || | 595 | if((cmsg->cmsg_level != SOL_SOCKET) || |
592 | (cmsg->cmsg_type != SCM_RIGHTS)){ | 596 | (cmsg->cmsg_type != SCM_RIGHTS)){ |
593 | printk("rcv_fd didn't receive a descriptor\n"); | 597 | printk("rcv_fd didn't receive a descriptor\n"); |
594 | return(-1); | 598 | return -1; |
595 | } | 599 | } |
596 | 600 | ||
597 | new = ((int *) CMSG_DATA(cmsg))[0]; | 601 | new = ((int *) CMSG_DATA(cmsg))[0]; |
598 | return(new); | 602 | return new; |
599 | } | 603 | } |
600 | 604 | ||
601 | int os_create_unix_socket(char *file, int len, int close_on_exec) | 605 | int os_create_unix_socket(char *file, int len, int close_on_exec) |
@@ -623,7 +627,7 @@ int os_create_unix_socket(char *file, int len, int close_on_exec) | |||
623 | if(err < 0) | 627 | if(err < 0) |
624 | return -errno; | 628 | return -errno; |
625 | 629 | ||
626 | return(sock); | 630 | return sock; |
627 | } | 631 | } |
628 | 632 | ||
629 | void os_flush_stdout(void) | 633 | void os_flush_stdout(void) |
@@ -654,16 +658,5 @@ int os_lock_file(int fd, int excl) | |||
654 | printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); | 658 | printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); |
655 | err = save; | 659 | err = save; |
656 | out: | 660 | out: |
657 | return(err); | 661 | return err; |
658 | } | 662 | } |
659 | |||
660 | /* | ||
661 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
662 | * Emacs will notice this stuff at the end of the file and automatically | ||
663 | * adjust the settings for this buffer only. This must remain at the end | ||
664 | * of the file. | ||
665 | * --------------------------------------------------------------------------- | ||
666 | * Local variables: | ||
667 | * c-file-style: "linux" | ||
668 | * End: | ||
669 | */ | ||
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index 3788d4568d33..7555bf9c33d9 100644 --- a/arch/um/os-Linux/irq.c +++ b/arch/um/os-Linux/irq.c | |||
@@ -52,11 +52,6 @@ int os_waiting_for_events(struct irq_fd *active_fds) | |||
52 | return n; | 52 | return n; |
53 | } | 53 | } |
54 | 54 | ||
55 | int os_isatty(int fd) | ||
56 | { | ||
57 | return isatty(fd); | ||
58 | } | ||
59 | |||
60 | int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) | 55 | int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds) |
61 | { | 56 | { |
62 | if (pollfds_num == pollfds_size) { | 57 | if (pollfds_num == pollfds_size) { |
@@ -142,17 +137,14 @@ void os_set_ioignore(void) | |||
142 | 137 | ||
143 | void init_irq_signals(int on_sigstack) | 138 | void init_irq_signals(int on_sigstack) |
144 | { | 139 | { |
145 | __sighandler_t h; | ||
146 | int flags; | 140 | int flags; |
147 | 141 | ||
148 | flags = on_sigstack ? SA_ONSTACK : 0; | 142 | flags = on_sigstack ? SA_ONSTACK : 0; |
149 | if (timer_irq_inited) | ||
150 | h = (__sighandler_t)alarm_handler; | ||
151 | else | ||
152 | h = boot_timer_handler; | ||
153 | 143 | ||
154 | set_handler(SIGVTALRM, h, flags | SA_RESTART, | 144 | set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, |
155 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); | 145 | flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); |
146 | set_handler(SIGALRM, (__sighandler_t) alarm_handler, | ||
147 | flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); | ||
156 | set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, | 148 | set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, |
157 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 149 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
158 | signal(SIGWINCH, SIG_IGN); | 150 | signal(SIGWINCH, SIG_IGN); |
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 233be2f4f8cb..b98d3ca2cd1b 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -250,36 +250,35 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) | |||
250 | if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); | 250 | if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); |
251 | } | 251 | } |
252 | 252 | ||
253 | void init_new_thread_signals(int altstack) | 253 | void init_new_thread_signals(void) |
254 | { | 254 | { |
255 | int flags = altstack ? SA_ONSTACK : 0; | 255 | set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, |
256 | |||
257 | set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags, | ||
258 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 256 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
259 | set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, | 257 | set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, |
260 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 258 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
261 | set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, | 259 | set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, |
262 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 260 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
263 | set_handler(SIGILL, (__sighandler_t) sig_handler, flags, | 261 | set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, |
264 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 262 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
265 | set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, | 263 | set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, |
266 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 264 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
267 | set_handler(SIGUSR2, (__sighandler_t) sig_handler, | 265 | set_handler(SIGUSR2, (__sighandler_t) sig_handler, |
268 | flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 266 | SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, |
267 | -1); | ||
269 | signal(SIGHUP, SIG_IGN); | 268 | signal(SIGHUP, SIG_IGN); |
270 | 269 | ||
271 | init_irq_signals(altstack); | 270 | init_irq_signals(1); |
272 | } | 271 | } |
273 | 272 | ||
274 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 273 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) |
275 | { | 274 | { |
276 | jmp_buf buf; | 275 | jmp_buf buf; |
277 | int n, enable; | 276 | int n; |
278 | 277 | ||
279 | *jmp_ptr = &buf; | 278 | *jmp_ptr = &buf; |
280 | n = UML_SETJMP(&buf, enable); | 279 | n = UML_SETJMP(&buf); |
281 | if(n != 0) | 280 | if(n != 0) |
282 | return(n); | 281 | return n; |
283 | (*fn)(arg); | 282 | (*fn)(arg); |
284 | return(0); | 283 | return 0; |
285 | } | 284 | } |
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c index 00e9388e947a..0ecac563c7b3 100644 --- a/arch/um/os-Linux/sigio.c +++ b/arch/um/os-Linux/sigio.c | |||
@@ -43,13 +43,13 @@ struct pollfds { | |||
43 | /* Protected by sigio_lock(). Used by the sigio thread, but the UML thread | 43 | /* Protected by sigio_lock(). Used by the sigio thread, but the UML thread |
44 | * synchronizes with it. | 44 | * synchronizes with it. |
45 | */ | 45 | */ |
46 | struct pollfds current_poll = { | 46 | static struct pollfds current_poll = { |
47 | .poll = NULL, | 47 | .poll = NULL, |
48 | .size = 0, | 48 | .size = 0, |
49 | .used = 0 | 49 | .used = 0 |
50 | }; | 50 | }; |
51 | 51 | ||
52 | struct pollfds next_poll = { | 52 | static struct pollfds next_poll = { |
53 | .poll = NULL, | 53 | .poll = NULL, |
54 | .size = 0, | 54 | .size = 0, |
55 | .used = 0 | 55 | .used = 0 |
@@ -156,7 +156,7 @@ static void update_thread(void) | |||
156 | set_signals(flags); | 156 | set_signals(flags); |
157 | } | 157 | } |
158 | 158 | ||
159 | int add_sigio_fd(int fd, int read) | 159 | static int add_sigio_fd(int fd, int read) |
160 | { | 160 | { |
161 | int err = 0, i, n, events; | 161 | int err = 0, i, n, events; |
162 | 162 | ||
@@ -191,6 +191,13 @@ int ignore_sigio_fd(int fd) | |||
191 | struct pollfd *p; | 191 | struct pollfd *p; |
192 | int err = 0, i, n = 0; | 192 | int err = 0, i, n = 0; |
193 | 193 | ||
194 | /* This is called from exitcalls elsewhere in UML - if | ||
195 | * sigio_cleanup has already run, then update_thread will hang | ||
196 | * or fail because the thread is no longer running. | ||
197 | */ | ||
198 | if(write_sigio_pid == -1) | ||
199 | return -EIO; | ||
200 | |||
194 | sigio_lock(); | 201 | sigio_lock(); |
195 | for(i = 0; i < current_poll.used; i++){ | 202 | for(i = 0; i < current_poll.used; i++){ |
196 | if(current_poll.poll[i].fd == fd) break; | 203 | if(current_poll.poll[i].fd == fd) break; |
@@ -215,7 +222,7 @@ int ignore_sigio_fd(int fd) | |||
215 | update_thread(); | 222 | update_thread(); |
216 | out: | 223 | out: |
217 | sigio_unlock(); | 224 | sigio_unlock(); |
218 | return(err); | 225 | return err; |
219 | } | 226 | } |
220 | 227 | ||
221 | static struct pollfd *setup_initial_poll(int fd) | 228 | static struct pollfd *setup_initial_poll(int fd) |
@@ -233,7 +240,7 @@ static struct pollfd *setup_initial_poll(int fd) | |||
233 | return p; | 240 | return p; |
234 | } | 241 | } |
235 | 242 | ||
236 | void write_sigio_workaround(void) | 243 | static void write_sigio_workaround(void) |
237 | { | 244 | { |
238 | unsigned long stack; | 245 | unsigned long stack; |
239 | struct pollfd *p; | 246 | struct pollfd *p; |
@@ -314,10 +321,24 @@ out_close1: | |||
314 | close(l_write_sigio_fds[1]); | 321 | close(l_write_sigio_fds[1]); |
315 | } | 322 | } |
316 | 323 | ||
317 | void sigio_cleanup(void) | 324 | void maybe_sigio_broken(int fd, int read) |
325 | { | ||
326 | if(!isatty(fd)) | ||
327 | return; | ||
328 | |||
329 | if((read || pty_output_sigio) && (!read || pty_close_sigio)) | ||
330 | return; | ||
331 | |||
332 | write_sigio_workaround(); | ||
333 | add_sigio_fd(fd, read); | ||
334 | } | ||
335 | |||
336 | static void sigio_cleanup(void) | ||
318 | { | 337 | { |
319 | if(write_sigio_pid != -1){ | 338 | if(write_sigio_pid != -1){ |
320 | os_kill_process(write_sigio_pid, 1); | 339 | os_kill_process(write_sigio_pid, 1); |
321 | write_sigio_pid = -1; | 340 | write_sigio_pid = -1; |
322 | } | 341 | } |
323 | } | 342 | } |
343 | |||
344 | __uml_exitcall(sigio_cleanup); | ||
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index f11b3124a0c8..60e4faedf254 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -106,29 +106,6 @@ void alarm_handler(ARCH_SIGHDLR_PARAM) | |||
106 | set_signals(enabled); | 106 | set_signals(enabled); |
107 | } | 107 | } |
108 | 108 | ||
109 | extern void do_boot_timer_handler(struct sigcontext * sc); | ||
110 | |||
111 | void boot_timer_handler(ARCH_SIGHDLR_PARAM) | ||
112 | { | ||
113 | struct sigcontext *sc; | ||
114 | int enabled; | ||
115 | |||
116 | ARCH_GET_SIGCONTEXT(sc, sig); | ||
117 | |||
118 | enabled = signals_enabled; | ||
119 | if(!enabled){ | ||
120 | if(sig == SIGVTALRM) | ||
121 | pending |= SIGVTALRM_MASK; | ||
122 | else pending |= SIGALRM_MASK; | ||
123 | return; | ||
124 | } | ||
125 | |||
126 | block_signals(); | ||
127 | |||
128 | do_boot_timer_handler(sc); | ||
129 | set_signals(enabled); | ||
130 | } | ||
131 | |||
132 | void set_sigstack(void *sig_stack, int size) | 109 | void set_sigstack(void *sig_stack, int size) |
133 | { | 110 | { |
134 | stack_t stack = ((stack_t) { .ss_flags = 0, | 111 | stack_t stack = ((stack_t) { .ss_flags = 0, |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index bd89c6b99d5d..7baf90fda58b 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -159,7 +159,7 @@ static int userspace_tramp(void *stack) | |||
159 | 159 | ||
160 | ptrace(PTRACE_TRACEME, 0, 0, 0); | 160 | ptrace(PTRACE_TRACEME, 0, 0, 0); |
161 | 161 | ||
162 | init_new_thread_signals(1); | 162 | init_new_thread_signals(); |
163 | enable_timer(); | 163 | enable_timer(); |
164 | 164 | ||
165 | if(!proc_mm){ | 165 | if(!proc_mm){ |
@@ -435,7 +435,6 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
435 | { | 435 | { |
436 | unsigned long flags; | 436 | unsigned long flags; |
437 | jmp_buf switch_buf, fork_buf; | 437 | jmp_buf switch_buf, fork_buf; |
438 | int enable; | ||
439 | 438 | ||
440 | *switch_buf_ptr = &switch_buf; | 439 | *switch_buf_ptr = &switch_buf; |
441 | *fork_buf_ptr = &fork_buf; | 440 | *fork_buf_ptr = &fork_buf; |
@@ -450,7 +449,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
450 | */ | 449 | */ |
451 | flags = get_signals(); | 450 | flags = get_signals(); |
452 | block_signals(); | 451 | block_signals(); |
453 | if(UML_SETJMP(&fork_buf, enable) == 0) | 452 | if(UML_SETJMP(&fork_buf) == 0) |
454 | new_thread_proc(stack, handler); | 453 | new_thread_proc(stack, handler); |
455 | 454 | ||
456 | remove_sigstack(); | 455 | remove_sigstack(); |
@@ -467,21 +466,19 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
467 | void thread_wait(void *sw, void *fb) | 466 | void thread_wait(void *sw, void *fb) |
468 | { | 467 | { |
469 | jmp_buf buf, **switch_buf = sw, *fork_buf; | 468 | jmp_buf buf, **switch_buf = sw, *fork_buf; |
470 | int enable; | ||
471 | 469 | ||
472 | *switch_buf = &buf; | 470 | *switch_buf = &buf; |
473 | fork_buf = fb; | 471 | fork_buf = fb; |
474 | if(UML_SETJMP(&buf, enable) == 0) | 472 | if(UML_SETJMP(&buf) == 0) |
475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | 473 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); |
476 | } | 474 | } |
477 | 475 | ||
478 | void switch_threads(void *me, void *next) | 476 | void switch_threads(void *me, void *next) |
479 | { | 477 | { |
480 | jmp_buf my_buf, **me_ptr = me, *next_buf = next; | 478 | jmp_buf my_buf, **me_ptr = me, *next_buf = next; |
481 | int enable; | ||
482 | 479 | ||
483 | *me_ptr = &my_buf; | 480 | *me_ptr = &my_buf; |
484 | if(UML_SETJMP(&my_buf, enable) == 0) | 481 | if(UML_SETJMP(&my_buf) == 0) |
485 | UML_LONGJMP(next_buf, 1); | 482 | UML_LONGJMP(next_buf, 1); |
486 | } | 483 | } |
487 | 484 | ||
@@ -495,14 +492,14 @@ static jmp_buf *cb_back; | |||
495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | 492 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) |
496 | { | 493 | { |
497 | jmp_buf **switch_buf = switch_buf_ptr; | 494 | jmp_buf **switch_buf = switch_buf_ptr; |
498 | int n, enable; | 495 | int n; |
499 | 496 | ||
500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | 497 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, |
501 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, | 498 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, |
502 | SIGVTALRM, -1); | 499 | SIGVTALRM, -1); |
503 | 500 | ||
504 | *fork_buf_ptr = &initial_jmpbuf; | 501 | *fork_buf_ptr = &initial_jmpbuf; |
505 | n = UML_SETJMP(&initial_jmpbuf, enable); | 502 | n = UML_SETJMP(&initial_jmpbuf); |
506 | switch(n){ | 503 | switch(n){ |
507 | case INIT_JMP_NEW_THREAD: | 504 | case INIT_JMP_NEW_THREAD: |
508 | new_thread_proc((void *) stack, new_thread_handler); | 505 | new_thread_proc((void *) stack, new_thread_handler); |
@@ -529,14 +526,13 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 526 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) |
530 | { | 527 | { |
531 | jmp_buf here; | 528 | jmp_buf here; |
532 | int enable; | ||
533 | 529 | ||
534 | cb_proc = proc; | 530 | cb_proc = proc; |
535 | cb_arg = arg; | 531 | cb_arg = arg; |
536 | cb_back = &here; | 532 | cb_back = &here; |
537 | 533 | ||
538 | block_signals(); | 534 | block_signals(); |
539 | if(UML_SETJMP(&here, enable) == 0) | 535 | if(UML_SETJMP(&here) == 0) |
540 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); | 536 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); |
541 | unblock_signals(); | 537 | unblock_signals(); |
542 | 538 | ||
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c index 280c4fb9b585..4ae73c0e5485 100644 --- a/arch/um/os-Linux/time.c +++ b/arch/um/os-Linux/time.c | |||
@@ -17,11 +17,6 @@ | |||
17 | #include "kern_constants.h" | 17 | #include "kern_constants.h" |
18 | #include "os.h" | 18 | #include "os.h" |
19 | 19 | ||
20 | /* XXX This really needs to be declared and initialized in a kernel file since | ||
21 | * it's in <linux/time.h> | ||
22 | */ | ||
23 | extern struct timespec wall_to_monotonic; | ||
24 | |||
25 | static void set_interval(int timer_type) | 20 | static void set_interval(int timer_type) |
26 | { | 21 | { |
27 | int usec = 1000000/hz(); | 22 | int usec = 1000000/hz(); |
@@ -71,6 +66,7 @@ void switch_timers(int to_real) | |||
71 | errno); | 66 | errno); |
72 | } | 67 | } |
73 | 68 | ||
69 | #ifdef UML_CONFIG_MODE_TT | ||
74 | void uml_idle_timer(void) | 70 | void uml_idle_timer(void) |
75 | { | 71 | { |
76 | if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) | 72 | if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) |
@@ -80,14 +76,7 @@ void uml_idle_timer(void) | |||
80 | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); | 76 | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); |
81 | set_interval(ITIMER_REAL); | 77 | set_interval(ITIMER_REAL); |
82 | } | 78 | } |
83 | 79 | #endif | |
84 | void time_init(void) | ||
85 | { | ||
86 | if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) | ||
87 | panic("Couldn't set SIGVTALRM handler"); | ||
88 | set_interval(ITIMER_VIRTUAL); | ||
89 | time_init_kern(); | ||
90 | } | ||
91 | 80 | ||
92 | unsigned long long os_nsecs(void) | 81 | unsigned long long os_nsecs(void) |
93 | { | 82 | { |
@@ -106,15 +95,7 @@ void idle_sleep(int secs) | |||
106 | nanosleep(&ts, NULL); | 95 | nanosleep(&ts, NULL); |
107 | } | 96 | } |
108 | 97 | ||
109 | /* XXX This partly duplicates init_irq_signals */ | ||
110 | |||
111 | void user_time_init(void) | 98 | void user_time_init(void) |
112 | { | 99 | { |
113 | set_handler(SIGVTALRM, (__sighandler_t) alarm_handler, | ||
114 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, | ||
115 | SIGALRM, SIGUSR2, -1); | ||
116 | set_handler(SIGALRM, (__sighandler_t) alarm_handler, | ||
117 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, | ||
118 | SIGVTALRM, SIGUSR2, -1); | ||
119 | set_interval(ITIMER_VIRTUAL); | 100 | set_interval(ITIMER_VIRTUAL); |
120 | } | 101 | } |
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index e523719330b2..865f6a6a2590 100644 --- a/arch/um/os-Linux/uaccess.c +++ b/arch/um/os-Linux/uaccess.c | |||
@@ -14,11 +14,10 @@ unsigned long __do_user_copy(void *to, const void *from, int n, | |||
14 | int n), int *faulted_out) | 14 | int n), int *faulted_out) |
15 | { | 15 | { |
16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; | 16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; |
17 | int enable; | ||
18 | 17 | ||
19 | jmp_buf jbuf; | 18 | jmp_buf jbuf; |
20 | *fault_catcher = &jbuf; | 19 | *fault_catcher = &jbuf; |
21 | if(UML_SETJMP(&jbuf, enable) == 0){ | 20 | if(UML_SETJMP(&jbuf) == 0){ |
22 | (*op)(to, from, n); | 21 | (*op)(to, from, n); |
23 | ret = 0; | 22 | ret = 0; |
24 | *faulted_out = 0; | 23 | *faulted_out = 0; |