diff options
Diffstat (limited to 'arch/um')
28 files changed, 103 insertions, 99 deletions
diff --git a/arch/um/Makefile b/arch/um/Makefile index 5d5ed726faa0..989224f21346 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -146,7 +146,7 @@ define cmd_vmlinux__ -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ -lutil \ - $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ + $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o \ FORCE ,$^) ; rm -f linux endef diff --git a/arch/um/defconfig b/arch/um/defconfig index a25cd25d55d4..1e0f677c2f46 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -52,7 +52,6 @@ CONFIG_X86_WP_WORKS_OK=y CONFIG_X86_INVLPG=y CONFIG_X86_BSWAP=y CONFIG_X86_POPAD_OK=y -CONFIG_X86_CMPXCHG64=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 368d3e97dfd9..629b00e3b0b0 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -157,7 +157,7 @@ static void tty_receive_char(struct tty_struct *tty, char ch) static int open_one_chan(struct chan *chan) { - int fd; + int fd, err; if(chan->opened) return 0; @@ -168,6 +168,13 @@ static int open_one_chan(struct chan *chan) chan->data, &chan->dev); if(fd < 0) return fd; + + err = os_set_fd_block(fd, 0); + if (err) { + (*chan->ops->close)(fd, chan->data); + return err; + } + chan->fd = fd; chan->opened = 1; diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 542c9ef858f8..d87090507401 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -499,7 +499,7 @@ static struct mc_device mem_mc = { .remove = mem_remove, }; -static int mem_mc_init(void) +static int __init mem_mc_init(void) { if(can_drop_memory()) mconsole_register_dev(&mem_mc); @@ -798,7 +798,7 @@ void mconsole_stack(struct mc_request *req) */ static char *notify_socket = NULL; -static int mconsole_init(void) +static int __init mconsole_init(void) { /* long to avoid size mismatch warnings from gcc */ long sock; diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index e41a08f04694..867666a02339 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c @@ -12,6 +12,7 @@ #include <linux/init.h> #include <linux/module.h> #include <linux/mm.h> +#include <linux/fs.h> #include <linux/miscdevice.h> #include <asm/uaccess.h> #include "mem_user.h" diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 72773dd54425..d35d0c1ee7f4 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -623,7 +623,7 @@ static int eth_setup_common(char *str, int index) return found; } -static int eth_setup(char *str) +static int __init eth_setup(char *str) { struct eth_init *new; char *error; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index fc27f6c72b41..0eabe73c964d 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -469,7 +469,7 @@ __uml_help(fakehd, " Change the ubd device name to \"hd\".\n\n" ); -static void do_ubd_request(request_queue_t * q); +static void do_ubd_request(struct request_queue * q); /* Only changed by ubd_init, which is an initcall. */ int thread_fd = -1; @@ -612,6 +612,8 @@ static int ubd_open_dev(struct ubd *ubd_dev) ubd_dev->fd = fd; if(ubd_dev->cow.file != NULL){ + blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); + err = -ENOMEM; ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); if(ubd_dev->cow.bitmap == NULL){ @@ -712,8 +714,6 @@ static int ubd_add(int n, char **error_out) ubd_dev->queue->queuedata = ubd_dev; blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); - if(ubd_dev->cow.file != NULL) - blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); if(err){ *error_out = "Failed to register device"; @@ -1081,7 +1081,7 @@ static void prepare_request(struct request *req, struct io_thread_req *io_req, } /* Called with dev->lock held */ -static void do_ubd_request(request_queue_t *q) +static void do_ubd_request(struct request_queue *q) { struct io_thread_req *io_req; struct request *req; diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 8d7f7c1cb9c6..6c2be26f1d7d 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h @@ -117,7 +117,7 @@ extern void sigio_handler(int sig, union uml_pt_regs *regs); extern void copy_sc(union uml_pt_regs *regs, void *from); -unsigned long to_irq_stack(int sig, unsigned long *mask_out); +extern unsigned long to_irq_stack(unsigned long *mask_out); unsigned long from_irq_stack(int nested); #endif diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index 24547741b205..41850906116e 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S @@ -71,11 +71,13 @@ SECTIONS *(.gnu.warning) . = ALIGN(4096); - __syscall_stub_start = .; - *(.__syscall_stub*) - __syscall_stub_end = .; - . = ALIGN(4096); } =0x90909090 + . = ALIGN(4096); + .syscall_stub : { + __syscall_stub_start = .; + *(.__syscall_stub*) + __syscall_stub_end = .; + } .fini : { KEEP (*(.fini)) } =0x90909090 @@ -138,8 +140,8 @@ SECTIONS .got : { *(.got.plt) *(.got) } _edata = .; PROVIDE (edata = .); - __bss_start = .; .bss : { + __bss_start = .; *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c index 356e50f5aaed..ce6828fd396f 100644 --- a/arch/um/kernel/exec.c +++ b/arch/um/kernel/exec.c @@ -6,6 +6,7 @@ #include "linux/slab.h" #include "linux/smp_lock.h" #include "linux/ptrace.h" +#include "linux/fs.h" #include "asm/ptrace.h" #include "asm/pgtable.h" #include "asm/tlbflush.h" diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c index d4f1d1ab252b..cba516e6c99a 100644 --- a/arch/um/kernel/init_task.c +++ b/arch/um/kernel/init_task.c @@ -4,6 +4,7 @@ */ #include "linux/mm.h" +#include "linux/fs.h" #include "linux/module.h" #include "linux/sched.h" #include "linux/init_task.h" diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 9870febdbead..cf0dd9cf8c43 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -518,13 +518,13 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler) static unsigned long pending_mask; -unsigned long to_irq_stack(int sig, unsigned long *mask_out) +unsigned long to_irq_stack(unsigned long *mask_out) { struct thread_info *ti; unsigned long mask, old; int nested; - mask = xchg(&pending_mask, 1 << sig); + mask = xchg(&pending_mask, *mask_out); if(mask != 0){ /* If any interrupts come in at this point, we want to * make sure that their bits aren't lost by our @@ -534,7 +534,7 @@ unsigned long to_irq_stack(int sig, unsigned long *mask_out) * and pending_mask contains a bit for each interrupt * that came in. */ - old = 1 << sig; + old = *mask_out; do { old |= mask; mask = xchg(&pending_mask, old); @@ -550,6 +550,7 @@ unsigned long to_irq_stack(int sig, unsigned long *mask_out) task = cpu_tasks[ti->cpu].task; tti = task_thread_info(task); + *ti = *tti; ti->real_thread = tti; task->stack = ti; diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 72ff85693a39..d2b11f242698 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -62,7 +62,7 @@ static void setup_highmem(unsigned long highmem_start, } #endif -void mem_init(void) +void __init mem_init(void) { /* clear the zero-page */ memset((void *) empty_zero_page, 0, PAGE_SIZE); diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index 3ba6e4c841da..5ee7e851bbc1 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c @@ -28,7 +28,8 @@ unsigned long high_physmem; extern unsigned long long physmem_size; -int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem) +int __init init_maps(unsigned long physmem, unsigned long iomem, + unsigned long highmem) { struct page *p, *map; unsigned long phys_len, phys_pages, highmem_len, highmem_pages; @@ -47,13 +48,7 @@ int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem) total_pages = phys_pages + iomem_pages + highmem_pages; total_len = phys_len + iomem_len + highmem_len; - if(kmalloc_ok){ - map = kmalloc(total_len, GFP_KERNEL); - if(map == NULL) - map = vmalloc(total_len); - } - else map = alloc_bootmem_low_pages(total_len); - + map = alloc_bootmem_low_pages(total_len); if(map == NULL) return -ENOMEM; @@ -98,8 +93,8 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len, extern int __syscall_stub_start; -void setup_physmem(unsigned long start, unsigned long reserve_end, - unsigned long len, unsigned long long highmem) +void __init setup_physmem(unsigned long start, unsigned long reserve_end, + unsigned long len, unsigned long long highmem) { unsigned long reserve = reserve_end - start; int pfn = PFN_UP(__pa(reserve_end)); diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 2a69a7ce5792..48051a98525f 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -145,7 +145,7 @@ void init_idle_skas(void) extern void start_kernel(void); -static int start_kernel_proc(void *unused) +static int __init start_kernel_proc(void *unused) { int pid; @@ -165,7 +165,7 @@ extern int userspace_pid[]; extern char cpu0_irqstack[]; -int start_uml_skas(void) +int __init start_uml_skas(void) { stack_protections((unsigned long) &cpu0_irqstack); set_sigstack(cpu0_irqstack, THREAD_SIZE); diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c index 237c4eab7cfd..7b3b67333ff3 100644 --- a/arch/um/kernel/syscall.c +++ b/arch/um/kernel/syscall.c @@ -7,6 +7,7 @@ #include "linux/file.h" #include "linux/smp_lock.h" #include "linux/mm.h" +#include "linux/fs.h" #include "linux/utsname.h" #include "linux/msg.h" #include "linux/shm.h" diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index abab90c3803f..3850d53f79fd 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -76,23 +76,24 @@ good_area: goto out; do { + int fault; survive: - switch (handle_mm_fault(mm, vma, address, is_write)){ - case VM_FAULT_MINOR: - current->min_flt++; - break; - case VM_FAULT_MAJOR: - current->maj_flt++; - break; - case VM_FAULT_SIGBUS: - err = -EACCES; - goto out; - case VM_FAULT_OOM: - err = -ENOMEM; - goto out_of_memory; - default: + fault = handle_mm_fault(mm, vma, address, is_write); + if (unlikely(fault & VM_FAULT_ERROR)) { + if (fault & VM_FAULT_OOM) { + err = -ENOMEM; + goto out_of_memory; + } else if (fault & VM_FAULT_SIGBUS) { + err = -EACCES; + goto out; + } BUG(); } + if (fault & VM_FAULT_MAJOR) + current->maj_flt++; + else + current->min_flt++; + pgd = pgd_offset(mm, address); pud = pud_offset(pgd, address); pmd = pmd_offset(pud, address); diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 307b9373676b..81acdc24348e 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S @@ -44,12 +44,13 @@ SECTIONS /* .gnu.warning sections are handled specially by elf32.em. */ *(.gnu.warning) *(.gnu.linkonce.t*) + } - . = ALIGN(4096); - __syscall_stub_start = .; - *(.__syscall_stub*) - __syscall_stub_end = .; - . = ALIGN(4096); + . = ALIGN(4096); + .syscall_stub : { + __syscall_stub_start = .; + *(.__syscall_stub*) + __syscall_stub_end = .; } #include "asm/common.lds.S" diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c index b126df4ea168..59348359f9ab 100644 --- a/arch/um/os-Linux/aio.c +++ b/arch/um/os-Linux/aio.c @@ -14,6 +14,7 @@ #include "init.h" #include "user.h" #include "mode.h" +#include "kern_constants.h" struct aio_thread_req { enum aio_type type; @@ -65,47 +66,33 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr, static int do_aio(aio_context_t ctx, enum aio_type type, int fd, char *buf, int len, unsigned long long offset, struct aio_context *aio) { - struct iocb iocb, *iocbp = &iocb; + struct iocb *iocbp = & ((struct iocb) { + .aio_data = (unsigned long) aio, + .aio_fildes = fd, + .aio_buf = (unsigned long) buf, + .aio_nbytes = len, + .aio_offset = offset + }); char c; - int err; - iocb = ((struct iocb) { .aio_data = (unsigned long) aio, - .aio_reqprio = 0, - .aio_fildes = fd, - .aio_buf = (unsigned long) buf, - .aio_nbytes = len, - .aio_offset = offset, - .aio_reserved1 = 0, - .aio_reserved2 = 0, - .aio_reserved3 = 0 }); - - switch(type){ + switch (type) { case AIO_READ: - iocb.aio_lio_opcode = IOCB_CMD_PREAD; - err = io_submit(ctx, 1, &iocbp); + iocbp->aio_lio_opcode = IOCB_CMD_PREAD; break; case AIO_WRITE: - iocb.aio_lio_opcode = IOCB_CMD_PWRITE; - err = io_submit(ctx, 1, &iocbp); + iocbp->aio_lio_opcode = IOCB_CMD_PWRITE; break; case AIO_MMAP: - iocb.aio_lio_opcode = IOCB_CMD_PREAD; - iocb.aio_buf = (unsigned long) &c; - iocb.aio_nbytes = sizeof(c); - err = io_submit(ctx, 1, &iocbp); + iocbp->aio_lio_opcode = IOCB_CMD_PREAD; + iocbp->aio_buf = (unsigned long) &c; + iocbp->aio_nbytes = sizeof(c); break; default: - printk("Bogus op in do_aio - %d\n", type); - err = -EINVAL; - break; + printk(UM_KERN_ERR "Bogus op in do_aio - %d\n", type); + return -EINVAL; } - if(err > 0) - err = 0; - else - err = -errno; - - return err; + return (io_submit(ctx, 1, &iocbp) > 0) ? 0 : -errno; } /* Initialized in an initcall and unchanged thereafter */ diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c index 6f92f732d253..c3ecc2a84e0c 100644 --- a/arch/um/os-Linux/file.c +++ b/arch/um/os-Linux/file.c @@ -320,7 +320,8 @@ int os_file_size(char *file, unsigned long long *size_out) } if(S_ISBLK(buf.ust_mode)){ - int fd, blocks; + int fd; + long blocks; fd = os_open_file(file, of_read(OPENFLAGS()), 0); if(fd < 0){ diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 2d9d2ca39299..e9c143297512 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -194,7 +194,7 @@ int os_unmap_memory(void *addr, int len) #define MADV_REMOVE KERNEL_MADV_REMOVE #endif -int __init os_drop_memory(void *addr, int length) +int os_drop_memory(void *addr, int length) { int err; diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 18e5c8b67eb8..b98f7ea2d2f6 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -119,7 +119,7 @@ void (*handlers[_NSIG])(int sig, struct sigcontext *sc); void handle_signal(int sig, struct sigcontext *sc) { - unsigned long pending = 0; + unsigned long pending = 1UL << sig; do { int nested, bail; @@ -134,7 +134,7 @@ void handle_signal(int sig, struct sigcontext *sc) * have to return, and the upper handler will deal * with this interrupt. */ - bail = to_irq_stack(sig, &pending); + bail = to_irq_stack(&pending); if(bail) return; diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index e6fc2179d1bc..9467315b8059 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -4,6 +4,7 @@ */ #include <errno.h> +#include <sys/ptrace.h> #include <string.h> #include "ptrace_user.h" #include "uml-config.h" @@ -17,6 +18,20 @@ static unsigned long exec_regs[MAX_REG_NR]; static unsigned long exec_fp_regs[HOST_FP_SIZE]; +int save_fp_registers(int pid, unsigned long *fp_regs) +{ + if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) + return -errno; + return 0; +} + +int restore_fp_registers(int pid, unsigned long *fp_regs) +{ + if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) + return -errno; + return 0; +} + void init_thread_registers(union uml_pt_regs *to) { memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs)); diff --git a/arch/um/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c index 419b2d5ff6de..4c37b1b1d0b5 100644 --- a/arch/um/os-Linux/user_syms.c +++ b/arch/um/os-Linux/user_syms.c @@ -19,10 +19,7 @@ extern void *memmove(void *, const void *, size_t); extern void *memset(void *, int, size_t); extern int printf(const char *, ...); -/* If they're not defined, the export is included in lib/string.c.*/ -#ifdef __HAVE_ARCH_STRLEN -EXPORT_SYMBOL(strlen); -#endif +/* If it's not defined, the export is included in lib/string.c.*/ #ifdef __HAVE_ARCH_STRSTR EXPORT_SYMBOL(strstr); #endif diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 098720be019a..d6b3ecd4b77e 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile @@ -4,7 +4,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o -subarch-obj-y = lib/bitops.o lib/semaphore.o +subarch-obj-y = lib/bitops.o lib/semaphore.o lib/string.o subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem.o subarch-obj-$(CONFIG_MODULES) += kernel/module.o diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S index 2497554b7b95..12d4148dba39 100644 --- a/arch/um/sys-i386/sys_call_table.S +++ b/arch/um/sys-i386/sys_call_table.S @@ -9,4 +9,4 @@ #define old_mmap old_mmap_i386 -#include "../../i386/kernel/syscall_table.S" +#include "../../x86/kernel/syscall_table_32.S" diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 55b66e09a98c..1970d78aa528 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -156,12 +156,6 @@ int is_syscall(unsigned long addr) return(instr == 0x050f); } -int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu ) -{ - panic("dump_fpu"); - return(1); -} - int get_fpregs(unsigned long buf, struct task_struct *child) { panic("get_fpregs"); diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c index 5133988d3610..71b2ae4ad5de 100644 --- a/arch/um/sys-x86_64/syscall_table.c +++ b/arch/um/sys-x86_64/syscall_table.c @@ -36,7 +36,7 @@ #define __SYSCALL(nr, sym) extern asmlinkage void sym(void) ; #undef _ASM_X86_64_UNISTD_H_ -#include <asm-x86_64/unistd.h> +#include <asm-x86/unistd_64.h> #undef __SYSCALL #define __SYSCALL(nr, sym) [ nr ] = sym, @@ -49,5 +49,5 @@ extern void sys_ni_syscall(void); sys_call_ptr_t sys_call_table[UM_NR_syscall_max+1] __cacheline_aligned = { /* Smells like a like a compiler bug -- it doesn't work when the & below is removed. */ [0 ... UM_NR_syscall_max] = &sys_ni_syscall, -#include <asm-x86_64/unistd.h> +#include <asm-x86/unistd_64.h> }; |