aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-03-27 04:14:30 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:44:37 -0500
commit63ae2a94d98dd9d94163918539ec80df33f44a69 (patch)
treeebb7d6d0919fd5a8d3bac6c6a726f2f51f53f779 /arch/um
parentd9f8b62a6b033fe7226d7c2b2efdd164ca1aa07c (diff)
[PATCH] uml: move libc-dependent irq code to os-Linux
The serial UML OS-abstraction layer patch (um/kernel dir). This moves all systemcalls from irq_user.c file under os-Linux dir Signed-off-by: Gennady Sharapov <Gennady.V.Sharapov@intel.com> Signed-off-by: Jeff Dike <jdike@addtoit.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/include/irq_user.h15
-rw-r--r--arch/um/include/misc_constants.h6
-rw-r--r--arch/um/include/os.h16
-rw-r--r--arch/um/kernel/irq_user.c204
-rw-r--r--arch/um/kernel/smp.c14
-rw-r--r--arch/um/os-Linux/Makefile6
-rw-r--r--arch/um/os-Linux/irq.c162
-rw-r--r--arch/um/os-Linux/tt.c10
-rw-r--r--arch/um/sys-i386/user-offsets.c10
-rw-r--r--arch/um/sys-x86_64/user-offsets.c6
10 files changed, 288 insertions, 161 deletions
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index b61deb8b362a..69a93c804f0e 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -6,6 +6,17 @@
6#ifndef __IRQ_USER_H__ 6#ifndef __IRQ_USER_H__
7#define __IRQ_USER_H__ 7#define __IRQ_USER_H__
8 8
9struct irq_fd {
10 struct irq_fd *next;
11 void *id;
12 int fd;
13 int type;
14 int irq;
15 int pid;
16 int events;
17 int current_events;
18};
19
9enum { IRQ_READ, IRQ_WRITE }; 20enum { IRQ_READ, IRQ_WRITE };
10 21
11extern void sigio_handler(int sig, union uml_pt_regs *regs); 22extern void sigio_handler(int sig, union uml_pt_regs *regs);
@@ -16,8 +27,6 @@ extern void reactivate_fd(int fd, int irqnum);
16extern void deactivate_fd(int fd, int irqnum); 27extern void deactivate_fd(int fd, int irqnum);
17extern int deactivate_all_fds(void); 28extern int deactivate_all_fds(void);
18extern void forward_interrupts(int pid); 29extern void forward_interrupts(int pid);
19extern void init_irq_signals(int on_sigstack);
20extern void forward_ipi(int fd, int pid);
21extern int activate_ipi(int fd, int pid); 30extern int activate_ipi(int fd, int pid);
22extern unsigned long irq_lock(void); 31extern unsigned long irq_lock(void);
23extern void irq_unlock(unsigned long flags); 32extern void irq_unlock(unsigned long flags);
diff --git a/arch/um/include/misc_constants.h b/arch/um/include/misc_constants.h
new file mode 100644
index 000000000000..989bc08de36e
--- /dev/null
+++ b/arch/um/include/misc_constants.h
@@ -0,0 +1,6 @@
1#ifndef __MISC_CONSTANT_H_
2#define __MISC_CONSTANT_H_
3
4#include <user_constants.h>
5
6#endif
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 2a1c64d8d0bf..efae3e6acb5b 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -12,6 +12,7 @@
12#include "sysdep/ptrace.h" 12#include "sysdep/ptrace.h"
13#include "kern_util.h" 13#include "kern_util.h"
14#include "skas/mm_id.h" 14#include "skas/mm_id.h"
15#include "irq_user.h"
15 16
16#define OS_TYPE_FILE 1 17#define OS_TYPE_FILE 1
17#define OS_TYPE_DIR 2 18#define OS_TYPE_DIR 2
@@ -198,6 +199,8 @@ extern void os_flush_stdout(void);
198/* tt.c 199/* tt.c
199 * for tt mode only (will be deleted in future...) 200 * for tt mode only (will be deleted in future...)
200 */ 201 */
202extern void forward_ipi(int fd, int pid);
203extern void kill_child_dead(int pid);
201extern void stop(void); 204extern void stop(void);
202extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); 205extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
203extern int protect_memory(unsigned long addr, unsigned long len, 206extern int protect_memory(unsigned long addr, unsigned long len,
@@ -294,4 +297,17 @@ extern void initial_thread_cb_skas(void (*proc)(void *),
294extern void halt_skas(void); 297extern void halt_skas(void);
295extern void reboot_skas(void); 298extern void reboot_skas(void);
296 299
300/* irq.c */
301extern int os_waiting_for_events(struct irq_fd *active_fds);
302extern int os_isatty(int fd);
303extern int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds);
304extern void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
305 struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2);
306extern void os_free_irq_later(struct irq_fd *active_fds,
307 int irq, void *dev_id);
308extern int os_get_pollfd(int i);
309extern void os_set_pollfd(int i, int fd);
310extern void os_set_ioignore(void);
311extern void init_irq_signals(int on_sigstack);
312
297#endif 313#endif
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
index 0e32f5f4a887..483e79c5ab98 100644
--- a/arch/um/kernel/irq_user.c
+++ b/arch/um/kernel/irq_user.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -18,53 +18,25 @@
18#include "sigio.h" 18#include "sigio.h"
19#include "irq_user.h" 19#include "irq_user.h"
20#include "os.h" 20#include "os.h"
21#include "misc_constants.h"
21 22
22struct irq_fd { 23struct irq_fd *active_fds = NULL;
23 struct irq_fd *next;
24 void *id;
25 int fd;
26 int type;
27 int irq;
28 int pid;
29 int events;
30 int current_events;
31};
32
33static struct irq_fd *active_fds = NULL;
34static struct irq_fd **last_irq_ptr = &active_fds; 24static struct irq_fd **last_irq_ptr = &active_fds;
35 25
36static struct pollfd *pollfds = NULL;
37static int pollfds_num = 0;
38static int pollfds_size = 0;
39
40extern int io_count, intr_count;
41
42extern void free_irqs(void); 26extern void free_irqs(void);
43 27
44void sigio_handler(int sig, union uml_pt_regs *regs) 28void sigio_handler(int sig, union uml_pt_regs *regs)
45{ 29{
46 struct irq_fd *irq_fd; 30 struct irq_fd *irq_fd;
47 int i, n; 31 int n;
48 32
49 if(smp_sigio_handler()) return; 33 if(smp_sigio_handler()) return;
50 while(1){ 34 while(1){
51 n = poll(pollfds, pollfds_num, 0); 35 n = os_waiting_for_events(active_fds);
52 if(n < 0){ 36 if (n <= 0) {
53 if(errno == EINTR) continue; 37 if(n == -EINTR) continue;
54 printk("sigio_handler : poll returned %d, " 38 else break;
55 "errno = %d\n", n, errno); 39 }
56 break;
57 }
58 if(n == 0) break;
59
60 irq_fd = active_fds;
61 for(i = 0; i < pollfds_num; i++){
62 if(pollfds[i].revents != 0){
63 irq_fd->current_events = pollfds[i].revents;
64 pollfds[i].fd = -1;
65 }
66 irq_fd = irq_fd->next;
67 }
68 40
69 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ 41 for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
70 if(irq_fd->current_events != 0){ 42 if(irq_fd->current_events != 0){
@@ -77,14 +49,9 @@ void sigio_handler(int sig, union uml_pt_regs *regs)
77 free_irqs(); 49 free_irqs();
78} 50}
79 51
80int activate_ipi(int fd, int pid)
81{
82 return(os_set_fd_async(fd, pid));
83}
84
85static void maybe_sigio_broken(int fd, int type) 52static void maybe_sigio_broken(int fd, int type)
86{ 53{
87 if(isatty(fd)){ 54 if(os_isatty(fd)){
88 if((type == IRQ_WRITE) && !pty_output_sigio){ 55 if((type == IRQ_WRITE) && !pty_output_sigio){
89 write_sigio_workaround(); 56 write_sigio_workaround();
90 add_sigio_fd(fd, 0); 57 add_sigio_fd(fd, 0);
@@ -96,12 +63,13 @@ static void maybe_sigio_broken(int fd, int type)
96 } 63 }
97} 64}
98 65
66
99int activate_fd(int irq, int fd, int type, void *dev_id) 67int activate_fd(int irq, int fd, int type, void *dev_id)
100{ 68{
101 struct pollfd *tmp_pfd; 69 struct pollfd *tmp_pfd;
102 struct irq_fd *new_fd, *irq_fd; 70 struct irq_fd *new_fd, *irq_fd;
103 unsigned long flags; 71 unsigned long flags;
104 int pid, events, err, n, size; 72 int pid, events, err, n;
105 73
106 pid = os_getpid(); 74 pid = os_getpid();
107 err = os_set_fd_async(fd, pid); 75 err = os_set_fd_async(fd, pid);
@@ -113,8 +81,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
113 if(new_fd == NULL) 81 if(new_fd == NULL)
114 goto out; 82 goto out;
115 83
116 if(type == IRQ_READ) events = POLLIN | POLLPRI; 84 if(type == IRQ_READ) events = UM_POLLIN | UM_POLLPRI;
117 else events = POLLOUT; 85 else events = UM_POLLOUT;
118 *new_fd = ((struct irq_fd) { .next = NULL, 86 *new_fd = ((struct irq_fd) { .next = NULL,
119 .id = dev_id, 87 .id = dev_id,
120 .fd = fd, 88 .fd = fd,
@@ -125,12 +93,12 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
125 .current_events = 0 } ); 93 .current_events = 0 } );
126 94
127 /* Critical section - locked by a spinlock because this stuff can 95 /* Critical section - locked by a spinlock because this stuff can
128 * be changed from interrupt handlers. The stuff above is done 96 * be changed from interrupt handlers. The stuff above is done
129 * outside the lock because it allocates memory. 97 * outside the lock because it allocates memory.
130 */ 98 */
131 99
132 /* Actually, it only looks like it can be called from interrupt 100 /* Actually, it only looks like it can be called from interrupt
133 * context. The culprit is reactivate_fd, which calls 101 * context. The culprit is reactivate_fd, which calls
134 * maybe_sigio_broken, which calls write_sigio_workaround, 102 * maybe_sigio_broken, which calls write_sigio_workaround,
135 * which calls activate_fd. However, write_sigio_workaround should 103 * which calls activate_fd. However, write_sigio_workaround should
136 * only be called once, at boot time. That would make it clear that 104 * only be called once, at boot time. That would make it clear that
@@ -147,40 +115,42 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
147 } 115 }
148 } 116 }
149 117
150 n = pollfds_num; 118 /*-------------*/
151 if(n == pollfds_size){ 119 if(type == IRQ_WRITE)
152 while(1){ 120 fd = -1;
153 /* Here we have to drop the lock in order to call 121
154 * kmalloc, which might sleep. If something else 122 tmp_pfd = NULL;
155 * came in and changed the pollfds array, we free 123 n = 0;
156 * the buffer and try again. 124
157 */ 125 while(1){
158 irq_unlock(flags); 126 n = os_create_pollfd(fd, events, tmp_pfd, n);
159 size = (pollfds_num + 1) * sizeof(pollfds[0]); 127 if (n == 0)
160 tmp_pfd = um_kmalloc(size); 128 break;
161 flags = irq_lock(); 129
162 if(tmp_pfd == NULL) 130 /* n > 0
163 goto out_unlock; 131 * It means we couldn't put new pollfd to current pollfds
164 if(n == pollfds_size) 132 * and tmp_fds is NULL or too small for new pollfds array.
165 break; 133 * Needed size is equal to n as minimum.
134 *
135 * Here we have to drop the lock in order to call
136 * kmalloc, which might sleep.
137 * If something else came in and changed the pollfds array
138 * so we will not be able to put new pollfd struct to pollfds
139 * then we free the buffer tmp_fds and try again.
140 */
141 irq_unlock(flags);
142 if (tmp_pfd != NULL) {
166 kfree(tmp_pfd); 143 kfree(tmp_pfd);
144 tmp_pfd = NULL;
167 } 145 }
168 if(pollfds != NULL){
169 memcpy(tmp_pfd, pollfds,
170 sizeof(pollfds[0]) * pollfds_size);
171 kfree(pollfds);
172 }
173 pollfds = tmp_pfd;
174 pollfds_size++;
175 }
176 146
177 if(type == IRQ_WRITE) 147 tmp_pfd = um_kmalloc(n);
178 fd = -1; 148 if (tmp_pfd == NULL)
149 goto out_kfree;
179 150
180 pollfds[pollfds_num] = ((struct pollfd) { .fd = fd, 151 flags = irq_lock();
181 .events = events, 152 }
182 .revents = 0 }); 153 /*-------------*/
183 pollfds_num++;
184 154
185 *last_irq_ptr = new_fd; 155 *last_irq_ptr = new_fd;
186 last_irq_ptr = &new_fd->next; 156 last_irq_ptr = &new_fd->next;
@@ -196,6 +166,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
196 166
197 out_unlock: 167 out_unlock:
198 irq_unlock(flags); 168 irq_unlock(flags);
169 out_kfree:
199 kfree(new_fd); 170 kfree(new_fd);
200 out: 171 out:
201 return(err); 172 return(err);
@@ -203,43 +174,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
203 174
204static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) 175static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
205{ 176{
206 struct irq_fd **prev;
207 unsigned long flags; 177 unsigned long flags;
208 int i = 0;
209 178
210 flags = irq_lock(); 179 flags = irq_lock();
211 prev = &active_fds; 180 os_free_irq_by_cb(test, arg, active_fds, &last_irq_ptr);
212 while(*prev != NULL){
213 if((*test)(*prev, arg)){
214 struct irq_fd *old_fd = *prev;
215 if((pollfds[i].fd != -1) &&
216 (pollfds[i].fd != (*prev)->fd)){
217 printk("free_irq_by_cb - mismatch between "
218 "active_fds and pollfds, fd %d vs %d\n",
219 (*prev)->fd, pollfds[i].fd);
220 goto out;
221 }
222
223 pollfds_num--;
224
225 /* This moves the *whole* array after pollfds[i] (though
226 * it doesn't spot as such)! */
227
228 memmove(&pollfds[i], &pollfds[i + 1],
229 (pollfds_num - i) * sizeof(pollfds[0]));
230
231 if(last_irq_ptr == &old_fd->next)
232 last_irq_ptr = prev;
233 *prev = (*prev)->next;
234 if(old_fd->type == IRQ_WRITE)
235 ignore_sigio_fd(old_fd->fd);
236 kfree(old_fd);
237 continue;
238 }
239 prev = &(*prev)->next;
240 i++;
241 }
242 out:
243 irq_unlock(flags); 181 irq_unlock(flags);
244} 182}
245 183
@@ -277,6 +215,7 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
277{ 215{
278 struct irq_fd *irq; 216 struct irq_fd *irq;
279 int i = 0; 217 int i = 0;
218 int fdi;
280 219
281 for(irq=active_fds; irq != NULL; irq = irq->next){ 220 for(irq=active_fds; irq != NULL; irq = irq->next){
282 if((irq->fd == fd) && (irq->irq == irqnum)) break; 221 if((irq->fd == fd) && (irq->irq == irqnum)) break;
@@ -286,10 +225,11 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
286 printk("find_irq_by_fd doesn't have descriptor %d\n", fd); 225 printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
287 goto out; 226 goto out;
288 } 227 }
289 if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){ 228 fdi = os_get_pollfd(i);
229 if((fdi != -1) && (fdi != fd)){
290 printk("find_irq_by_fd - mismatch between active_fds and " 230 printk("find_irq_by_fd - mismatch between active_fds and "
291 "pollfds, fd %d vs %d, need %d\n", irq->fd, 231 "pollfds, fd %d vs %d, need %d\n", irq->fd,
292 pollfds[i].fd, fd); 232 fdi, fd);
293 irq = NULL; 233 irq = NULL;
294 goto out; 234 goto out;
295 } 235 }
@@ -310,9 +250,7 @@ void reactivate_fd(int fd, int irqnum)
310 irq_unlock(flags); 250 irq_unlock(flags);
311 return; 251 return;
312 } 252 }
313 253 os_set_pollfd(i, irq->fd);
314 pollfds[i].fd = irq->fd;
315
316 irq_unlock(flags); 254 irq_unlock(flags);
317 255
318 /* This calls activate_fd, so it has to be outside the critical 256 /* This calls activate_fd, so it has to be outside the critical
@@ -331,7 +269,7 @@ void deactivate_fd(int fd, int irqnum)
331 irq = find_irq_by_fd(fd, irqnum, &i); 269 irq = find_irq_by_fd(fd, irqnum, &i);
332 if(irq == NULL) 270 if(irq == NULL)
333 goto out; 271 goto out;
334 pollfds[i].fd = -1; 272 os_set_pollfd(i, -1);
335 out: 273 out:
336 irq_unlock(flags); 274 irq_unlock(flags);
337} 275}
@@ -347,21 +285,11 @@ int deactivate_all_fds(void)
347 return(err); 285 return(err);
348 } 286 }
349 /* If there is a signal already queued, after unblocking ignore it */ 287 /* If there is a signal already queued, after unblocking ignore it */
350 set_handler(SIGIO, SIG_IGN, 0, -1); 288 os_set_ioignore();
351 289
352 return(0); 290 return(0);
353} 291}
354 292
355void forward_ipi(int fd, int pid)
356{
357 int err;
358
359 err = os_set_owner(fd, pid);
360 if(err < 0)
361 printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
362 "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
363}
364
365void forward_interrupts(int pid) 293void forward_interrupts(int pid)
366{ 294{
367 struct irq_fd *irq; 295 struct irq_fd *irq;
@@ -384,22 +312,6 @@ void forward_interrupts(int pid)
384 irq_unlock(flags); 312 irq_unlock(flags);
385} 313}
386 314
387void init_irq_signals(int on_sigstack)
388{
389 __sighandler_t h;
390 int flags;
391
392 flags = on_sigstack ? SA_ONSTACK : 0;
393 if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
394 else h = boot_timer_handler;
395
396 set_handler(SIGVTALRM, h, flags | SA_RESTART,
397 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
398 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
399 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
400 signal(SIGWINCH, SIG_IGN);
401}
402
403/* 315/*
404 * Overrides for Emacs so that we follow Linus's tabbing style. 316 * Overrides for Emacs so that we follow Linus's tabbing style.
405 * Emacs will notice this stuff at the end of the file and automatically 317 * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index 72113b0a96e7..c8d8d0ac1a7f 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -77,9 +77,9 @@ static int idle_proc(void *cpup)
77 if(err < 0) 77 if(err < 0)
78 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); 78 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
79 79
80 activate_ipi(cpu_data[cpu].ipi_pipe[0], 80 os_set_fd_async(cpu_data[cpu].ipi_pipe[0],
81 current->thread.mode.tt.extern_pid); 81 current->thread.mode.tt.extern_pid);
82 82
83 wmb(); 83 wmb();
84 if (cpu_test_and_set(cpu, cpu_callin_map)) { 84 if (cpu_test_and_set(cpu, cpu_callin_map)) {
85 printk("huh, CPU#%d already present??\n", cpu); 85 printk("huh, CPU#%d already present??\n", cpu);
@@ -106,7 +106,7 @@ static struct task_struct *idle_thread(int cpu)
106 panic("copy_process failed in idle_thread, error = %ld", 106 panic("copy_process failed in idle_thread, error = %ld",
107 PTR_ERR(new_task)); 107 PTR_ERR(new_task));
108 108
109 cpu_tasks[cpu] = ((struct cpu_task) 109 cpu_tasks[cpu] = ((struct cpu_task)
110 { .pid = new_task->thread.mode.tt.extern_pid, 110 { .pid = new_task->thread.mode.tt.extern_pid,
111 .task = new_task } ); 111 .task = new_task } );
112 idle_threads[cpu] = new_task; 112 idle_threads[cpu] = new_task;
@@ -134,12 +134,12 @@ void smp_prepare_cpus(unsigned int maxcpus)
134 if(err < 0) 134 if(err < 0)
135 panic("CPU#0 failed to create IPI pipe, errno = %d", -err); 135 panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
136 136
137 activate_ipi(cpu_data[me].ipi_pipe[0], 137 os_set_fd_async(cpu_data[me].ipi_pipe[0],
138 current->thread.mode.tt.extern_pid); 138 current->thread.mode.tt.extern_pid);
139 139
140 for(cpu = 1; cpu < ncpus; cpu++){ 140 for(cpu = 1; cpu < ncpus; cpu++){
141 printk("Booting processor %d...\n", cpu); 141 printk("Booting processor %d...\n", cpu);
142 142
143 idle = idle_thread(cpu); 143 idle = idle_thread(cpu);
144 144
145 init_idle(idle, cpu); 145 init_idle(idle, cpu);
@@ -223,7 +223,7 @@ void smp_call_function_slave(int cpu)
223 atomic_inc(&scf_finished); 223 atomic_inc(&scf_finished);
224} 224}
225 225
226int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 226int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
227 int wait) 227 int wait)
228{ 228{
229 int cpus = num_online_cpus() - 1; 229 int cpus = num_online_cpus() - 1;
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 08a4e628b24c..73d3d837ed6b 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,14 +3,14 @@
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y = aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 6obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o signal.o \
7 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \ 7 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o user_syms.o \
8 util.o drivers/ sys-$(SUBARCH)/ 8 util.o drivers/ sys-$(SUBARCH)/
9 9
10obj-$(CONFIG_MODE_SKAS) += skas/ 10obj-$(CONFIG_MODE_SKAS) += skas/
11 11
12USER_OBJS := aio.o elf_aux.o file.o helper.o main.o mem.o process.o signal.o \ 12USER_OBJS := aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o \
13 start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o util.o 13 signal.o start_up.o time.o trap.o tt.o tty.o uaccess.o umid.o util.o
14 14
15elf_aux.o: $(ARCH_DIR)/kernel-offsets.h 15elf_aux.o: $(ARCH_DIR)/kernel-offsets.h
16CFLAGS_elf_aux.o += -I$(objtree)/arch/um 16CFLAGS_elf_aux.o += -I$(objtree)/arch/um
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
new file mode 100644
index 000000000000..e599be423da1
--- /dev/null
+++ b/arch/um/os-Linux/irq.c
@@ -0,0 +1,162 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h>
9#include <signal.h>
10#include <string.h>
11#include <sys/poll.h>
12#include <sys/types.h>
13#include <sys/time.h>
14#include "user_util.h"
15#include "kern_util.h"
16#include "user.h"
17#include "process.h"
18#include "sigio.h"
19#include "irq_user.h"
20#include "os.h"
21
22static struct pollfd *pollfds = NULL;
23static int pollfds_num = 0;
24static int pollfds_size = 0;
25
26int os_waiting_for_events(struct irq_fd *active_fds)
27{
28 struct irq_fd *irq_fd;
29 int i, n, err;
30
31 n = poll(pollfds, pollfds_num, 0);
32 if(n < 0){
33 err = -errno;
34 if(errno != EINTR)
35 printk("sigio_handler: os_waiting_for_events:"
36 " poll returned %d, errno = %d\n", n, errno);
37 return err;
38 }
39
40 if(n == 0)
41 return 0;
42
43 irq_fd = active_fds;
44
45 for(i = 0; i < pollfds_num; i++){
46 if(pollfds[i].revents != 0){
47 irq_fd->current_events = pollfds[i].revents;
48 pollfds[i].fd = -1;
49 }
50 irq_fd = irq_fd->next;
51 }
52 return n;
53}
54
55int os_isatty(int fd)
56{
57 return(isatty(fd));
58}
59
60int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds)
61{
62 if (pollfds_num == pollfds_size) {
63 if (size_tmpfds <= pollfds_size * sizeof(pollfds[0])) {
64 /* return min size needed for new pollfds area */
65 return((pollfds_size + 1) * sizeof(pollfds[0]));
66 }
67
68 if(pollfds != NULL){
69 memcpy(tmp_pfd, pollfds,
70 sizeof(pollfds[0]) * pollfds_size);
71 /* remove old pollfds */
72 kfree(pollfds);
73 }
74 pollfds = tmp_pfd;
75 pollfds_size++;
76 } else {
77 /* remove not used tmp_pfd */
78 if (tmp_pfd != NULL)
79 kfree(tmp_pfd);
80 }
81
82 pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
83 .events = events,
84 .revents = 0 });
85 pollfds_num++;
86
87 return(0);
88}
89
90void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
91 struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2)
92{
93 struct irq_fd **prev;
94 int i = 0;
95
96 prev = &active_fds;
97 while(*prev != NULL){
98 if((*test)(*prev, arg)){
99 struct irq_fd *old_fd = *prev;
100 if((pollfds[i].fd != -1) &&
101 (pollfds[i].fd != (*prev)->fd)){
102 printk("os_free_irq_by_cb - mismatch between "
103 "active_fds and pollfds, fd %d vs %d\n",
104 (*prev)->fd, pollfds[i].fd);
105 goto out;
106 }
107
108 pollfds_num--;
109
110 /* This moves the *whole* array after pollfds[i]
111 * (though it doesn't spot as such)!
112 */
113
114 memmove(&pollfds[i], &pollfds[i + 1],
115 (pollfds_num - i) * sizeof(pollfds[0]));
116 if(*last_irq_ptr2 == &old_fd->next)
117 *last_irq_ptr2 = prev;
118
119 *prev = (*prev)->next;
120 if(old_fd->type == IRQ_WRITE)
121 ignore_sigio_fd(old_fd->fd);
122 kfree(old_fd);
123 continue;
124 }
125 prev = &(*prev)->next;
126 i++;
127 }
128 out:
129 return;
130}
131
132
133int os_get_pollfd(int i)
134{
135 return(pollfds[i].fd);
136}
137
138void os_set_pollfd(int i, int fd)
139{
140 pollfds[i].fd = fd;
141}
142
143void os_set_ioignore(void)
144{
145 set_handler(SIGIO, SIG_IGN, 0, -1);
146}
147
148void init_irq_signals(int on_sigstack)
149{
150 __sighandler_t h;
151 int flags;
152
153 flags = on_sigstack ? SA_ONSTACK : 0;
154 if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
155 else h = boot_timer_handler;
156
157 set_handler(SIGVTALRM, h, flags | SA_RESTART,
158 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
159 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
160 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
161 signal(SIGWINCH, SIG_IGN);
162}
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 919d19f11537..5461a065bbb9 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -110,6 +110,16 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay)
110 } 110 }
111} 111}
112 112
113void forward_ipi(int fd, int pid)
114{
115 int err;
116
117 err = os_set_owner(fd, pid);
118 if(err < 0)
119 printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
120 "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
121}
122
113/* 123/*
114 *------------------------- 124 *-------------------------
115 * only for tt mode (will be deleted in future...) 125 * only for tt mode (will be deleted in future...)
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 26b68675053d..6f4ef2b7fa4a 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -3,12 +3,13 @@
3#include <asm/ptrace.h> 3#include <asm/ptrace.h>
4#include <asm/user.h> 4#include <asm/user.h>
5#include <linux/stddef.h> 5#include <linux/stddef.h>
6#include <sys/poll.h>
6 7
7#define DEFINE(sym, val) \ 8#define DEFINE(sym, val) \
8 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 9 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
9 10
10#define DEFINE_LONGS(sym, val) \ 11#define DEFINE_LONGS(sym, val) \
11 asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long))) 12 asm volatile("\n->" #sym " %0 " #val : : "i" (val/sizeof(unsigned long)))
12 13
13#define OFFSET(sym, str, mem) \ 14#define OFFSET(sym, str, mem) \
14 DEFINE(sym, offsetof(struct str, mem)); 15 DEFINE(sym, offsetof(struct str, mem));
@@ -67,4 +68,9 @@ void foo(void)
67 DEFINE(HOST_ES, ES); 68 DEFINE(HOST_ES, ES);
68 DEFINE(HOST_GS, GS); 69 DEFINE(HOST_GS, GS);
69 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); 70 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
71
72 /* XXX Duplicated between i386 and x86_64 */
73 DEFINE(UM_POLLIN, POLLIN);
74 DEFINE(UM_POLLPRI, POLLPRI);
75 DEFINE(UM_POLLOUT, POLLOUT);
70} 76}
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 7bd54a921cf7..899cebb57c3f 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -1,6 +1,7 @@
1#include <stdio.h> 1#include <stdio.h>
2#include <stddef.h> 2#include <stddef.h>
3#include <signal.h> 3#include <signal.h>
4#include <sys/poll.h>
4#define __FRAME_OFFSETS 5#define __FRAME_OFFSETS
5#include <asm/ptrace.h> 6#include <asm/ptrace.h>
6#include <asm/types.h> 7#include <asm/types.h>
@@ -88,4 +89,9 @@ void foo(void)
88 DEFINE_LONGS(HOST_IP, RIP); 89 DEFINE_LONGS(HOST_IP, RIP);
89 DEFINE_LONGS(HOST_SP, RSP); 90 DEFINE_LONGS(HOST_SP, RSP);
90 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct)); 91 DEFINE(UM_FRAME_SIZE, sizeof(struct user_regs_struct));
92
93 /* XXX Duplicated between i386 and x86_64 */
94 DEFINE(UM_POLLIN, POLLIN);
95 DEFINE(UM_POLLPRI, POLLPRI);
96 DEFINE(UM_POLLOUT, POLLOUT);
91} 97}