diff options
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/drivers/harddog_kern.c | 1 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 6 | ||||
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/net_kern.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/port_kern.c | 4 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/xterm_kern.c | 2 | ||||
-rw-r--r-- | arch/um/include/sysdep-x86_64/kernel-offsets.h | 1 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/sigio_kern.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/skas/uaccess.c | 15 | ||||
-rw-r--r-- | arch/um/kernel/time_kern.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/vmlinux.lds.S | 1 | ||||
-rw-r--r-- | arch/um/os-Linux/umid.c | 97 | ||||
-rw-r--r-- | arch/um/sys-i386/checksum.S | 1 | ||||
-rw-r--r-- | arch/um/sys-i386/ptrace.c | 1 | ||||
-rw-r--r-- | arch/um/sys-ppc/misc.S | 1 | ||||
-rw-r--r-- | arch/um/sys-x86_64/syscall_table.c | 1 |
18 files changed, 85 insertions, 58 deletions
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c index d18a974735e6..64ff22aa077b 100644 --- a/arch/um/drivers/harddog_kern.c +++ b/arch/um/drivers/harddog_kern.c @@ -35,7 +35,6 @@ */ #include <linux/module.h> -#include <linux/config.h> #include <linux/types.h> #include <linux/kernel.h> #include <linux/fs.h> diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 5ca57ca33713..ebebaabb78ad 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -373,7 +373,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data, int err; /* Interrupts are enabled here because we registered the interrupt with - * SA_INTERRUPT (see line_setup_irq).*/ + * IRQF_DISABLED (see line_setup_irq).*/ spin_lock_irq(&line->lock); err = flush_buffer(line); @@ -406,7 +406,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data, int line_setup_irq(int fd, int input, int output, struct line *line, void *data) { struct line_driver *driver = line->driver; - int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; + int err = 0, flags = IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM; if (input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, @@ -767,7 +767,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) spin_unlock(&winch_handler_lock); if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "winch", winch) < 0) printk("register_winch_irq - failed to register IRQ\n"); } diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 79149314ed04..b414522f7686 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -777,7 +777,7 @@ static int mconsole_init(void) register_reboot_notifier(&reboot_notifier); err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "mconsole", (void *)sock); if (err){ printk("Failed to get IRQ for management console\n"); diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 8c7279bb353b..501f95675d89 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -128,7 +128,7 @@ static int uml_net_open(struct net_device *dev) } err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, - SA_INTERRUPT | SA_SHIRQ, dev->name, dev); + IRQF_DISABLED | IRQF_SHARED, dev->name, dev); if(err != 0){ printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); err = -ENETUNREACH; diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index 189839e4f1d4..73755f37a8a8 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -105,7 +105,7 @@ static int port_accept(struct port_list *port) .port = port }); if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "telnetd", conn)){ printk(KERN_ERR "port_accept : failed to get IRQ for " "telnetd\n"); @@ -186,7 +186,7 @@ void *port_data(int port_num) goto out_free; } if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port", + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "port", port)){ printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); goto out_close; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 0345e2551247..602d7286b9e0 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -874,7 +874,7 @@ int ubd_driver_init(void){ return(0); } err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, - SA_INTERRUPT, "ubd", ubd_dev); + IRQF_DISABLED, "ubd", ubd_dev); if(err != 0) printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); return 0; diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index d269a80f4b0c..6036ec85895a 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -54,7 +54,7 @@ int xterm_fd(int socket, int *pid_out) init_completion(&data->ready); err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, - SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, + IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, "xterm", data); if (err){ printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index 939cc475757a..91d129fb3930 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h @@ -1,4 +1,3 @@ -#include <linux/config.h> #include <linux/stddef.h> #include <linux/sched.h> #include <linux/time.h> diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index fae43a3054a0..bfd0bdc8cd40 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -474,7 +474,7 @@ int init_aio_irq(int irq, char *name, irqreturn_t (*handler)(int, void *, } err = um_request_irq(irq, fds[0], IRQ_READ, handler, - SA_INTERRUPT | SA_SAMPLE_RANDOM, name, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name, (void *) (long) fds[0]); if (err) { printk("init_aio_irq - : um_request_irq failed, err = %d\n", diff --git a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c index 1c1300fb1e95..51b677083948 100644 --- a/arch/um/kernel/sigio_kern.c +++ b/arch/um/kernel/sigio_kern.c @@ -31,7 +31,7 @@ int write_sigio_irq(int fd) int err; err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, - SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", + IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "write sigio", NULL); if(err){ printk("write_sigio_irq : um_request_irq failed, err = %d\n", diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 5992c3257167..8912cec0fe43 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -8,6 +8,7 @@ #include "linux/kernel.h" #include "linux/string.h" #include "linux/fs.h" +#include "linux/hardirq.h" #include "linux/highmem.h" #include "asm/page.h" #include "asm/pgtable.h" @@ -38,7 +39,7 @@ static unsigned long maybe_map(unsigned long virt, int is_write) return((unsigned long) phys); } -static int do_op(unsigned long addr, int len, int is_write, +static int do_op_one_page(unsigned long addr, int len, int is_write, int (*op)(unsigned long addr, int len, void *arg), void *arg) { struct page *page; @@ -49,9 +50,11 @@ static int do_op(unsigned long addr, int len, int is_write, return(-1); page = phys_to_page(addr); - addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); + addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + (addr & ~PAGE_MASK); + n = (*op)(addr, len, arg); - kunmap(page); + + kunmap_atomic(page, KM_UML_USERCOPY); return(n); } @@ -77,7 +80,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) remain = len; current->thread.fault_catcher = jmpbuf; - n = do_op(addr, size, is_write, op, arg); + n = do_op_one_page(addr, size, is_write, op, arg); if(n != 0){ *res = (n < 0 ? remain : 0); goto out; @@ -91,7 +94,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) } while(addr < ((addr + remain) & PAGE_MASK)){ - n = do_op(addr, PAGE_SIZE, is_write, op, arg); + n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg); if(n != 0){ *res = (n < 0 ? remain : 0); goto out; @@ -105,7 +108,7 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr) goto out; } - n = do_op(addr, remain, is_write, op, arg); + n = do_op_one_page(addr, remain, is_write, op, arg); if(n != 0) *res = (n < 0 ? remain : 0); else *res = 0; diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 820fa3615a3f..d7e044b5e5ee 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c @@ -195,7 +195,7 @@ int __init timer_init(void) int err; user_time_init(); - err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); + err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); if(err != 0) printk(KERN_ERR "timer_init : request_irq failed - " "errno = %d\n", -err); diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S index 0a7d50ff9a4c..72acdce205e0 100644 --- a/arch/um/kernel/vmlinux.lds.S +++ b/arch/um/kernel/vmlinux.lds.S @@ -1,4 +1,3 @@ -#include <linux/config.h> /* in case the preprocessor is a 32bit one */ #undef i386 #ifdef CONFIG_LD_SCRIPT_STATIC diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c index 362db059fe30..48092b95c8ab 100644 --- a/arch/um/os-Linux/umid.c +++ b/arch/um/os-Linux/umid.c @@ -67,32 +67,53 @@ err: return err; } -static int actually_do_remove(char *dir) +/* + * Unlinks the files contained in @dir and then removes @dir. + * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We + * ignore ENOENT errors for anything (they happen, strangely enough - possibly due + * to races between multiple dying UML threads). + */ +static int remove_files_and_dir(char *dir) { DIR *directory; struct dirent *ent; int len; char file[256]; + int ret; directory = opendir(dir); - if(directory == NULL) - return -errno; + if (directory == NULL) { + if (errno != ENOENT) + return -errno; + else + return 0; + } - while((ent = readdir(directory)) != NULL){ - if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) + while ((ent = readdir(directory)) != NULL) { + if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) continue; len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; - if(len > sizeof(file)) - return -E2BIG; + if (len > sizeof(file)) { + ret = -E2BIG; + goto out; + } sprintf(file, "%s/%s", dir, ent->d_name); - if(unlink(file) < 0) - return -errno; + if (unlink(file) < 0 && errno != ENOENT) { + ret = -errno; + goto out; + } } - if(rmdir(dir) < 0) - return -errno; - return 0; + if (rmdir(dir) < 0 && errno != ENOENT) { + ret = -errno; + goto out; + } + + ret = 0; +out: + closedir(directory); + return ret; } /* This says that there isn't already a user of the specified directory even if @@ -103,9 +124,10 @@ static int actually_do_remove(char *dir) * something other than UML sticking stuff in the directory * this boot racing with a shutdown of the other UML * In any of these cases, the directory isn't useful for anything else. + * + * Boolean return: 1 if in use, 0 otherwise. */ - -static int not_dead_yet(char *dir) +static inline int is_umdir_used(char *dir) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; char pid[sizeof("nnnnn\0")], *end; @@ -113,7 +135,7 @@ static int not_dead_yet(char *dir) n = snprintf(file, sizeof(file), "%s/pid", dir); if(n >= sizeof(file)){ - printk("not_dead_yet - pid filename too long\n"); + printk("is_umdir_used - pid filename too long\n"); err = -E2BIG; goto out; } @@ -123,7 +145,7 @@ static int not_dead_yet(char *dir) if(fd < 0) { fd = -errno; if(fd != -ENOENT){ - printk("not_dead_yet : couldn't open pid file '%s', " + printk("is_umdir_used : couldn't open pid file '%s', " "err = %d\n", file, -fd); } goto out; @@ -132,18 +154,18 @@ static int not_dead_yet(char *dir) err = 0; n = read(fd, pid, sizeof(pid)); if(n < 0){ - printk("not_dead_yet : couldn't read pid file '%s', " + printk("is_umdir_used : couldn't read pid file '%s', " "err = %d\n", file, errno); goto out_close; } else if(n == 0){ - printk("not_dead_yet : couldn't read pid file '%s', " + printk("is_umdir_used : couldn't read pid file '%s', " "0-byte read\n", file); goto out_close; } p = strtoul(pid, &end, 0); if(end == pid){ - printk("not_dead_yet : couldn't parse pid file '%s', " + printk("is_umdir_used : couldn't parse pid file '%s', " "errno = %d\n", file, errno); goto out_close; } @@ -153,19 +175,32 @@ static int not_dead_yet(char *dir) return 1; } - err = actually_do_remove(dir); - if(err) - printk("not_dead_yet - actually_do_remove failed with " - "err = %d\n", err); - - return err; - out_close: close(fd); out: return 0; } +/* + * Try to remove the directory @dir unless it's in use. + * Precondition: @dir exists. + * Returns 0 for success, < 0 for failure in removal or if the directory is in + * use. + */ +static int umdir_take_if_dead(char *dir) +{ + int ret; + if (is_umdir_used(dir)) + return -EEXIST; + + ret = remove_files_and_dir(dir); + if (ret) { + printk("is_umdir_used - remove_files_and_dir failed with " + "err = %d\n", ret); + } + return ret; +} + static void __init create_pid_file(void) { char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; @@ -244,11 +279,7 @@ int __init make_umid(void) if(err != -EEXIST) goto err; - /* 1 -> this umid is already in use - * < 0 -> we couldn't remove the umid directory - * In either case, we can't use this umid, so return -EEXIST. - */ - if(not_dead_yet(tmp) != 0) + if (umdir_take_if_dead(tmp) < 0) goto err; err = mkdir(tmp, 0777); @@ -344,9 +375,9 @@ static void remove_umid_dir(void) char dir[strlen(uml_dir) + UMID_LEN + 1], err; sprintf(dir, "%s%s", uml_dir, umid); - err = actually_do_remove(dir); + err = remove_files_and_dir(dir); if(err) - printf("remove_umid_dir - actually_do_remove failed with " + printf("remove_umid_dir - remove_files_and_dir failed with " "err = %d\n", err); } diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S index d98b2fff3d08..62c7e564f22e 100644 --- a/arch/um/sys-i386/checksum.S +++ b/arch/um/sys-i386/checksum.S @@ -25,7 +25,6 @@ * 2 of the License, or (at your option) any later version. */ -#include <linux/config.h> #include <asm/errno.h> /* diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index 6028bc7cc01b..28bf01150323 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -3,7 +3,6 @@ * Licensed under the GPL */ -#include <linux/config.h> #include <linux/compiler.h> #include "linux/sched.h" #include "linux/mm.h" diff --git a/arch/um/sys-ppc/misc.S b/arch/um/sys-ppc/misc.S index f0c971db47e4..1364b7da578c 100644 --- a/arch/um/sys-ppc/misc.S +++ b/arch/um/sys-ppc/misc.S @@ -15,7 +15,6 @@ * */ -#include <linux/config.h> #include <asm/processor.h> #include "ppc_asm.h" diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 3c4318165de0..9e9ad72c2ba4 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c @@ -4,7 +4,6 @@ #include <linux/linkage.h> #include <linux/sys.h> #include <linux/cache.h> -#include <linux/config.h> #define __NO_STUBS |