diff options
author | Anton Arapov <anton@redhat.com> | 2012-08-07 11:21:50 +0200 |
---|---|---|
committer | Anton Arapov <anton@redhat.com> | 2012-08-07 12:52:25 +0200 |
commit | 1d44b6f3fcf6058fb7c960b7558766967e8028f7 (patch) | |
tree | 53d88547c973ba048d233091a3f91f3173ad01df /arch/um | |
parent | d91eda5d7b0383e6a0c83e0146ff141ff3b1355b (diff) | |
download | kernel-uprobes-1d44b6f3fcf6058fb7c960b7558766967e8028f7.tar.gz kernel-uprobes-1d44b6f3fcf6058fb7c960b7558766967e8028f7.tar.xz kernel-uprobes-1d44b6f3fcf6058fb7c960b7558766967e8028f7.zip |
fedora kernel: 222b075b3ff0d9e88aa9353e3c80667756ed7361v3.5.0-4
Signed-off-by: Anton Arapov <anton@redhat.com>
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/Kconfig.common | 10 | ||||
-rw-r--r-- | arch/um/Kconfig.um | 1 | ||||
-rw-r--r-- | arch/um/Makefile | 11 | ||||
-rw-r--r-- | arch/um/defconfig | 1 | ||||
-rw-r--r-- | arch/um/drivers/chan_kern.c | 9 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/net_kern.c | 4 | ||||
-rw-r--r-- | arch/um/drivers/port_kern.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/xterm_kern.c | 2 | ||||
-rw-r--r-- | arch/um/include/asm/kvm_para.h | 1 | ||||
-rw-r--r-- | arch/um/include/asm/processor-generic.h | 7 | ||||
-rw-r--r-- | arch/um/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/um/include/shared/frame_kern.h | 3 | ||||
-rw-r--r-- | arch/um/include/shared/irq_kern.h | 2 | ||||
-rw-r--r-- | arch/um/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/um/kernel/init_task.c | 38 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 9 | ||||
-rw-r--r-- | arch/um/kernel/process.c | 7 | ||||
-rw-r--r-- | arch/um/kernel/reboot.c | 13 | ||||
-rw-r--r-- | arch/um/kernel/signal.c | 50 | ||||
-rw-r--r-- | arch/um/kernel/skas/syscall.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/smp.c | 2 | ||||
-rw-r--r-- | arch/um/kernel/tlb.c | 1 | ||||
-rw-r--r-- | arch/um/kernel/trap.c | 24 | ||||
-rw-r--r-- | arch/um/kernel/um_arch.c | 5 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/mem.c | 10 |
26 files changed, 74 insertions, 146 deletions
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common index 20a49ba93cb..cb837c22392 100644 --- a/arch/um/Kconfig.common +++ b/arch/um/Kconfig.common @@ -10,6 +10,7 @@ config UML select GENERIC_IRQ_SHOW select GENERIC_CPU_DEVICES select GENERIC_IO + select GENERIC_CLOCKEVENTS config MMU bool @@ -52,15 +53,6 @@ config GENERIC_BUG default y depends on BUG -config GENERIC_CLOCKEVENTS - bool - default y - -# Used in kernel/irq/manage.c and include/linux/irq.h -config IRQ_RELEASE_METHOD - bool - default y - config HZ int default 100 diff --git a/arch/um/Kconfig.um b/arch/um/Kconfig.um index 70fd690964e..bf87f25eb2d 100644 --- a/arch/um/Kconfig.um +++ b/arch/um/Kconfig.um @@ -10,7 +10,6 @@ config STATIC_LINK 2.75G) for UML. source "mm/Kconfig" -source "kernel/time/Kconfig" config LD_SCRIPT_STATIC bool diff --git a/arch/um/Makefile b/arch/um/Makefile index 55c0661e2b5..097091059aa 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile @@ -121,15 +121,8 @@ LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc LD_FLAGS_CMDLINE = $(foreach opt,$(LDFLAGS),-Wl,$(opt)) -CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) -define cmd_vmlinux__ - $(CC) $(CFLAGS_vmlinux) -o $@ \ - -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ - -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ - -lutil \ - $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o \ - FORCE ,$^) ; rm -f linux -endef +# Used by link-vmlinux.sh which has special support for um link +export CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) $(LD_FLAGS_CMDLINE) # When cleaning we don't include .config, so we don't include # TT or skas makefiles and don't clean skas_ptregs.h. diff --git a/arch/um/defconfig b/arch/um/defconfig index fdc97e2c3d7..7823ab12e6a 100644 --- a/arch/um/defconfig +++ b/arch/um/defconfig @@ -12,7 +12,6 @@ CONFIG_LOCKDEP_SUPPORT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_GENERIC_BUG=y CONFIG_GENERIC_CLOCKEVENTS=y -CONFIG_IRQ_RELEASE_METHOD=y CONFIG_HZ=100 # diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index ca4c7ebfd0a..45e248c2f43 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -8,6 +8,7 @@ #include <linux/tty_flip.h> #include "chan.h" #include "os.h" +#include "irq_kern.h" #ifdef CONFIG_NOCONFIG_CHAN static void *not_configged_init(char *str, int device, @@ -213,9 +214,9 @@ void free_irqs(void) chan = list_entry(ele, struct chan, free_list); if (chan->input && chan->enabled) - free_irq(chan->line->driver->read_irq, chan); + um_free_irq(chan->line->driver->read_irq, chan); if (chan->output && chan->enabled) - free_irq(chan->line->driver->write_irq, chan); + um_free_irq(chan->line->driver->write_irq, chan); chan->enabled = 0; } } @@ -234,9 +235,9 @@ static void close_one_chan(struct chan *chan, int delay_free_irq) } else { if (chan->input && chan->enabled) - free_irq(chan->line->driver->read_irq, chan); + um_free_irq(chan->line->driver->read_irq, chan); if (chan->output && chan->enabled) - free_irq(chan->line->driver->write_irq, chan); + um_free_irq(chan->line->driver->write_irq, chan); chan->enabled = 0; } if (chan->ops->close != NULL) diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 4ab0d9c0911..acfd0e0fd0c 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -699,7 +699,7 @@ struct winch { static void __free_winch(struct work_struct *work) { struct winch *winch = container_of(work, struct winch, work); - free_irq(WINCH_IRQ, winch); + um_free_irq(WINCH_IRQ, winch); if (winch->pid != -1) os_kill_process(winch->pid, 1); diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c index 95f4416e6d9..0d60c5685c2 100644 --- a/arch/um/drivers/net_kern.c +++ b/arch/um/drivers/net_kern.c @@ -195,7 +195,7 @@ static int uml_net_close(struct net_device *dev) netif_stop_queue(dev); - free_irq(dev->irq, dev); + um_free_irq(dev->irq, dev); if (lp->close != NULL) (*lp->close)(lp->fd, &lp->user); lp->fd = -1; @@ -835,7 +835,7 @@ static void close_devices(void) spin_lock(&opened_lock); list_for_each(ele, &opened) { lp = list_entry(ele, struct uml_net_private, list); - free_irq(lp->dev->irq, lp->dev); + um_free_irq(lp->dev->irq, lp->dev); if ((lp->close != NULL) && (lp->fd >= 0)) (*lp->close)(lp->fd, &lp->user); if (lp->remove != NULL) diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c index e31680e662a..11866ffd45a 100644 --- a/arch/um/drivers/port_kern.c +++ b/arch/um/drivers/port_kern.c @@ -254,7 +254,7 @@ int port_wait(void *data) * connection. Then we loop here throwing out failed * connections until a good one is found. */ - free_irq(TELNETD_IRQ, conn); + um_free_irq(TELNETD_IRQ, conn); if (conn->fd >= 0) break; diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index 8bd130f0bda..b68bbe269e0 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c @@ -65,7 +65,7 @@ int xterm_fd(int socket, int *pid_out) * isn't set) this will hang... */ wait_for_completion(&data->ready); - free_irq(XTERM_IRQ, data); + um_free_irq(XTERM_IRQ, data); ret = data->new_fd; *pid_out = data->pid; diff --git a/arch/um/include/asm/kvm_para.h b/arch/um/include/asm/kvm_para.h new file mode 100644 index 00000000000..14fab8f0b95 --- /dev/null +++ b/arch/um/include/asm/kvm_para.h @@ -0,0 +1 @@ +#include <asm-generic/kvm_para.h> diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h index 98d01bc4fa9..69f1c57a8d0 100644 --- a/arch/um/include/asm/processor-generic.h +++ b/arch/um/include/asm/processor-generic.h @@ -68,19 +68,12 @@ struct thread_struct { .request = { 0 } \ } -extern struct task_struct *alloc_task_struct_node(int node); - static inline void release_thread(struct task_struct *task) { } extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); -static inline void prepare_to_copy(struct task_struct *tsk) -{ -} - - extern unsigned long thread_saved_pc(struct task_struct *t); static inline void mm_copy_segments(struct mm_struct *from_mm, diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h index 200c4ab1240..c04e5ab68f5 100644 --- a/arch/um/include/asm/thread_info.h +++ b/arch/um/include/asm/thread_info.h @@ -71,6 +71,7 @@ static inline struct thread_info *current_thread_info(void) #define TIF_MEMDIE 5 /* is terminating due to OOM killer */ #define TIF_SYSCALL_AUDIT 6 #define TIF_RESTORE_SIGMASK 7 +#define TIF_NOTIFY_RESUME 8 #define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) @@ -78,6 +79,5 @@ static inline struct thread_info *current_thread_info(void) #define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) #define _TIF_MEMDIE (1 << TIF_MEMDIE) #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) -#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) #endif diff --git a/arch/um/include/shared/frame_kern.h b/arch/um/include/shared/frame_kern.h index 76078490c25..e584e40ee83 100644 --- a/arch/um/include/shared/frame_kern.h +++ b/arch/um/include/shared/frame_kern.h @@ -6,9 +6,6 @@ #ifndef __FRAME_KERN_H_ #define __FRAME_KERN_H_ -#define _S(nr) (1<<((nr)-1)) -#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) - extern int setup_signal_stack_sc(unsigned long stack_top, int sig, struct k_sigaction *ka, struct pt_regs *regs, diff --git a/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h index b05d22f3d84..7a5bfa6291b 100644 --- a/arch/um/include/shared/irq_kern.h +++ b/arch/um/include/shared/irq_kern.h @@ -13,6 +13,6 @@ extern int um_request_irq(unsigned int irq, int fd, int type, irq_handler_t handler, unsigned long irqflags, const char * devname, void *dev_id); - +void um_free_irq(unsigned int irq, void *dev); #endif diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 65a1c3d690e..babe21826e3 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -10,7 +10,7 @@ CPPFLAGS_vmlinux.lds := -DSTART=$(LDS_START) \ extra-y := vmlinux.lds clean-files := -obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ +obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o \ um_arch.o umid.o skas/ diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c deleted file mode 100644 index ddc9698b66e..00000000000 --- a/arch/um/kernel/init_task.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,intel.linux}.com) - * Licensed under the GPL - */ - -#include "linux/sched.h" -#include "linux/init_task.h" -#include "linux/fs.h" -#include "linux/module.h" -#include "linux/mqueue.h" -#include "asm/uaccess.h" - -static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -/* - * Initial task structure. - * - * All other task structs will be allocated on slabs in fork.c - */ - -struct task_struct init_task = INIT_TASK(init_task); - -EXPORT_SYMBOL(init_task); - -/* - * Initial thread structure. - * - * We need to make sure that this is aligned due to the - * way process stacks are handled. This is done by having a special - * "init_task" linker map entry.. - */ - -union thread_union init_thread_union __init_task_data = - { INIT_THREAD_INFO(init_task) }; - -union thread_union cpu0_irqstack - __attribute__((__section__(".data..init_irqstack"))) = - { INIT_THREAD_INFO(init_task) }; diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 71b8c947e5e..00506c3d5d6 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -297,6 +297,13 @@ unsigned int do_IRQ(int irq, struct uml_pt_regs *regs) return 1; } +void um_free_irq(unsigned int irq, void *dev) +{ + free_irq_by_irq_and_dev(irq, dev); + free_irq(irq, dev); +} +EXPORT_SYMBOL(um_free_irq); + int um_request_irq(unsigned int irq, int fd, int type, irq_handler_t handler, unsigned long irqflags, const char * devname, @@ -327,7 +334,6 @@ static void dummy(struct irq_data *d) /* This is used for everything else than the timer. */ static struct irq_chip normal_irq_type = { .name = "SIGIO", - .release = free_irq_by_irq_and_dev, .irq_disable = dummy, .irq_enable = dummy, .irq_ack = dummy, @@ -335,7 +341,6 @@ static struct irq_chip normal_irq_type = { static struct irq_chip SIGVTALRM_irq_type = { .name = "SIGVTALRM", - .release = free_irq_by_irq_and_dev, .irq_disable = dummy, .irq_enable = dummy, .irq_ack = dummy, diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 2b73dedb44c..ccb9a9d283f 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c @@ -18,6 +18,7 @@ #include <linux/seq_file.h> #include <linux/tick.h> #include <linux/threads.h> +#include <linux/tracehook.h> #include <asm/current.h> #include <asm/pgtable.h> #include <asm/mmu_context.h> @@ -114,8 +115,10 @@ void interrupt_end(void) { if (need_resched()) schedule(); - if (test_tsk_thread_flag(current, TIF_SIGPENDING)) + if (test_thread_flag(TIF_SIGPENDING)) do_signal(); + if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME)) + tracehook_notify_resume(¤t->thread.regs); } void exit_thread(void) @@ -190,7 +193,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, if (current->thread.forking) { memcpy(&p->thread.regs.regs, ®s->regs, sizeof(p->thread.regs.regs)); - REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.gp, 0); + UPT_SET_SYSCALL_RETURN(&p->thread.regs.regs, 0); if (sp != 0) REGS_SP(p->thread.regs.regs.gp) = sp; diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c index 4d93dff6b37..3d15243ce69 100644 --- a/arch/um/kernel/reboot.c +++ b/arch/um/kernel/reboot.c @@ -4,7 +4,9 @@ */ #include "linux/sched.h" +#include "linux/spinlock.h" #include "linux/slab.h" +#include "linux/oom.h" #include "kern_util.h" #include "os.h" #include "skas.h" @@ -22,13 +24,18 @@ static void kill_off_processes(void) struct task_struct *p; int pid; + read_lock(&tasklist_lock); for_each_process(p) { - if (p->mm == NULL) - continue; + struct task_struct *t; - pid = p->mm->context.id.u.pid; + t = find_lock_task_mm(p); + if (!t) + continue; + pid = t->mm->context.id.u.pid; + task_unlock(t); os_kill_ptraced_process(pid, 1); } + read_unlock(&tasklist_lock); } } diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index fb12f4c5e64..7362d58efc2 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c @@ -15,23 +15,16 @@ EXPORT_SYMBOL(block_signals); EXPORT_SYMBOL(unblock_signals); -#define _S(nr) (1<<((nr)-1)) - -#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) - /* * OK, we're invoking a handler */ -static int handle_signal(struct pt_regs *regs, unsigned long signr, - struct k_sigaction *ka, siginfo_t *info, - sigset_t *oldset) +static void handle_signal(struct pt_regs *regs, unsigned long signr, + struct k_sigaction *ka, siginfo_t *info) { + sigset_t *oldset = sigmask_to_save(); unsigned long sp; int err; - /* Always make any pending restarted system calls return -EINTR */ - current_thread_info()->restart_block.fn = do_no_restart_syscall; - /* Did we come from a system call? */ if (PT_REGS_SYSCALL_NR(regs) >= 0) { /* If so, check system call restarting.. */ @@ -68,37 +61,19 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, if (err) force_sigsegv(signr, current); else - block_sigmask(ka, signr); - - return err; + signal_delivered(signr, info, ka, regs, 0); } static int kern_do_signal(struct pt_regs *regs) { struct k_sigaction ka_copy; siginfo_t info; - sigset_t *oldset; int sig, handled_sig = 0; - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - oldset = ¤t->saved_sigmask; - else - oldset = ¤t->blocked; - while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { handled_sig = 1; /* Whee! Actually deliver the signal. */ - if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) { - /* - * a signal was successfully delivered; the saved - * sigmask will have been stored in the signal frame, - * and will be restored by sigreturn, so we can simply - * clear the TIF_RESTORE_SIGMASK flag - */ - if (test_thread_flag(TIF_RESTORE_SIGMASK)) - clear_thread_flag(TIF_RESTORE_SIGMASK); - break; - } + handle_signal(regs, sig, &ka_copy, &info); } /* Did we come from a system call? */ @@ -134,10 +109,8 @@ static int kern_do_signal(struct pt_regs *regs) * if there's no signal to deliver, we just put the saved sigmask * back */ - if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { - clear_thread_flag(TIF_RESTORE_SIGMASK); - sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); - } + if (!handled_sig) + restore_saved_sigmask(); return handled_sig; } @@ -152,15 +125,8 @@ int do_signal(void) long sys_sigsuspend(int history0, int history1, old_sigset_t mask) { sigset_t blocked; - - mask &= _BLOCKABLE; siginitset(&blocked, mask); - set_current_blocked(&blocked); - - current->state = TASK_INTERRUPTIBLE; - schedule(); - set_thread_flag(TIF_RESTORE_SIGMASK); - return -ERESTARTNOHAND; + return sigsuspend(&blocked); } long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss) diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index f5173e1ec3a..05fbeb480e0 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c @@ -34,7 +34,7 @@ void handle_syscall(struct uml_pt_regs *r) result = -ENOSYS; else result = EXECUTE_SYSCALL(syscall, regs); - REGS_SET_SYSCALL_RETURN(r->gp, result); + UPT_SET_SYSCALL_RETURN(r, result); syscall_trace(r, 1); } diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index 6f588e160fb..a02b7e9e6b9 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c @@ -140,7 +140,7 @@ void smp_prepare_boot_cpu(void) set_cpu_online(smp_processor_id(), true); } -int __cpu_up(unsigned int cpu) +int __cpu_up(unsigned int cpu, struct task_struct *tidle) { cpu_set(cpu, smp_commenced_mask); while (!cpu_online(cpu)) diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 7f3d4d86431..f819af951c1 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c @@ -75,6 +75,7 @@ static int do_ops(struct host_vm_change *hvc, int end, default: printk(KERN_ERR "Unknown op type %d in do_ops\n", op->type); + BUG(); break; } } diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index dafc9471595..3be60765c0e 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c @@ -30,6 +30,8 @@ int handle_page_fault(unsigned long address, unsigned long ip, pmd_t *pmd; pte_t *pte; int err = -EFAULT; + unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | + (is_write ? FAULT_FLAG_WRITE : 0); *code_out = SEGV_MAPERR; @@ -40,6 +42,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, if (in_atomic()) goto out_nosemaphore; +retry: down_read(&mm->mmap_sem); vma = find_vma(mm, address); if (!vma) @@ -65,7 +68,11 @@ good_area: do { int fault; - fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0); + fault = handle_mm_fault(mm, vma, address, flags); + + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + goto out_nosemaphore; + if (unlikely(fault & VM_FAULT_ERROR)) { if (fault & VM_FAULT_OOM) { goto out_of_memory; @@ -75,10 +82,17 @@ good_area: } BUG(); } - if (fault & VM_FAULT_MAJOR) - current->maj_flt++; - else - current->min_flt++; + if (flags & FAULT_FLAG_ALLOW_RETRY) { + if (fault & VM_FAULT_MAJOR) + current->maj_flt++; + else + current->min_flt++; + if (fault & VM_FAULT_RETRY) { + flags &= ~FAULT_FLAG_ALLOW_RETRY; + + goto retry; + } + } pgd = pgd_offset(mm, address); pud = pud_offset(pgd, address); diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index ba00eae45aa..4db8770906c 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -10,6 +10,7 @@ #include <linux/seq_file.h> #include <linux/string.h> #include <linux/utsname.h> +#include <linux/sched.h> #include <asm/pgtable.h> #include <asm/processor.h> #include <asm/setup.h> @@ -47,6 +48,10 @@ struct cpuinfo_um boot_cpu_data = { .ipi_pipe = { -1, -1 } }; +union thread_union cpu0_irqstack + __attribute__((__section__(".data..init_irqstack"))) = + { INIT_THREAD_INFO(init_task) }; + unsigned long thread_saved_pc(struct task_struct *task) { /* FIXME: Need to look up userspace_pid by cpu */ diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index c0afff7af4b..90b310d2917 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -48,10 +48,6 @@ __initcall(init_syscall_regs); extern int proc_mm; -int single_count = 0; -int multi_count = 0; -int multi_op_count = 0; - static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) { int n, i; @@ -64,8 +60,6 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) /* FIXME: Need to look up userspace_pid by cpu */ pid = userspace_pid[0]; - multi_count++; - n = ptrace_setregs(pid, syscall_regs); if (n < 0) { printk(UM_KERN_ERR "Registers - \n"); @@ -126,9 +120,6 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall, { unsigned long *stack = check_init_stack(mm_idp, *addr); - if (done && *addr == NULL) - single_count++; - *stack += sizeof(long); stack += *stack / sizeof(long); @@ -141,7 +132,6 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall, *stack++ = args[5]; *stack++ = expected; *stack = 0; - multi_op_count++; if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) < UM_KERN_PAGE_SIZE - 10 * sizeof(long))) { |