aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/.gitignore3
-rw-r--r--arch/um/Makefile2
-rw-r--r--arch/um/drivers/line.c5
-rw-r--r--arch/um/drivers/mconsole_kern.c79
-rw-r--r--arch/um/drivers/mmapper_kern.c11
-rw-r--r--arch/um/drivers/net_kern.c1
-rw-r--r--arch/um/drivers/port_kern.c1
-rw-r--r--arch/um/drivers/random.c3
-rw-r--r--arch/um/drivers/ubd_kern.c41
-rw-r--r--arch/um/include/asm/asm-offsets.h1
-rw-r--r--arch/um/include/asm/dma-mapping.h8
-rw-r--r--arch/um/include/asm/pgtable.h2
-rw-r--r--arch/um/include/asm/ptrace-generic.h2
-rw-r--r--arch/um/kernel/exec.c1
-rw-r--r--arch/um/kernel/exitcode.c43
-rw-r--r--arch/um/kernel/irq.c5
-rw-r--r--arch/um/kernel/mem.c2
-rw-r--r--arch/um/kernel/process.c33
-rw-r--r--arch/um/kernel/ptrace.c70
-rw-r--r--arch/um/kernel/reboot.c1
-rw-r--r--arch/um/kernel/skas/mmu.c1
-rw-r--r--arch/um/kernel/syscall.c73
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/asm/elf.h44
-rw-r--r--arch/um/sys-i386/elfcore.c83
-rw-r--r--arch/um/sys-i386/ldt.c1
-rw-r--r--arch/um/sys-i386/shared/sysdep/syscalls.h6
-rw-r--r--arch/um/sys-i386/sys_call_table.S2
-rw-r--r--arch/um/sys-i386/syscalls.c137
-rw-r--r--arch/um/sys-ppc/asm/elf.h2
-rw-r--r--arch/um/sys-x86_64/Makefile3
-rw-r--r--arch/um/sys-x86_64/asm/elf.h1
-rw-r--r--arch/um/sys-x86_64/syscall_table.c5
-rw-r--r--arch/um/sys-x86_64/syscalls.c14
34 files changed, 230 insertions, 458 deletions
diff --git a/arch/um/.gitignore b/arch/um/.gitignore
new file mode 100644
index 000000000000..a73d3a1cc746
--- /dev/null
+++ b/arch/um/.gitignore
@@ -0,0 +1,3 @@
1kernel/config.c
2kernel/config.tmp
3kernel/vmlinux.lds
diff --git a/arch/um/Makefile b/arch/um/Makefile
index fc633dbacf84..fab8121d2b32 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -149,6 +149,6 @@ $(SHARED_HEADERS)/user_constants.h: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.s
149 149
150$(SHARED_HEADERS)/kern_constants.h: 150$(SHARED_HEADERS)/kern_constants.h:
151 $(Q)mkdir -p $(dir $@) 151 $(Q)mkdir -p $(dir $@)
152 $(Q)echo '#include "../../../../include/asm/asm-offsets.h"' >$@ 152 $(Q)echo '#include "../../../../include/generated/asm-offsets.h"' >$@
153 153
154export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH 154export SUBARCH USER_CFLAGS CFLAGS_NO_HARDENING OS HEADER_ARCH DEV_NULL_PATH
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index cf8a97f34518..7a656bd8bd3c 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -6,6 +6,7 @@
6#include "linux/irqreturn.h" 6#include "linux/irqreturn.h"
7#include "linux/kd.h" 7#include "linux/kd.h"
8#include "linux/sched.h" 8#include "linux/sched.h"
9#include "linux/slab.h"
9#include "chan_kern.h" 10#include "chan_kern.h"
10#include "irq_kern.h" 11#include "irq_kern.h"
11#include "irq_user.h" 12#include "irq_user.h"
@@ -18,10 +19,10 @@ static irqreturn_t line_interrupt(int irq, void *data)
18{ 19{
19 struct chan *chan = data; 20 struct chan *chan = data;
20 struct line *line = chan->line; 21 struct line *line = chan->line;
21 struct tty_struct *tty = line->tty; 22 struct tty_struct *tty;
22 23
23 if (line) 24 if (line)
24 chan_interrupt(&line->chan_list, &line->task, tty, irq); 25 chan_interrupt(&line->chan_list, &line->task, line->tty, irq);
25 return IRQ_HANDLED; 26 return IRQ_HANDLED;
26} 27}
27 28
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index e14629c87de4..de317d0c3294 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -6,6 +6,7 @@
6 6
7#include <linux/console.h> 7#include <linux/console.h>
8#include <linux/ctype.h> 8#include <linux/ctype.h>
9#include <linux/string.h>
9#include <linux/interrupt.h> 10#include <linux/interrupt.h>
10#include <linux/list.h> 11#include <linux/list.h>
11#include <linux/mm.h> 12#include <linux/mm.h>
@@ -124,50 +125,36 @@ void mconsole_log(struct mc_request *req)
124void mconsole_proc(struct mc_request *req) 125void mconsole_proc(struct mc_request *req)
125{ 126{
126 struct nameidata nd; 127 struct nameidata nd;
127 struct file_system_type *proc; 128 struct vfsmount *mnt = current->nsproxy->pid_ns->proc_mnt;
128 struct super_block *super;
129 struct file *file; 129 struct file *file;
130 int n, err; 130 int n, err;
131 char *ptr = req->request.data, *buf; 131 char *ptr = req->request.data, *buf;
132 mm_segment_t old_fs = get_fs();
132 133
133 ptr += strlen("proc"); 134 ptr += strlen("proc");
134 while (isspace(*ptr)) ptr++; 135 ptr = skip_spaces(ptr);
135 136
136 proc = get_fs_type("proc"); 137 err = vfs_path_lookup(mnt->mnt_root, mnt, ptr, LOOKUP_FOLLOW, &nd);
137 if (proc == NULL) { 138 if (err) {
138 mconsole_reply(req, "procfs not registered", 1, 0); 139 mconsole_reply(req, "Failed to look up file", 1, 0);
139 goto out; 140 goto out;
140 } 141 }
141 142
142 super = (*proc->get_sb)(proc, 0, NULL, NULL); 143 err = may_open(&nd.path, MAY_READ, O_RDONLY);
143 put_filesystem(proc); 144 if (result) {
144 if (super == NULL) { 145 mconsole_reply(req, "Failed to open file", 1, 0);
145 mconsole_reply(req, "Failed to get procfs superblock", 1, 0); 146 path_put(&nd.path);
146 goto out; 147 goto out;
147 } 148 }
148 up_write(&super->s_umount);
149
150 nd.path.dentry = super->s_root;
151 nd.path.mnt = NULL;
152 nd.flags = O_RDONLY + 1;
153 nd.last_type = LAST_ROOT;
154
155 /* START: it was experienced that the stability problems are closed
156 * if commenting out these two calls + the below read cycle. To
157 * make UML crash again, it was enough to readd either one.*/
158 err = link_path_walk(ptr, &nd);
159 if (err) {
160 mconsole_reply(req, "Failed to look up file", 1, 0);
161 goto out_kill;
162 }
163 149
164 file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY, 150 file = dentry_open(nd.path.dentry, nd.path.mnt, O_RDONLY,
165 current_cred()); 151 current_cred());
152 err = PTR_ERR(file);
166 if (IS_ERR(file)) { 153 if (IS_ERR(file)) {
167 mconsole_reply(req, "Failed to open file", 1, 0); 154 mconsole_reply(req, "Failed to open file", 1, 0);
168 goto out_kill; 155 path_put(&nd.path);
156 goto out;
169 } 157 }
170 /*END*/
171 158
172 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 159 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
173 if (buf == NULL) { 160 if (buf == NULL) {
@@ -175,10 +162,13 @@ void mconsole_proc(struct mc_request *req)
175 goto out_fput; 162 goto out_fput;
176 } 163 }
177 164
178 if ((file->f_op != NULL) && (file->f_op->read != NULL)) { 165 if (file->f_op->read) {
179 do { 166 do {
180 n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 167 loff_t pos;
181 &file->f_pos); 168 set_fs(KERNEL_DS);
169 n = vfs_read(file, buf, PAGE_SIZE - 1, &pos);
170 file_pos_write(file, pos);
171 set_fs(old_fs);
182 if (n >= 0) { 172 if (n >= 0) {
183 buf[n] = '\0'; 173 buf[n] = '\0';
184 mconsole_reply(req, buf, 0, (n > 0)); 174 mconsole_reply(req, buf, 0, (n > 0));
@@ -196,8 +186,6 @@ void mconsole_proc(struct mc_request *req)
196 kfree(buf); 186 kfree(buf);
197 out_fput: 187 out_fput:
198 fput(file); 188 fput(file);
199 out_kill:
200 deactivate_super(super);
201 out: ; 189 out: ;
202} 190}
203#endif 191#endif
@@ -212,8 +200,7 @@ void mconsole_proc(struct mc_request *req)
212 char *ptr = req->request.data; 200 char *ptr = req->request.data;
213 201
214 ptr += strlen("proc"); 202 ptr += strlen("proc");
215 while (isspace(*ptr)) 203 ptr = skip_spaces(ptr);
216 ptr++;
217 snprintf(path, sizeof(path), "/proc/%s", ptr); 204 snprintf(path, sizeof(path), "/proc/%s", ptr);
218 205
219 fd = sys_open(path, 0, 0); 206 fd = sys_open(path, 0, 0);
@@ -560,8 +547,7 @@ void mconsole_config(struct mc_request *req)
560 int err; 547 int err;
561 548
562 ptr += strlen("config"); 549 ptr += strlen("config");
563 while (isspace(*ptr)) 550 ptr = skip_spaces(ptr);
564 ptr++;
565 dev = mconsole_find_dev(ptr); 551 dev = mconsole_find_dev(ptr);
566 if (dev == NULL) { 552 if (dev == NULL) {
567 mconsole_reply(req, "Bad configuration option", 1, 0); 553 mconsole_reply(req, "Bad configuration option", 1, 0);
@@ -588,7 +574,7 @@ void mconsole_remove(struct mc_request *req)
588 int err, start, end, n; 574 int err, start, end, n;
589 575
590 ptr += strlen("remove"); 576 ptr += strlen("remove");
591 while (isspace(*ptr)) ptr++; 577 ptr = skip_spaces(ptr);
592 dev = mconsole_find_dev(ptr); 578 dev = mconsole_find_dev(ptr);
593 if (dev == NULL) { 579 if (dev == NULL) {
594 mconsole_reply(req, "Bad remove option", 1, 0); 580 mconsole_reply(req, "Bad remove option", 1, 0);
@@ -712,7 +698,7 @@ void mconsole_sysrq(struct mc_request *req)
712 char *ptr = req->request.data; 698 char *ptr = req->request.data;
713 699
714 ptr += strlen("sysrq"); 700 ptr += strlen("sysrq");
715 while (isspace(*ptr)) ptr++; 701 ptr = skip_spaces(ptr);
716 702
717 /* 703 /*
718 * With 'b', the system will shut down without a chance to reply, 704 * With 'b', the system will shut down without a chance to reply,
@@ -757,8 +743,7 @@ void mconsole_stack(struct mc_request *req)
757 */ 743 */
758 744
759 ptr += strlen("stack"); 745 ptr += strlen("stack");
760 while (isspace(*ptr)) 746 ptr = skip_spaces(ptr);
761 ptr++;
762 747
763 /* 748 /*
764 * Should really check for multiple pids or reject bad args here 749 * Should really check for multiple pids or reject bad args here
@@ -833,8 +818,8 @@ static int __init mconsole_init(void)
833 818
834__initcall(mconsole_init); 819__initcall(mconsole_init);
835 820
836static int write_proc_mconsole(struct file *file, const char __user *buffer, 821static ssize_t mconsole_proc_write(struct file *file,
837 unsigned long count, void *data) 822 const char __user *buffer, size_t count, loff_t *pos)
838{ 823{
839 char *buf; 824 char *buf;
840 825
@@ -855,6 +840,11 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer,
855 return count; 840 return count;
856} 841}
857 842
843static const struct file_operations mconsole_proc_fops = {
844 .owner = THIS_MODULE,
845 .write = mconsole_proc_write,
846};
847
858static int create_proc_mconsole(void) 848static int create_proc_mconsole(void)
859{ 849{
860 struct proc_dir_entry *ent; 850 struct proc_dir_entry *ent;
@@ -862,15 +852,12 @@ static int create_proc_mconsole(void)
862 if (notify_socket == NULL) 852 if (notify_socket == NULL)
863 return 0; 853 return 0;
864 854
865 ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); 855 ent = proc_create("mconsole", 0200, NULL, &mconsole_proc_fops);
866 if (ent == NULL) { 856 if (ent == NULL) {
867 printk(KERN_INFO "create_proc_mconsole : create_proc_entry " 857 printk(KERN_INFO "create_proc_mconsole : create_proc_entry "
868 "failed\n"); 858 "failed\n");
869 return 0; 859 return 0;
870 } 860 }
871
872 ent->read_proc = NULL;
873 ent->write_proc = write_proc_mconsole;
874 return 0; 861 return 0;
875} 862}
876 863
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index eb240323c40a..d22f9e5c0eac 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -16,7 +16,7 @@
16#include <linux/miscdevice.h> 16#include <linux/miscdevice.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/mm.h> 18#include <linux/mm.h>
19#include <linux/smp_lock.h> 19
20#include <asm/uaccess.h> 20#include <asm/uaccess.h>
21#include "mem_user.h" 21#include "mem_user.h"
22 22
@@ -78,7 +78,6 @@ out:
78 78
79static int mmapper_open(struct inode *inode, struct file *file) 79static int mmapper_open(struct inode *inode, struct file *file)
80{ 80{
81 cycle_kernel_lock();
82 return 0; 81 return 0;
83} 82}
84 83
@@ -115,18 +114,16 @@ static int __init mmapper_init(void)
115 v_buf = (char *) find_iomem("mmapper", &mmapper_size); 114 v_buf = (char *) find_iomem("mmapper", &mmapper_size);
116 if (mmapper_size == 0) { 115 if (mmapper_size == 0) {
117 printk(KERN_ERR "mmapper_init - find_iomem failed\n"); 116 printk(KERN_ERR "mmapper_init - find_iomem failed\n");
118 goto out; 117 return -ENODEV;
119 } 118 }
119 p_buf = __pa(v_buf);
120 120
121 err = misc_register(&mmapper_dev); 121 err = misc_register(&mmapper_dev);
122 if (err) { 122 if (err) {
123 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", 123 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
124 err); 124 err);
125 goto out; 125 return err;;
126 } 126 }
127
128 p_buf = __pa(v_buf);
129out:
130 return 0; 127 return 0;
131} 128}
132 129
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index a74245ae3a84..f05372694233 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -16,6 +16,7 @@
16#include <linux/platform_device.h> 16#include <linux/platform_device.h>
17#include <linux/rtnetlink.h> 17#include <linux/rtnetlink.h>
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/slab.h>
19#include <linux/spinlock.h> 20#include <linux/spinlock.h>
20#include "init.h" 21#include "init.h"
21#include "irq_kern.h" 22#include "irq_kern.h"
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 4ebc8a34738f..a11573be0961 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -7,6 +7,7 @@
7#include "linux/interrupt.h" 7#include "linux/interrupt.h"
8#include "linux/list.h" 8#include "linux/list.h"
9#include "linux/mutex.h" 9#include "linux/mutex.h"
10#include "linux/slab.h"
10#include "linux/workqueue.h" 11#include "linux/workqueue.h"
11#include "asm/atomic.h" 12#include "asm/atomic.h"
12#include "init.h" 13#include "init.h"
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 6eabb7022a2d..4949044773ba 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -7,7 +7,6 @@
7 * of the GNU General Public License, incorporated herein by reference. 7 * of the GNU General Public License, incorporated herein by reference.
8 */ 8 */
9#include <linux/sched.h> 9#include <linux/sched.h>
10#include <linux/smp_lock.h>
11#include <linux/module.h> 10#include <linux/module.h>
12#include <linux/fs.h> 11#include <linux/fs.h>
13#include <linux/interrupt.h> 12#include <linux/interrupt.h>
@@ -34,8 +33,6 @@ static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
34 33
35static int rng_dev_open (struct inode *inode, struct file *filp) 34static int rng_dev_open (struct inode *inode, struct file *filp)
36{ 35{
37 cycle_kernel_lock();
38
39 /* enforce read-only access to this chrdev */ 36 /* enforce read-only access to this chrdev */
40 if ((filp->f_mode & FMODE_READ) == 0) 37 if ((filp->f_mode & FMODE_READ) == 0)
41 return -EINVAL; 38 return -EINVAL;
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 635d16d90a80..da992a3ad6b7 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -27,9 +27,11 @@
27#include "linux/init.h" 27#include "linux/init.h"
28#include "linux/cdrom.h" 28#include "linux/cdrom.h"
29#include "linux/proc_fs.h" 29#include "linux/proc_fs.h"
30#include "linux/seq_file.h"
30#include "linux/ctype.h" 31#include "linux/ctype.h"
31#include "linux/capability.h" 32#include "linux/capability.h"
32#include "linux/mm.h" 33#include "linux/mm.h"
34#include "linux/slab.h"
33#include "linux/vmalloc.h" 35#include "linux/vmalloc.h"
34#include "linux/blkpg.h" 36#include "linux/blkpg.h"
35#include "linux/genhd.h" 37#include "linux/genhd.h"
@@ -200,23 +202,25 @@ static void make_proc_ide(void)
200 proc_ide = proc_mkdir("ide0", proc_ide_root); 202 proc_ide = proc_mkdir("ide0", proc_ide_root);
201} 203}
202 204
203static int proc_ide_read_media(char *page, char **start, off_t off, int count, 205static int fake_ide_media_proc_show(struct seq_file *m, void *v)
204 int *eof, void *data)
205{ 206{
206 int len; 207 seq_puts(m, "disk\n");
207 208 return 0;
208 strcpy(page, "disk\n"); 209}
209 len = strlen("disk\n"); 210
210 len -= off; 211static int fake_ide_media_proc_open(struct inode *inode, struct file *file)
211 if (len < count){ 212{
212 *eof = 1; 213 return single_open(file, fake_ide_media_proc_show, NULL);
213 if (len <= 0) return 0;
214 }
215 else len = count;
216 *start = page + off;
217 return len;
218} 214}
219 215
216static const struct file_operations fake_ide_media_proc_fops = {
217 .owner = THIS_MODULE,
218 .open = fake_ide_media_proc_open,
219 .read = seq_read,
220 .llseek = seq_lseek,
221 .release = single_release,
222};
223
220static void make_ide_entries(const char *dev_name) 224static void make_ide_entries(const char *dev_name)
221{ 225{
222 struct proc_dir_entry *dir, *ent; 226 struct proc_dir_entry *dir, *ent;
@@ -227,11 +231,8 @@ static void make_ide_entries(const char *dev_name)
227 dir = proc_mkdir(dev_name, proc_ide); 231 dir = proc_mkdir(dev_name, proc_ide);
228 if(!dir) return; 232 if(!dir) return;
229 233
230 ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir); 234 ent = proc_create("media", S_IRUGO, dir, &fake_ide_media_proc_fops);
231 if(!ent) return; 235 if(!ent) return;
232 ent->data = NULL;
233 ent->read_proc = proc_ide_read_media;
234 ent->write_proc = NULL;
235 snprintf(name, sizeof(name), "ide0/%s", dev_name); 236 snprintf(name, sizeof(name), "ide0/%s", dev_name);
236 proc_symlink(dev_name, proc_ide_root, name); 237 proc_symlink(dev_name, proc_ide_root, name);
237} 238}
@@ -747,7 +748,7 @@ static int ubd_open_dev(struct ubd *ubd_dev)
747 ubd_dev->fd = fd; 748 ubd_dev->fd = fd;
748 749
749 if(ubd_dev->cow.file != NULL){ 750 if(ubd_dev->cow.file != NULL){
750 blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); 751 blk_queue_max_hw_sectors(ubd_dev->queue, 8 * sizeof(long));
751 752
752 err = -ENOMEM; 753 err = -ENOMEM;
753 ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len); 754 ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
@@ -849,7 +850,7 @@ static int ubd_add(int n, char **error_out)
849 } 850 }
850 ubd_dev->queue->queuedata = ubd_dev; 851 ubd_dev->queue->queuedata = ubd_dev;
851 852
852 blk_queue_max_hw_segments(ubd_dev->queue, MAX_SG); 853 blk_queue_max_segments(ubd_dev->queue, MAX_SG);
853 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]); 854 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
854 if(err){ 855 if(err){
855 *error_out = "Failed to register device"; 856 *error_out = "Failed to register device";
diff --git a/arch/um/include/asm/asm-offsets.h b/arch/um/include/asm/asm-offsets.h
new file mode 100644
index 000000000000..d370ee36a182
--- /dev/null
+++ b/arch/um/include/asm/asm-offsets.h
@@ -0,0 +1 @@
#include <generated/asm-offsets.h>
diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h
index 378de4bbf49f..b948c14a7867 100644
--- a/arch/um/include/asm/dma-mapping.h
+++ b/arch/um/include/asm/dma-mapping.h
@@ -104,14 +104,6 @@ dma_get_cache_alignment(void)
104} 104}
105 105
106static inline void 106static inline void
107dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
108 unsigned long offset, size_t size,
109 enum dma_data_direction direction)
110{
111 BUG();
112}
113
114static inline void
115dma_cache_sync(struct device *dev, void *vaddr, size_t size, 107dma_cache_sync(struct device *dev, void *vaddr, size_t size,
116 enum dma_data_direction direction) 108 enum dma_data_direction direction)
117{ 109{
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
index 9ce3f165111a..a9f7251b4a8d 100644
--- a/arch/um/include/asm/pgtable.h
+++ b/arch/um/include/asm/pgtable.h
@@ -345,7 +345,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
345struct mm_struct; 345struct mm_struct;
346extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr); 346extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
347 347
348#define update_mmu_cache(vma,address,pte) do ; while (0) 348#define update_mmu_cache(vma,address,ptep) do ; while (0)
349 349
350/* Encode and de-code a swap entry */ 350/* Encode and de-code a swap entry */
351#define __swp_type(x) (((x).val >> 4) & 0x3f) 351#define __swp_type(x) (((x).val >> 4) & 0x3f)
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index 6c8899013c92..2cd899f75a3c 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -16,6 +16,8 @@ struct pt_regs {
16 struct uml_pt_regs regs; 16 struct uml_pt_regs regs;
17}; 17};
18 18
19#define arch_has_single_step() (1)
20
19#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS } 21#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
20 22
21#define PT_REGS_IP(r) UPT_IP(&(r)->regs) 23#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index fda30d21fb90..97974c1bdd12 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -8,6 +8,7 @@
8#include "linux/smp_lock.h" 8#include "linux/smp_lock.h"
9#include "linux/ptrace.h" 9#include "linux/ptrace.h"
10#include "linux/sched.h" 10#include "linux/sched.h"
11#include "linux/slab.h"
11#include "asm/current.h" 12#include "asm/current.h"
12#include "asm/processor.h" 13#include "asm/processor.h"
13#include "asm/uaccess.h" 14#include "asm/uaccess.h"
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index 6540d2c9fbb7..829df49dee99 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -6,7 +6,9 @@
6#include <linux/ctype.h> 6#include <linux/ctype.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/kernel.h> 8#include <linux/kernel.h>
9#include <linux/module.h>
9#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/seq_file.h>
10#include <linux/types.h> 12#include <linux/types.h>
11#include <asm/uaccess.h> 13#include <asm/uaccess.h>
12 14
@@ -16,30 +18,26 @@
16 */ 18 */
17int uml_exitcode = 0; 19int uml_exitcode = 0;
18 20
19static int read_proc_exitcode(char *page, char **start, off_t off, 21static int exitcode_proc_show(struct seq_file *m, void *v)
20 int count, int *eof, void *data)
21{ 22{
22 int len, val; 23 int val;
23 24
24 /* 25 /*
25 * Save uml_exitcode in a local so that we don't need to guarantee 26 * Save uml_exitcode in a local so that we don't need to guarantee
26 * that sprintf accesses it atomically. 27 * that sprintf accesses it atomically.
27 */ 28 */
28 val = uml_exitcode; 29 val = uml_exitcode;
29 len = sprintf(page, "%d\n", val); 30 seq_printf(m, "%d\n", val);
30 len -= off; 31 return 0;
31 if (len <= off+count) 32}
32 *eof = 1; 33
33 *start = page + off; 34static int exitcode_proc_open(struct inode *inode, struct file *file)
34 if (len > count) 35{
35 len = count; 36 return single_open(file, exitcode_proc_show, NULL);
36 if (len < 0)
37 len = 0;
38 return len;
39} 37}
40 38
41static int write_proc_exitcode(struct file *file, const char __user *buffer, 39static ssize_t exitcode_proc_write(struct file *file,
42 unsigned long count, void *data) 40 const char __user *buffer, size_t count, loff_t *pos)
43{ 41{
44 char *end, buf[sizeof("nnnnn\0")]; 42 char *end, buf[sizeof("nnnnn\0")];
45 int tmp; 43 int tmp;
@@ -55,20 +53,25 @@ static int write_proc_exitcode(struct file *file, const char __user *buffer,
55 return count; 53 return count;
56} 54}
57 55
56static const struct file_operations exitcode_proc_fops = {
57 .owner = THIS_MODULE,
58 .open = exitcode_proc_open,
59 .read = seq_read,
60 .llseek = seq_lseek,
61 .release = single_release,
62 .write = exitcode_proc_write,
63};
64
58static int make_proc_exitcode(void) 65static int make_proc_exitcode(void)
59{ 66{
60 struct proc_dir_entry *ent; 67 struct proc_dir_entry *ent;
61 68
62 ent = create_proc_entry("exitcode", 0600, NULL); 69 ent = proc_create("exitcode", 0600, NULL, &exitcode_proc_fops);
63 if (ent == NULL) { 70 if (ent == NULL) {
64 printk(KERN_WARNING "make_proc_exitcode : Failed to register " 71 printk(KERN_WARNING "make_proc_exitcode : Failed to register "
65 "/proc/exitcode\n"); 72 "/proc/exitcode\n");
66 return 0; 73 return 0;
67 } 74 }
68
69 ent->read_proc = read_proc_exitcode;
70 ent->write_proc = write_proc_exitcode;
71
72 return 0; 75 return 0;
73} 76}
74 77
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 039270b9b73b..a3f0b04d7101 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -12,6 +12,7 @@
12#include "linux/module.h" 12#include "linux/module.h"
13#include "linux/sched.h" 13#include "linux/sched.h"
14#include "linux/seq_file.h" 14#include "linux/seq_file.h"
15#include "linux/slab.h"
15#include "as-layout.h" 16#include "as-layout.h"
16#include "kern_util.h" 17#include "kern_util.h"
17#include "os.h" 18#include "os.h"
@@ -34,7 +35,7 @@ int show_interrupts(struct seq_file *p, void *v)
34 } 35 }
35 36
36 if (i < NR_IRQS) { 37 if (i < NR_IRQS) {
37 spin_lock_irqsave(&irq_desc[i].lock, flags); 38 raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
38 action = irq_desc[i].action; 39 action = irq_desc[i].action;
39 if (!action) 40 if (!action)
40 goto skip; 41 goto skip;
@@ -53,7 +54,7 @@ int show_interrupts(struct seq_file *p, void *v)
53 54
54 seq_putc(p, '\n'); 55 seq_putc(p, '\n');
55skip: 56skip:
56 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 57 raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
57 } else if (i == NR_IRQS) 58 } else if (i == NR_IRQS)
58 seq_putc(p, '\n'); 59 seq_putc(p, '\n');
59 60
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index a5d5e70cf6f5..8137ccc9635b 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -5,10 +5,10 @@
5 5
6#include <linux/stddef.h> 6#include <linux/stddef.h>
7#include <linux/bootmem.h> 7#include <linux/bootmem.h>
8#include <linux/gfp.h>
9#include <linux/highmem.h> 8#include <linux/highmem.h>
10#include <linux/mm.h> 9#include <linux/mm.h>
11#include <linux/swap.h> 10#include <linux/swap.h>
11#include <linux/slab.h>
12#include <asm/fixmap.h> 12#include <asm/fixmap.h>
13#include <asm/page.h> 13#include <asm/page.h>
14#include "as-layout.h" 14#include "as-layout.h"
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 4a28a1568d85..fab4371184f6 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -7,13 +7,15 @@
7#include <linux/stddef.h> 7#include <linux/stddef.h>
8#include <linux/err.h> 8#include <linux/err.h>
9#include <linux/hardirq.h> 9#include <linux/hardirq.h>
10#include <linux/gfp.h>
11#include <linux/mm.h> 10#include <linux/mm.h>
11#include <linux/module.h>
12#include <linux/personality.h> 12#include <linux/personality.h>
13#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
14#include <linux/ptrace.h> 14#include <linux/ptrace.h>
15#include <linux/random.h> 15#include <linux/random.h>
16#include <linux/slab.h>
16#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/seq_file.h>
17#include <linux/tick.h> 19#include <linux/tick.h>
18#include <linux/threads.h> 20#include <linux/threads.h>
19#include <asm/current.h> 21#include <asm/current.h>
@@ -336,16 +338,19 @@ int get_using_sysemu(void)
336 return atomic_read(&using_sysemu); 338 return atomic_read(&using_sysemu);
337} 339}
338 340
339static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) 341static int sysemu_proc_show(struct seq_file *m, void *v)
340{ 342{
341 if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) 343 seq_printf(m, "%d\n", get_using_sysemu());
342 /* No overflow */ 344 return 0;
343 *eof = 1; 345}
344 346
345 return strlen(buf); 347static int sysemu_proc_open(struct inode *inode, struct file *file)
348{
349 return single_open(file, sysemu_proc_show, NULL);
346} 350}
347 351
348static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned long count,void *data) 352static ssize_t sysemu_proc_write(struct file *file, const char __user *buf,
353 size_t count, loff_t *pos)
349{ 354{
350 char tmp[2]; 355 char tmp[2];
351 356
@@ -358,13 +363,22 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned
358 return count; 363 return count;
359} 364}
360 365
366static const struct file_operations sysemu_proc_fops = {
367 .owner = THIS_MODULE,
368 .open = sysemu_proc_open,
369 .read = seq_read,
370 .llseek = seq_lseek,
371 .release = single_release,
372 .write = sysemu_proc_write,
373};
374
361int __init make_proc_sysemu(void) 375int __init make_proc_sysemu(void)
362{ 376{
363 struct proc_dir_entry *ent; 377 struct proc_dir_entry *ent;
364 if (!sysemu_supported) 378 if (!sysemu_supported)
365 return 0; 379 return 0;
366 380
367 ent = create_proc_entry("sysemu", 0600, NULL); 381 ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_fops);
368 382
369 if (ent == NULL) 383 if (ent == NULL)
370 { 384 {
@@ -372,9 +386,6 @@ int __init make_proc_sysemu(void)
372 return 0; 386 return 0;
373 } 387 }
374 388
375 ent->read_proc = proc_read_sysemu;
376 ent->write_proc = proc_write_sysemu;
377
378 return 0; 389 return 0;
379} 390}
380 391
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 8e3d69e4fcb5..484509948ee9 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -12,16 +12,25 @@
12#endif 12#endif
13#include "skas_ptrace.h" 13#include "skas_ptrace.h"
14 14
15static inline void set_singlestepping(struct task_struct *child, int on) 15
16
17void user_enable_single_step(struct task_struct *child)
16{ 18{
17 if (on) 19 child->ptrace |= PT_DTRACE;
18 child->ptrace |= PT_DTRACE;
19 else
20 child->ptrace &= ~PT_DTRACE;
21 child->thread.singlestep_syscall = 0; 20 child->thread.singlestep_syscall = 0;
22 21
23#ifdef SUBARCH_SET_SINGLESTEPPING 22#ifdef SUBARCH_SET_SINGLESTEPPING
24 SUBARCH_SET_SINGLESTEPPING(child, on); 23 SUBARCH_SET_SINGLESTEPPING(child, 1);
24#endif
25}
26
27void user_disable_single_step(struct task_struct *child)
28{
29 child->ptrace &= ~PT_DTRACE;
30 child->thread.singlestep_syscall = 0;
31
32#ifdef SUBARCH_SET_SINGLESTEPPING
33 SUBARCH_SET_SINGLESTEPPING(child, 0);
25#endif 34#endif
26} 35}
27 36
@@ -30,7 +39,7 @@ static inline void set_singlestepping(struct task_struct *child, int on)
30 */ 39 */
31void ptrace_disable(struct task_struct *child) 40void ptrace_disable(struct task_struct *child)
32{ 41{
33 set_singlestepping(child,0); 42 user_disable_single_step(child);
34} 43}
35 44
36extern int peek_user(struct task_struct * child, long addr, long data); 45extern int peek_user(struct task_struct * child, long addr, long data);
@@ -69,53 +78,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
69 ret = -EIO; 78 ret = -EIO;
70 break; 79 break;
71 80
72 /* continue and stop at next (return from) syscall */
73 case PTRACE_SYSCALL:
74 /* restart after signal. */
75 case PTRACE_CONT: {
76 ret = -EIO;
77 if (!valid_signal(data))
78 break;
79
80 set_singlestepping(child, 0);
81 if (request == PTRACE_SYSCALL)
82 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
83 else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
84 child->exit_code = data;
85 wake_up_process(child);
86 ret = 0;
87 break;
88 }
89
90/*
91 * make the child exit. Best I can do is send it a sigkill.
92 * perhaps it should be put in the status that it wants to
93 * exit.
94 */
95 case PTRACE_KILL: {
96 ret = 0;
97 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
98 break;
99
100 set_singlestepping(child, 0);
101 child->exit_code = SIGKILL;
102 wake_up_process(child);
103 break;
104 }
105
106 case PTRACE_SINGLESTEP: { /* set the trap flag. */
107 ret = -EIO;
108 if (!valid_signal(data))
109 break;
110 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
111 set_singlestepping(child, 1);
112 child->exit_code = data;
113 /* give it a chance to run. */
114 wake_up_process(child);
115 ret = 0;
116 break;
117 }
118
119#ifdef PTRACE_GETREGS 81#ifdef PTRACE_GETREGS
120 case PTRACE_GETREGS: { /* Get all gp regs from the child. */ 82 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
121 if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) { 83 if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 00197d3d21ec..869bec9f2516 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -4,6 +4,7 @@
4 */ 4 */
5 5
6#include "linux/sched.h" 6#include "linux/sched.h"
7#include "linux/slab.h"
7#include "kern_util.h" 8#include "kern_util.h"
8#include "os.h" 9#include "os.h"
9#include "skas.h" 10#include "skas.h"
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 8bfd1e905812..3d099f974785 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -5,6 +5,7 @@
5 5
6#include "linux/mm.h" 6#include "linux/mm.h"
7#include "linux/sched.h" 7#include "linux/sched.h"
8#include "linux/slab.h"
8#include "asm/pgalloc.h" 9#include "asm/pgalloc.h"
9#include "asm/pgtable.h" 10#include "asm/pgtable.h"
10#include "as-layout.h" 11#include "as-layout.h"
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index a4625c7b2bf9..4393173923f5 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -8,6 +8,7 @@
8#include "linux/mm.h" 8#include "linux/mm.h"
9#include "linux/sched.h" 9#include "linux/sched.h"
10#include "linux/utsname.h" 10#include "linux/utsname.h"
11#include "linux/syscalls.h"
11#include "asm/current.h" 12#include "asm/current.h"
12#include "asm/mman.h" 13#include "asm/mman.h"
13#include "asm/uaccess.h" 14#include "asm/uaccess.h"
@@ -37,31 +38,6 @@ long sys_vfork(void)
37 return ret; 38 return ret;
38} 39}
39 40
40/* common code for old and new mmaps */
41long sys_mmap2(unsigned long addr, unsigned long len,
42 unsigned long prot, unsigned long flags,
43 unsigned long fd, unsigned long pgoff)
44{
45 long error = -EBADF;
46 struct file * file = NULL;
47
48 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
49 if (!(flags & MAP_ANONYMOUS)) {
50 file = fget(fd);
51 if (!file)
52 goto out;
53 }
54
55 down_write(&current->mm->mmap_sem);
56 error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
57 up_write(&current->mm->mmap_sem);
58
59 if (file)
60 fput(file);
61 out:
62 return error;
63}
64
65long old_mmap(unsigned long addr, unsigned long len, 41long old_mmap(unsigned long addr, unsigned long len,
66 unsigned long prot, unsigned long flags, 42 unsigned long prot, unsigned long flags,
67 unsigned long fd, unsigned long offset) 43 unsigned long fd, unsigned long offset)
@@ -70,56 +46,11 @@ long old_mmap(unsigned long addr, unsigned long len,
70 if (offset & ~PAGE_MASK) 46 if (offset & ~PAGE_MASK)
71 goto out; 47 goto out;
72 48
73 err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); 49 err = sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
74 out: 50 out:
75 return err; 51 return err;
76} 52}
77 53
78long sys_uname(struct old_utsname __user * name)
79{
80 long err;
81 if (!name)
82 return -EFAULT;
83 down_read(&uts_sem);
84 err = copy_to_user(name, utsname(), sizeof (*name));
85 up_read(&uts_sem);
86 return err?-EFAULT:0;
87}
88
89long sys_olduname(struct oldold_utsname __user * name)
90{
91 long error;
92
93 if (!name)
94 return -EFAULT;
95 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
96 return -EFAULT;
97
98 down_read(&uts_sem);
99
100 error = __copy_to_user(&name->sysname, &utsname()->sysname,
101 __OLD_UTS_LEN);
102 error |= __put_user(0, name->sysname + __OLD_UTS_LEN);
103 error |= __copy_to_user(&name->nodename, &utsname()->nodename,
104 __OLD_UTS_LEN);
105 error |= __put_user(0, name->nodename + __OLD_UTS_LEN);
106 error |= __copy_to_user(&name->release, &utsname()->release,
107 __OLD_UTS_LEN);
108 error |= __put_user(0, name->release + __OLD_UTS_LEN);
109 error |= __copy_to_user(&name->version, &utsname()->version,
110 __OLD_UTS_LEN);
111 error |= __put_user(0, name->version + __OLD_UTS_LEN);
112 error |= __copy_to_user(&name->machine, &utsname()->machine,
113 __OLD_UTS_LEN);
114 error |= __put_user(0, name->machine + __OLD_UTS_LEN);
115
116 up_read(&uts_sem);
117
118 error = error ? -EFAULT : 0;
119
120 return error;
121}
122
123int kernel_execve(const char *filename, char *const argv[], char *const envp[]) 54int kernel_execve(const char *filename, char *const argv[], char *const envp[])
124{ 55{
125 mm_segment_t fs; 56 mm_segment_t fs;
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 1b549bca4645..804b28dd0328 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -6,6 +6,8 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ 6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
7 sys_call_table.o tls.o 7 sys_call_table.o tls.o
8 8
9obj-$(CONFIG_BINFMT_ELF) += elfcore.o
10
9subarch-obj-y = lib/semaphore_32.o lib/string_32.o 11subarch-obj-y = lib/semaphore_32.o lib/string_32.o
10subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 12subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
11subarch-obj-$(CONFIG_MODULES) += kernel/module.o 13subarch-obj-$(CONFIG_MODULES) += kernel/module.o
diff --git a/arch/um/sys-i386/asm/elf.h b/arch/um/sys-i386/asm/elf.h
index d0da9d7c5371..e64cd41d7bab 100644
--- a/arch/um/sys-i386/asm/elf.h
+++ b/arch/um/sys-i386/asm/elf.h
@@ -48,7 +48,6 @@ typedef struct user_i387_struct elf_fpregset_t;
48 PT_REGS_EAX(regs) = 0; \ 48 PT_REGS_EAX(regs) = 0; \
49} while (0) 49} while (0)
50 50
51#define USE_ELF_CORE_DUMP
52#define ELF_EXEC_PAGESIZE 4096 51#define ELF_EXEC_PAGESIZE 4096
53 52
54#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) 53#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
@@ -117,47 +116,4 @@ do { \
117 } \ 116 } \
118} while (0) 117} while (0)
119 118
120/*
121 * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
122 * extra segments containing the vsyscall DSO contents. Dumping its
123 * contents makes post-mortem fully interpretable later without matching up
124 * the same kernel and hardware config to see what PC values meant.
125 * Dumping its extra ELF program headers includes all the other information
126 * a debugger needs to easily find how the vsyscall DSO was being used.
127 */
128#define ELF_CORE_EXTRA_PHDRS \
129 (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 )
130
131#define ELF_CORE_WRITE_EXTRA_PHDRS \
132if ( vsyscall_ehdr ) { \
133 const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
134 const struct elf_phdr *const phdrp = \
135 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
136 int i; \
137 Elf32_Off ofs = 0; \
138 for (i = 0; i < ehdrp->e_phnum; ++i) { \
139 struct elf_phdr phdr = phdrp[i]; \
140 if (phdr.p_type == PT_LOAD) { \
141 ofs = phdr.p_offset = offset; \
142 offset += phdr.p_filesz; \
143 } \
144 else \
145 phdr.p_offset += ofs; \
146 phdr.p_paddr = 0; /* match other core phdrs */ \
147 DUMP_WRITE(&phdr, sizeof(phdr)); \
148 } \
149}
150#define ELF_CORE_WRITE_EXTRA_DATA \
151if ( vsyscall_ehdr ) { \
152 const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \
153 const struct elf_phdr *const phdrp = \
154 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \
155 int i; \
156 for (i = 0; i < ehdrp->e_phnum; ++i) { \
157 if (phdrp[i].p_type == PT_LOAD) \
158 DUMP_WRITE((void *) phdrp[i].p_vaddr, \
159 phdrp[i].p_filesz); \
160 } \
161}
162
163#endif 119#endif
diff --git a/arch/um/sys-i386/elfcore.c b/arch/um/sys-i386/elfcore.c
new file mode 100644
index 000000000000..6bb49b687c97
--- /dev/null
+++ b/arch/um/sys-i386/elfcore.c
@@ -0,0 +1,83 @@
1#include <linux/elf.h>
2#include <linux/coredump.h>
3#include <linux/fs.h>
4#include <linux/mm.h>
5
6#include <asm/elf.h>
7
8
9Elf32_Half elf_core_extra_phdrs(void)
10{
11 return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0;
12}
13
14int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size,
15 unsigned long limit)
16{
17 if ( vsyscall_ehdr ) {
18 const struct elfhdr *const ehdrp =
19 (struct elfhdr *) vsyscall_ehdr;
20 const struct elf_phdr *const phdrp =
21 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
22 int i;
23 Elf32_Off ofs = 0;
24
25 for (i = 0; i < ehdrp->e_phnum; ++i) {
26 struct elf_phdr phdr = phdrp[i];
27
28 if (phdr.p_type == PT_LOAD) {
29 ofs = phdr.p_offset = offset;
30 offset += phdr.p_filesz;
31 } else {
32 phdr.p_offset += ofs;
33 }
34 phdr.p_paddr = 0; /* match other core phdrs */
35 *size += sizeof(phdr);
36 if (*size > limit
37 || !dump_write(file, &phdr, sizeof(phdr)))
38 return 0;
39 }
40 }
41 return 1;
42}
43
44int elf_core_write_extra_data(struct file *file, size_t *size,
45 unsigned long limit)
46{
47 if ( vsyscall_ehdr ) {
48 const struct elfhdr *const ehdrp =
49 (struct elfhdr *) vsyscall_ehdr;
50 const struct elf_phdr *const phdrp =
51 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
52 int i;
53
54 for (i = 0; i < ehdrp->e_phnum; ++i) {
55 if (phdrp[i].p_type == PT_LOAD) {
56 void *addr = (void *) phdrp[i].p_vaddr;
57 size_t filesz = phdrp[i].p_filesz;
58
59 *size += filesz;
60 if (*size > limit
61 || !dump_write(file, addr, filesz))
62 return 0;
63 }
64 }
65 }
66 return 1;
67}
68
69size_t elf_core_extra_data_size(void)
70{
71 if ( vsyscall_ehdr ) {
72 const struct elfhdr *const ehdrp =
73 (struct elfhdr *)vsyscall_ehdr;
74 const struct elf_phdr *const phdrp =
75 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff);
76 int i;
77
78 for (i = 0; i < ehdrp->e_phnum; ++i)
79 if (phdrp[i].p_type == PT_LOAD)
80 return (size_t) phdrp[i].p_filesz;
81 }
82 return 0;
83}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index a4846a84a7be..3f2bf208d884 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -5,6 +5,7 @@
5 5
6#include <linux/mm.h> 6#include <linux/mm.h>
7#include <linux/sched.h> 7#include <linux/sched.h>
8#include <linux/slab.h>
8#include <asm/unistd.h> 9#include <asm/unistd.h>
9#include "os.h" 10#include "os.h"
10#include "proc_mm.h" 11#include "proc_mm.h"
diff --git a/arch/um/sys-i386/shared/sysdep/syscalls.h b/arch/um/sys-i386/shared/sysdep/syscalls.h
index 905698197e35..05cb796aecb5 100644
--- a/arch/um/sys-i386/shared/sysdep/syscalls.h
+++ b/arch/um/sys-i386/shared/sysdep/syscalls.h
@@ -13,14 +13,8 @@ typedef long syscall_handler_t(struct pt_regs);
13 */ 13 */
14extern syscall_handler_t sys_rt_sigaction; 14extern syscall_handler_t sys_rt_sigaction;
15 15
16extern syscall_handler_t old_mmap_i386;
17
18extern syscall_handler_t *sys_call_table[]; 16extern syscall_handler_t *sys_call_table[];
19 17
20#define EXECUTE_SYSCALL(syscall, regs) \ 18#define EXECUTE_SYSCALL(syscall, regs) \
21 ((long (*)(struct syscall_args)) \ 19 ((long (*)(struct syscall_args)) \
22 (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs)) 20 (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
23
24extern long sys_mmap2(unsigned long addr, unsigned long len,
25 unsigned long prot, unsigned long flags,
26 unsigned long fd, unsigned long pgoff);
diff --git a/arch/um/sys-i386/sys_call_table.S b/arch/um/sys-i386/sys_call_table.S
index c6260dd6ebb9..de274071455d 100644
--- a/arch/um/sys-i386/sys_call_table.S
+++ b/arch/um/sys-i386/sys_call_table.S
@@ -7,7 +7,7 @@
7#define sys_vm86old sys_ni_syscall 7#define sys_vm86old sys_ni_syscall
8#define sys_vm86 sys_ni_syscall 8#define sys_vm86 sys_ni_syscall
9 9
10#define old_mmap old_mmap_i386 10#define old_mmap sys_old_mmap
11 11
12#define ptregs_fork sys_fork 12#define ptregs_fork sys_fork
13#define ptregs_execve sys_execve 13#define ptregs_execve sys_execve
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
index 857ca0b3bdef..70ca357393b8 100644
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -12,57 +12,6 @@
12#include "asm/unistd.h" 12#include "asm/unistd.h"
13 13
14/* 14/*
15 * Perform the select(nd, in, out, ex, tv) and mmap() system
16 * calls. Linux/i386 didn't use to be able to handle more than
17 * 4 system call parameters, so these system calls used a memory
18 * block for parameter passing..
19 */
20
21struct mmap_arg_struct {
22 unsigned long addr;
23 unsigned long len;
24 unsigned long prot;
25 unsigned long flags;
26 unsigned long fd;
27 unsigned long offset;
28};
29
30extern int old_mmap(unsigned long addr, unsigned long len,
31 unsigned long prot, unsigned long flags,
32 unsigned long fd, unsigned long offset);
33
34long old_mmap_i386(struct mmap_arg_struct __user *arg)
35{
36 struct mmap_arg_struct a;
37 int err = -EFAULT;
38
39 if (copy_from_user(&a, arg, sizeof(a)))
40 goto out;
41
42 err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
43 out:
44 return err;
45}
46
47struct sel_arg_struct {
48 unsigned long n;
49 fd_set __user *inp;
50 fd_set __user *outp;
51 fd_set __user *exp;
52 struct timeval __user *tvp;
53};
54
55long old_select(struct sel_arg_struct __user *arg)
56{
57 struct sel_arg_struct a;
58
59 if (copy_from_user(&a, arg, sizeof(a)))
60 return -EFAULT;
61 /* sys_select() does the appropriate kernel locking */
62 return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
63}
64
65/*
66 * The prototype on i386 is: 15 * The prototype on i386 is:
67 * 16 *
68 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr) 17 * int clone(int flags, void * child_stack, int * parent_tidptr, struct user_desc * newtls, int * child_tidptr)
@@ -85,92 +34,6 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
85 return ret; 34 return ret;
86} 35}
87 36
88/*
89 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
90 *
91 * This is really horribly ugly.
92 */
93long sys_ipc (uint call, int first, int second,
94 int third, void __user *ptr, long fifth)
95{
96 int version, ret;
97
98 version = call >> 16; /* hack for backward compatibility */
99 call &= 0xffff;
100
101 switch (call) {
102 case SEMOP:
103 return sys_semtimedop(first, (struct sembuf __user *) ptr,
104 second, NULL);
105 case SEMTIMEDOP:
106 return sys_semtimedop(first, (struct sembuf __user *) ptr,
107 second,
108 (const struct timespec __user *) fifth);
109 case SEMGET:
110 return sys_semget (first, second, third);
111 case SEMCTL: {
112 union semun fourth;
113 if (!ptr)
114 return -EINVAL;
115 if (get_user(fourth.__pad, (void __user * __user *) ptr))
116 return -EFAULT;
117 return sys_semctl (first, second, third, fourth);
118 }
119
120 case MSGSND:
121 return sys_msgsnd (first, (struct msgbuf *) ptr,
122 second, third);
123 case MSGRCV:
124 switch (version) {
125 case 0: {
126 struct ipc_kludge tmp;
127 if (!ptr)
128 return -EINVAL;
129
130 if (copy_from_user(&tmp,
131 (struct ipc_kludge *) ptr,
132 sizeof (tmp)))
133 return -EFAULT;
134 return sys_msgrcv (first, tmp.msgp, second,
135 tmp.msgtyp, third);
136 }
137 default:
138 panic("msgrcv with version != 0");
139 return sys_msgrcv (first,
140 (struct msgbuf *) ptr,
141 second, fifth, third);
142 }
143 case MSGGET:
144 return sys_msgget ((key_t) first, second);
145 case MSGCTL:
146 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
147
148 case SHMAT:
149 switch (version) {
150 default: {
151 ulong raddr;
152 ret = do_shmat (first, (char *) ptr, second, &raddr);
153 if (ret)
154 return ret;
155 return put_user (raddr, (ulong *) third);
156 }
157 case 1: /* iBCS2 emulator entry point */
158 if (!segment_eq(get_fs(), get_ds()))
159 return -EINVAL;
160 return do_shmat (first, (char *) ptr, second, (ulong *) third);
161 }
162 case SHMDT:
163 return sys_shmdt ((char *)ptr);
164 case SHMGET:
165 return sys_shmget (first, second, third);
166 case SHMCTL:
167 return sys_shmctl (first, second,
168 (struct shmid_ds *) ptr);
169 default:
170 return -ENOSYS;
171 }
172}
173
174long sys_sigaction(int sig, const struct old_sigaction __user *act, 37long sys_sigaction(int sig, const struct old_sigaction __user *act,
175 struct old_sigaction __user *oact) 38 struct old_sigaction __user *oact)
176{ 39{
diff --git a/arch/um/sys-ppc/asm/elf.h b/arch/um/sys-ppc/asm/elf.h
index af9463cd8ce5..8aacaf56508d 100644
--- a/arch/um/sys-ppc/asm/elf.h
+++ b/arch/um/sys-ppc/asm/elf.h
@@ -17,8 +17,6 @@ extern long elf_aux_hwcap;
17#define ELF_CLASS ELFCLASS32 17#define ELF_CLASS ELFCLASS32
18#endif 18#endif
19 19
20#define USE_ELF_CORE_DUMP
21
22#define R_386_NONE 0 20#define R_386_NONE 0
23#define R_386_32 1 21#define R_386_32 1
24#define R_386_PC32 2 22#define R_386_PC32 2
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 2201e9c20e4a..c1ea9eb04466 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -8,7 +8,8 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
8 setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \ 8 setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \
9 sysrq.o ksyms.o tls.o 9 sysrq.o ksyms.o tls.o
10 10
11subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o 11subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o \
12 lib/rwsem_64.o
12subarch-obj-$(CONFIG_MODULES) += kernel/module.o 13subarch-obj-$(CONFIG_MODULES) += kernel/module.o
13 14
14ldt-y = ../sys-i386/ldt.o 15ldt-y = ../sys-i386/ldt.o
diff --git a/arch/um/sys-x86_64/asm/elf.h b/arch/um/sys-x86_64/asm/elf.h
index 04b9e87c8dad..49655c83efd2 100644
--- a/arch/um/sys-x86_64/asm/elf.h
+++ b/arch/um/sys-x86_64/asm/elf.h
@@ -104,7 +104,6 @@ extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);
104 clear_thread_flag(TIF_IA32); 104 clear_thread_flag(TIF_IA32);
105#endif 105#endif
106 106
107#define USE_ELF_CORE_DUMP
108#define ELF_EXEC_PAGESIZE 4096 107#define ELF_EXEC_PAGESIZE 4096
109 108
110#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) 109#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3)
diff --git a/arch/um/sys-x86_64/syscall_table.c b/arch/um/sys-x86_64/syscall_table.c
index dd21d69715e6..47d469e7e7ce 100644
--- a/arch/um/sys-x86_64/syscall_table.c
+++ b/arch/um/sys-x86_64/syscall_table.c
@@ -26,11 +26,6 @@
26 26
27/* On UML we call it this way ("old" means it's not mmap2) */ 27/* On UML we call it this way ("old" means it's not mmap2) */
28#define sys_mmap old_mmap 28#define sys_mmap old_mmap
29/*
30 * On x86-64 sys_uname is actually sys_newuname plus a compatibility trick.
31 * See arch/x86_64/kernel/sys_x86_64.c
32 */
33#define sys_uname sys_uname64
34 29
35#define stub_clone sys_clone 30#define stub_clone sys_clone
36#define stub_fork sys_fork 31#define stub_fork sys_fork
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index f1199fd34d38..f3d82bb6e15a 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -12,20 +12,6 @@
12#include "asm/uaccess.h" 12#include "asm/uaccess.h"
13#include "os.h" 13#include "os.h"
14 14
15asmlinkage long sys_uname64(struct new_utsname __user * name)
16{
17 int err;
18
19 down_read(&uts_sem);
20 err = copy_to_user(name, utsname(), sizeof (*name));
21 up_read(&uts_sem);
22
23 if (personality(current->personality) == PER_LINUX32)
24 err |= copy_to_user(&name->machine, "i686", 5);
25
26 return err ? -EFAULT : 0;
27}
28
29long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr) 15long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
30{ 16{
31 unsigned long *ptr = addr, tmp; 17 unsigned long *ptr = addr, tmp;