diff options
author | Paul Mackerras <paulus@samba.org> | 2007-04-13 03:50:03 +1000 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2007-04-13 03:50:03 +1000 |
commit | e049d1ca3094f3d1d94617f456a9961202f96e3a (patch) | |
tree | a30397ad22f2fbea268bd28fa69c60aad9dfa62a /arch/um | |
parent | edfac96a92b88d3b0b53e3f8231b74beee9ecd1d (diff) | |
parent | 80584ff3b99c36ead7e130e453b3a48b18072d18 (diff) |
Merge branch 'linux-2.6' into for-2.6.22
Diffstat (limited to 'arch/um')
-rw-r--r-- | arch/um/Kconfig | 2 | ||||
-rw-r--r-- | arch/um/drivers/chan_kern.c | 12 | ||||
-rw-r--r-- | arch/um/drivers/daemon_user.c | 17 | ||||
-rw-r--r-- | arch/um/drivers/line.c | 6 | ||||
-rw-r--r-- | arch/um/drivers/mcast_user.c | 10 | ||||
-rw-r--r-- | arch/um/drivers/mconsole_kern.c | 3 | ||||
-rw-r--r-- | arch/um/drivers/ssl.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/stdio_console.c | 2 | ||||
-rw-r--r-- | arch/um/drivers/ubd_kern.c | 13 | ||||
-rw-r--r-- | arch/um/include/mconsole.h | 2 | ||||
-rw-r--r-- | arch/um/include/os.h | 3 | ||||
-rw-r--r-- | arch/um/include/sysdep-x86_64/ptrace.h | 4 | ||||
-rw-r--r-- | arch/um/kernel/irq.c | 1 | ||||
-rw-r--r-- | arch/um/kernel/mem.c | 3 | ||||
-rw-r--r-- | arch/um/os-Linux/process.c | 3 | ||||
-rw-r--r-- | arch/um/os-Linux/signal.c | 5 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/mem.c | 10 | ||||
-rw-r--r-- | arch/um/os-Linux/skas/process.c | 6 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-i386/registers.c | 5 | ||||
-rw-r--r-- | arch/um/os-Linux/sys-x86_64/registers.c | 4 | ||||
-rw-r--r-- | arch/um/scripts/Makefile.rules | 4 | ||||
-rw-r--r-- | arch/um/sys-i386/delay.c | 11 | ||||
-rw-r--r-- | arch/um/sys-i386/ldt.c | 3 | ||||
-rw-r--r-- | arch/um/sys-x86_64/delay.c | 11 | ||||
-rw-r--r-- | arch/um/sys-x86_64/syscalls.c | 6 |
25 files changed, 72 insertions, 76 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index b3a21ba77cd..354cc6b7053 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig @@ -44,7 +44,7 @@ config LOCKDEP_SUPPORT config STACKTRACE_SUPPORT bool - default y + default n config GENERIC_CALIBRATE_DELAY bool diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 7b8baf146ac..9fdfad64953 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c @@ -236,11 +236,11 @@ void free_irqs(void) struct chan *chan; LIST_HEAD(list); struct list_head *ele; + unsigned long flags; - spin_lock_irq(&irqs_to_free_lock); + spin_lock_irqsave(&irqs_to_free_lock, flags); list_splice_init(&irqs_to_free, &list); - INIT_LIST_HEAD(&irqs_to_free); - spin_unlock_irq(&irqs_to_free_lock); + spin_unlock_irqrestore(&irqs_to_free_lock, flags); list_for_each(ele, &list){ chan = list_entry(ele, struct chan, free_list); @@ -255,13 +255,15 @@ void free_irqs(void) static void close_one_chan(struct chan *chan, int delay_free_irq) { + unsigned long flags; + if(!chan->opened) return; if(delay_free_irq){ - spin_lock_irq(&irqs_to_free_lock); + spin_lock_irqsave(&irqs_to_free_lock, flags); list_add(&chan->free_list, &irqs_to_free); - spin_unlock_irq(&irqs_to_free_lock); + spin_unlock_irqrestore(&irqs_to_free_lock, flags); } else { if(chan->input) diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c index 310af0f1e49..021b82c7a75 100644 --- a/arch/um/drivers/daemon_user.c +++ b/arch/um/drivers/daemon_user.c @@ -56,30 +56,31 @@ static int connect_to_switch(struct daemon_data *pri) pri->control = socket(AF_UNIX, SOCK_STREAM, 0); if(pri->control < 0){ + err = -errno; printk("daemon_open : control socket failed, errno = %d\n", - errno); - return(-errno); + -err); + return err; } if(connect(pri->control, (struct sockaddr *) ctl_addr, sizeof(*ctl_addr)) < 0){ - printk("daemon_open : control connect failed, errno = %d\n", - errno); err = -errno; + printk("daemon_open : control connect failed, errno = %d\n", + -err); goto out; } fd = socket(AF_UNIX, SOCK_DGRAM, 0); if(fd < 0){ - printk("daemon_open : data socket failed, errno = %d\n", - errno); err = -errno; + printk("daemon_open : data socket failed, errno = %d\n", + -err); goto out; } if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){ - printk("daemon_open : data bind failed, errno = %d\n", - errno); err = -errno; + printk("daemon_open : data bind failed, errno = %d\n", + -err); goto out_close; } diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index 01d4ab6b0ef..f75d7b05c48 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c @@ -370,10 +370,10 @@ static irqreturn_t line_write_interrupt(int irq, void *data) struct tty_struct *tty = line->tty; int err; - /* Interrupts are enabled here because we registered the interrupt with + /* Interrupts are disabled here because we registered the interrupt with * IRQF_DISABLED (see line_setup_irq).*/ - spin_lock_irq(&line->lock); + spin_lock(&line->lock); err = flush_buffer(line); if (err == 0) { return IRQ_NONE; @@ -381,7 +381,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data) line->head = line->buffer; line->tail = line->buffer; } - spin_unlock_irq(&line->lock); + spin_unlock(&line->lock); if(tty == NULL) return IRQ_NONE; diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 8138f5ea1bf..b827e82884c 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c @@ -50,6 +50,14 @@ static void mcast_user_init(void *data, void *dev) pri->dev = dev; } +static void mcast_remove(void *data) +{ + struct mcast_data *pri = data; + + kfree(pri->mcast_addr); + pri->mcast_addr = NULL; +} + static int mcast_open(void *data) { struct mcast_data *pri = data; @@ -157,7 +165,7 @@ const struct net_user_info mcast_user_info = { .init = mcast_user_init, .open = mcast_open, .close = mcast_close, - .remove = NULL, + .remove = mcast_remove, .set_mtu = mcast_set_mtu, .add_address = NULL, .delete_address = NULL, diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index 178b2eff4a8..65ad2932672 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c @@ -615,6 +615,9 @@ void mconsole_remove(struct mc_request *req) err_msg = NULL; err = (*dev->remove)(n, &err_msg); switch(err){ + case 0: + err_msg = ""; + break; case -ENODEV: if(err_msg == NULL) err_msg = "Device doesn't exist"; diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c index fc22b9bd915..4b382a6e710 100644 --- a/arch/um/drivers/ssl.c +++ b/arch/um/drivers/ssl.c @@ -179,7 +179,7 @@ static struct console ssl_cons = { .write = ssl_console_write, .device = ssl_console_device, .setup = ssl_console_setup, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER|CON_ANYTIME, .index = -1, }; diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c index 7ff0b0fc37e..76d1f1c980e 100644 --- a/arch/um/drivers/stdio_console.c +++ b/arch/um/drivers/stdio_console.c @@ -153,7 +153,7 @@ static struct console stdiocons = { .write = uml_console_write, .device = uml_console_device, .setup = uml_console_setup, - .flags = CON_PRINTBUFFER, + .flags = CON_PRINTBUFFER|CON_ANYTIME, .index = -1, }; diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index f98d26e5138..8bd9204ac1a 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c @@ -109,10 +109,6 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data) static DEFINE_MUTEX(ubd_lock); -/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and - * probably it doesn't make sense even for that. */ -static int do_ubd; - static int ubd_open(struct inode * inode, struct file * filp); static int ubd_release(struct inode * inode, struct file * file); static int ubd_ioctl(struct inode * inode, struct file * file, @@ -169,6 +165,7 @@ struct ubd { struct platform_device pdev; struct request_queue *queue; spinlock_t lock; + int active; }; #define DEFAULT_COW { \ @@ -190,6 +187,7 @@ struct ubd { .shared = 0, \ .cow = DEFAULT_COW, \ .lock = SPIN_LOCK_UNLOCKED, \ + .active = 0, \ } /* Protected by ubd_lock */ @@ -507,7 +505,6 @@ static void ubd_handler(void) struct ubd *dev; int n; - do_ubd = 0; n = os_read_file(thread_fd, &req, sizeof(req)); if(n != sizeof(req)){ printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " @@ -517,6 +514,7 @@ static void ubd_handler(void) rq = req.req; dev = rq->rq_disk->private_data; + dev->active = 0; ubd_finish(rq, req.error); reactivate_fd(thread_fd, UBD_IRQ); @@ -1081,11 +1079,12 @@ static void do_ubd_request(request_queue_t *q) } } else { - if(do_ubd || (req = elv_next_request(q)) == NULL) + struct ubd *dev = q->queuedata; + if(dev->active || (req = elv_next_request(q)) == NULL) return; err = prepare_request(req, &io_req); if(!err){ - do_ubd = 1; + dev->active = 1; n = os_write_file(thread_fd, (char *) &io_req, sizeof(io_req)); if(n != sizeof(io_req)) diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 2666815b6af..b282839c162 100644 --- a/arch/um/include/mconsole.h +++ b/arch/um/include/mconsole.h @@ -12,6 +12,8 @@ #define u32 uint32_t #endif +#include "sysdep/ptrace.h" + #define MCONSOLE_MAGIC (0xcafebabe) #define MCONSOLE_MAX_DATA (512) #define MCONSOLE_VERSION 2 diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 8629bd19149..5c74da41045 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h @@ -192,7 +192,9 @@ extern int os_process_parent(int pid); extern void os_stop_process(int pid); extern void os_kill_process(int pid, int reap_child); extern void os_kill_ptraced_process(int pid, int reap_child); +#ifdef UML_CONFIG_MODE_TT extern void os_usr1_process(int pid); +#endif extern long os_ptrace_ldt(long pid, long addr, long data); extern int os_getpid(void); @@ -261,7 +263,6 @@ extern void block_signals(void); extern void unblock_signals(void); extern int get_signals(void); extern int set_signals(int enable); -extern void os_usr1_signal(int on); /* trap.c */ extern void os_fill_handlinfo(struct kern_handlers h); diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h index 66cb400c2c9..62403bd9966 100644 --- a/arch/um/include/sysdep-x86_64/ptrace.h +++ b/arch/um/include/sysdep-x86_64/ptrace.h @@ -104,10 +104,6 @@ union uml_pt_regs { #endif #ifdef UML_CONFIG_MODE_SKAS struct skas_regs { - /* x86_64 ptrace uses sizeof(user_regs_struct) as its register - * file size, while i386 uses FRAME_SIZE. Therefore, we need - * to use UM_FRAME_SIZE here instead of HOST_FRAME_SIZE. - */ unsigned long regs[MAX_REG_NR]; unsigned long fp[HOST_FP_SIZE]; struct faultinfo faultinfo; diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index 50a288bb875..dbf2f5bc842 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c @@ -142,6 +142,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id) .events = events, .current_events = 0 } ); + err = -EBUSY; spin_lock_irqsave(&irq_lock, flags); for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { if ((irq_fd->fd == fd) && (irq_fd->type == type)) { diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index e85d65deea0..df7d662b98c 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c @@ -64,8 +64,6 @@ static void setup_highmem(unsigned long highmem_start, void mem_init(void) { - max_low_pfn = (high_physmem - uml_physmem) >> PAGE_SHIFT; - /* clear the zero-page */ memset((void *) empty_zero_page, 0, PAGE_SIZE); @@ -80,6 +78,7 @@ void mem_init(void) /* this will put all low memory onto the freelists */ totalram_pages = free_all_bootmem(); + max_low_pfn = totalram_pages; #ifdef CONFIG_HIGHMEM totalhigh_pages = highmem >> PAGE_SHIFT; totalram_pages += totalhigh_pages; diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index c692a192957..76bdd671241 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c @@ -21,6 +21,7 @@ #include "longjmp.h" #include "skas_ptrace.h" #include "kern_constants.h" +#include "uml-config.h" #define ARBITRARY_ADDR -1 #define FAILURE_PID -1 @@ -131,10 +132,12 @@ void os_kill_ptraced_process(int pid, int reap_child) CATCH_EINTR(waitpid(pid, NULL, 0)); } +#ifdef UML_CONFIG_MODE_TT void os_usr1_process(int pid) { kill(pid, SIGUSR1); } +#endif /* Don't use the glibc version, which caches the result in TLS. It misses some * syscalls, and also breaks with clone(), which does not unshare the TLS. diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index b897e8592d7..266768629fe 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c @@ -243,8 +243,3 @@ int set_signals(int enable) return ret; } - -void os_usr1_signal(int on) -{ - change_sig(SIGUSR1, on); -} diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c index b3c11cfa995..9383e8751ae 100644 --- a/arch/um/os-Linux/skas/mem.c +++ b/arch/um/os-Linux/skas/mem.c @@ -48,7 +48,7 @@ int multi_op_count = 0; static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) { unsigned long regs[MAX_REG_NR]; - int n; + int n, i; long ret, offset; unsigned long * data; unsigned long * syscall; @@ -66,9 +66,13 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) (unsigned long) &__syscall_stub_start); n = ptrace_setregs(pid, regs); - if(n < 0) + if(n < 0){ + printk("Registers - \n"); + for(i = 0; i < MAX_REG_NR; i++) + printk("\t%d\t0x%lx\n", i, regs[i]); panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", - n); + -n); + } wait_stub_done(pid, 0, "do_syscall_stub"); diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index dda06789bcb..0564422c155 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c @@ -67,7 +67,7 @@ void wait_stub_done(int pid, int sig, char * fname) if((n < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ - unsigned long regs[HOST_FRAME_SIZE]; + unsigned long regs[MAX_REG_NR]; if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) printk("Failed to get registers from stub, " @@ -76,7 +76,7 @@ void wait_stub_done(int pid, int sig, char * fname) int i; printk("Stub registers -\n"); - for(i = 0; i < HOST_FRAME_SIZE; i++) + for(i = 0; i < ARRAY_SIZE(regs); i++) printk("\t%d - %lx\n", i, regs[i]); } panic("%s : failed to wait for SIGUSR1/SIGTRAP, " @@ -328,7 +328,7 @@ void userspace(union uml_pt_regs *regs) int copy_context_skas0(unsigned long new_stack, int pid) { int err; - unsigned long regs[HOST_FRAME_SIZE]; + unsigned long regs[MAX_REG_NR]; unsigned long fp_regs[HOST_FP_SIZE]; unsigned long current_stack = current_stub_stack(); struct stub_data *data = (struct stub_data *) current_stack; diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c index 79cd93c8c5e..84b44f9cd42 100644 --- a/arch/um/os-Linux/sys-i386/registers.c +++ b/arch/um/os-Linux/sys-i386/registers.c @@ -15,7 +15,7 @@ /* These are set once at boot time and not changed thereafter */ -static unsigned long exec_regs[HOST_FRAME_SIZE]; +static unsigned long exec_regs[MAX_REG_NR]; static unsigned long exec_fp_regs[HOST_FP_SIZE]; static unsigned long exec_fpx_regs[HOST_XFP_SIZE]; static int have_fpx_regs = 1; @@ -101,6 +101,7 @@ void init_registers(int pid) { int err; + memset(exec_regs, 0, sizeof(exec_regs)); err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs); if(err) panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", @@ -124,7 +125,7 @@ void init_registers(int pid) void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { - memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); + memcpy(regs, exec_regs, sizeof(exec_regs)); if(fp_regs != NULL) memcpy(fp_regs, exec_fp_regs, HOST_FP_SIZE * sizeof(unsigned long)); diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c index a2d7e0c603f..e6fc2179d1b 100644 --- a/arch/um/os-Linux/sys-x86_64/registers.c +++ b/arch/um/os-Linux/sys-x86_64/registers.c @@ -14,7 +14,7 @@ /* These are set once at boot time and not changed thereafter */ -static unsigned long exec_regs[HOST_FRAME_SIZE]; +static unsigned long exec_regs[MAX_REG_NR]; static unsigned long exec_fp_regs[HOST_FP_SIZE]; void init_thread_registers(union uml_pt_regs *to) @@ -72,7 +72,7 @@ void init_registers(int pid) void get_safe_registers(unsigned long *regs, unsigned long *fp_regs) { - memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); + memcpy(regs, exec_regs, sizeof(exec_regs)); if(fp_regs != NULL) memcpy(fp_regs, exec_fp_regs, HOST_FP_SIZE * sizeof(unsigned long)); diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 813077fb1e5..a9a4b85ca51 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules @@ -10,7 +10,7 @@ USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) $(USER_OBJS:.o=.%): \ c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(basetarget).o) $(USER_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ - -Dunix -D__unix__ -D__$(SUBARCH)__ + -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) # These are like USER_OBJS but filter USER_CFLAGS through unprofile instead of # using it directly. @@ -19,7 +19,7 @@ UNPROFILE_OBJS := $(foreach file,$(UNPROFILE_OBJS),$(obj)/$(file)) $(UNPROFILE_OBJS:.o=.%): \ c_flags = -Wp,-MD,$(depfile) $(call unprofile,$(USER_CFLAGS)) $(CFLAGS_$(basetarget).o) $(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ - -Dunix -D__unix__ -D__$(SUBARCH)__ + -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) # The stubs and unmap.o can't try to call mcount or update basic block data define unprofile diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c index 2c11b9770e8..d623e074f41 100644 --- a/arch/um/sys-i386/delay.c +++ b/arch/um/sys-i386/delay.c @@ -27,14 +27,3 @@ void __udelay(unsigned long usecs) } EXPORT_SYMBOL(__udelay); - -void __const_udelay(unsigned long usecs) -{ - int i, n; - - n = (loops_per_jiffy * HZ * usecs) / MILLION; - for(i=0;i<n;i++) - cpu_relax(); -} - -EXPORT_SYMBOL(__const_udelay); diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index 4a8b4202ef9..a939a7ef022 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c @@ -394,7 +394,8 @@ static short * host_ldt_entries = NULL; static void ldt_get_host_info(void) { long ret; - struct ldt_entry * ldt, *tmp; + struct ldt_entry * ldt; + short *tmp; int i, size, k, order; spin_lock(&host_ldt_lock); diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c index 137f4446b43..dee5be66da8 100644 --- a/arch/um/sys-x86_64/delay.c +++ b/arch/um/sys-x86_64/delay.c @@ -28,14 +28,3 @@ void __udelay(unsigned long usecs) } EXPORT_SYMBOL(__udelay); - -void __const_udelay(unsigned long usecs) -{ - unsigned long i, n; - - n = (loops_per_jiffy * HZ * usecs) / MILLION; - for(i=0;i<n;i++) - cpu_relax(); -} - -EXPORT_SYMBOL(__const_udelay); diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 01b91f9fa78..b3f6350cac4 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c @@ -103,6 +103,9 @@ long arch_prctl_skas(struct task_struct *task, int code, switch(code){ case ARCH_SET_FS: + current->thread.arch.fs = (unsigned long) ptr; + save_registers(pid, ¤t->thread.regs.regs); + break; case ARCH_SET_GS: save_registers(pid, ¤t->thread.regs.regs); break; @@ -140,9 +143,8 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp, void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) { - if(to->thread.arch.fs == 0) + if((to->thread.arch.fs == 0) || (to->mm == NULL)) return; arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); } - |