aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/sys-i386
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2007-10-16 04:27:00 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-16 12:43:05 -0400
commitba180fd437156f7fd8cfb2fdd021d949eeef08d6 (patch)
treeb9f38b9cdd7a5b1aacf00341d1948314663c5871 /arch/um/sys-i386
parent77bf4400319db9d2a8af6b00c2be6faa0f3d07cb (diff)
uml: style fixes pass 3
Formatting changes in the files which have been changed in the course of folding foo_skas functions into their callers. These include: copyright updates header file trimming style fixes adding severity to printks These changes should be entirely non-functional. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/um/sys-i386')
-rw-r--r--arch/um/sys-i386/bugs.c106
-rw-r--r--arch/um/sys-i386/fault.c8
-rw-r--r--arch/um/sys-i386/ldt.c217
-rw-r--r--arch/um/sys-i386/ptrace.c109
-rw-r--r--arch/um/sys-i386/signal.c62
-rw-r--r--arch/um/sys-i386/tls.c74
6 files changed, 286 insertions, 290 deletions
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
index 25c1165d8093..806895d73bcc 100644
--- a/arch/um/sys-i386/bugs.c
+++ b/arch/um/sys-i386/bugs.c
@@ -1,18 +1,15 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <errno.h> 6#include <errno.h>
7#include <signal.h>
8#include <string.h> 8#include <string.h>
9#include <sys/signal.h> 9#include "kern_constants.h"
10#include <asm/ldt.h>
11#include "kern_util.h"
12#include "user.h"
13#include "sysdep/ptrace.h"
14#include "task.h"
15#include "os.h" 10#include "os.h"
11#include "task.h"
12#include "user.h"
16 13
17#define MAXTOKEN 64 14#define MAXTOKEN 64
18 15
@@ -30,18 +27,20 @@ static char token(int fd, char *buf, int len, char stop)
30 do { 27 do {
31 n = os_read_file(fd, ptr, sizeof(*ptr)); 28 n = os_read_file(fd, ptr, sizeof(*ptr));
32 c = *ptr++; 29 c = *ptr++;
33 if(n != sizeof(*ptr)){ 30 if (n != sizeof(*ptr)) {
34 if(n == 0) 31 if (n == 0)
35 return 0; 32 return 0;
36 printk("Reading /proc/cpuinfo failed, err = %d\n", -n); 33 printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, "
37 if(n < 0) 34 "err = %d\n", -n);
35 if (n < 0)
38 return n; 36 return n;
39 else return -EIO; 37 else return -EIO;
40 } 38 }
41 } while((c != '\n') && (c != stop) && (ptr < end)); 39 } while ((c != '\n') && (c != stop) && (ptr < end));
42 40
43 if(ptr == end){ 41 if (ptr == end) {
44 printk("Failed to find '%c' in /proc/cpuinfo\n", stop); 42 printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n",
43 stop);
45 return -1; 44 return -1;
46 } 45 }
47 *(ptr - 1) = '\0'; 46 *(ptr - 1) = '\0';
@@ -54,26 +53,27 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
54 char c; 53 char c;
55 54
56 scratch[len - 1] = '\0'; 55 scratch[len - 1] = '\0';
57 while(1){ 56 while (1) {
58 c = token(fd, scratch, len - 1, ':'); 57 c = token(fd, scratch, len - 1, ':');
59 if(c <= 0) 58 if (c <= 0)
60 return 0; 59 return 0;
61 else if(c != ':'){ 60 else if (c != ':') {
62 printk("Failed to find ':' in /proc/cpuinfo\n"); 61 printk(UM_KERN_ERR "Failed to find ':' in "
62 "/proc/cpuinfo\n");
63 return 0; 63 return 0;
64 } 64 }
65 65
66 if(!strncmp(scratch, key, strlen(key))) 66 if (!strncmp(scratch, key, strlen(key)))
67 return 1; 67 return 1;
68 68
69 do { 69 do {
70 n = os_read_file(fd, &c, sizeof(c)); 70 n = os_read_file(fd, &c, sizeof(c));
71 if(n != sizeof(c)){ 71 if (n != sizeof(c)) {
72 printk("Failed to find newline in " 72 printk(UM_KERN_ERR "Failed to find newline in "
73 "/proc/cpuinfo, err = %d\n", -n); 73 "/proc/cpuinfo, err = %d\n", -n);
74 return 0; 74 return 0;
75 } 75 }
76 } while(c != '\n'); 76 } while (c != '\n');
77 } 77 }
78 return 0; 78 return 0;
79} 79}
@@ -83,46 +83,50 @@ static int check_cpu_flag(char *feature, int *have_it)
83 char buf[MAXTOKEN], c; 83 char buf[MAXTOKEN], c;
84 int fd, len = ARRAY_SIZE(buf); 84 int fd, len = ARRAY_SIZE(buf);
85 85
86 printk("Checking for host processor %s support...", feature); 86 printk(UM_KERN_INFO "Checking for host processor %s support...",
87 feature);
87 fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); 88 fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
88 if(fd < 0){ 89 if (fd < 0) {
89 printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); 90 printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n",
91 -fd);
90 return 0; 92 return 0;
91 } 93 }
92 94
93 *have_it = 0; 95 *have_it = 0;
94 if(!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf))) 96 if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
95 goto out; 97 goto out;
96 98
97 c = token(fd, buf, len - 1, ' '); 99 c = token(fd, buf, len - 1, ' ');
98 if(c < 0) 100 if (c < 0)
99 goto out; 101 goto out;
100 else if(c != ' '){ 102 else if (c != ' ') {
101 printk("Failed to find ' ' in /proc/cpuinfo\n"); 103 printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n");
102 goto out; 104 goto out;
103 } 105 }
104 106
105 while(1){ 107 while (1) {
106 c = token(fd, buf, len - 1, ' '); 108 c = token(fd, buf, len - 1, ' ');
107 if(c < 0) 109 if (c < 0)
108 goto out; 110 goto out;
109 else if(c == '\n') break; 111 else if (c == '\n')
112 break;
110 113
111 if(!strcmp(buf, feature)){ 114 if (!strcmp(buf, feature)) {
112 *have_it = 1; 115 *have_it = 1;
113 goto out; 116 goto out;
114 } 117 }
115 } 118 }
116 out: 119 out:
117 if(*have_it == 0) 120 if (*have_it == 0)
118 printk("No\n"); 121 printk("No\n");
119 else if(*have_it == 1) 122 else if (*have_it == 1)
120 printk("Yes\n"); 123 printk("Yes\n");
121 os_close_file(fd); 124 os_close_file(fd);
122 return 1; 125 return 1;
123} 126}
124 127
125#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems 128#if 0 /*
129 * This doesn't work in tt mode, plus it's causing compilation problems
126 * for some people. 130 * for some people.
127 */ 131 */
128static void disable_lcall(void) 132static void disable_lcall(void)
@@ -135,8 +139,9 @@ static void disable_lcall(void)
135 ldt.base_addr = 0; 139 ldt.base_addr = 0;
136 ldt.limit = 0; 140 ldt.limit = 0;
137 err = modify_ldt(1, &ldt, sizeof(ldt)); 141 err = modify_ldt(1, &ldt, sizeof(ldt));
138 if(err) 142 if (err)
139 printk("Failed to disable lcall7 - errno = %d\n", errno); 143 printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n",
144 errno);
140} 145}
141#endif 146#endif
142 147
@@ -151,14 +156,14 @@ void arch_check_bugs(void)
151{ 156{
152 int have_it; 157 int have_it;
153 158
154 if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){ 159 if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) {
155 printk("/proc/cpuinfo not available - skipping CPU capability " 160 printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU "
156 "checks\n"); 161 "capability checks\n");
157 return; 162 return;
158 } 163 }
159 if(check_cpu_flag("cmov", &have_it)) 164 if (check_cpu_flag("cmov", &have_it))
160 host_has_cmov = have_it; 165 host_has_cmov = have_it;
161 if(check_cpu_flag("xmm", &have_it)) 166 if (check_cpu_flag("xmm", &have_it))
162 host_has_xmm = have_it; 167 host_has_xmm = have_it;
163} 168}
164 169
@@ -166,25 +171,26 @@ int arch_handle_signal(int sig, struct uml_pt_regs *regs)
166{ 171{
167 unsigned char tmp[2]; 172 unsigned char tmp[2];
168 173
169 /* This is testing for a cmov (0x0f 0x4x) instruction causing a 174 /*
175 * This is testing for a cmov (0x0f 0x4x) instruction causing a
170 * SIGILL in init. 176 * SIGILL in init.
171 */ 177 */
172 if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) 178 if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
173 return 0; 179 return 0;
174 180
175 if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) 181 if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
176 panic("SIGILL in init, could not read instructions!\n"); 182 panic("SIGILL in init, could not read instructions!\n");
177 if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) 183 if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
178 return 0; 184 return 0;
179 185
180 if(host_has_cmov == 0) 186 if (host_has_cmov == 0)
181 panic("SIGILL caused by cmov, which this processor doesn't " 187 panic("SIGILL caused by cmov, which this processor doesn't "
182 "implement, boot a filesystem compiled for older " 188 "implement, boot a filesystem compiled for older "
183 "processors"); 189 "processors");
184 else if(host_has_cmov == 1) 190 else if (host_has_cmov == 1)
185 panic("SIGILL caused by cmov, which this processor claims to " 191 panic("SIGILL caused by cmov, which this processor claims to "
186 "implement"); 192 "implement");
187 else if(host_has_cmov == -1) 193 else if (host_has_cmov == -1)
188 panic("SIGILL caused by cmov, couldn't tell if this processor " 194 panic("SIGILL caused by cmov, couldn't tell if this processor "
189 "implements it, boot a filesystem compiled for older " 195 "implements it, boot a filesystem compiled for older "
190 "processors"); 196 "processors");
diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
index cc06a5737df0..d670f68532f4 100644
--- a/arch/um/sys-i386/fault.c
+++ b/arch/um/sys-i386/fault.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -20,9 +20,9 @@ int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
20 const struct exception_table_entry *fixup; 20 const struct exception_table_entry *fixup;
21 21
22 fixup = search_exception_tables(address); 22 fixup = search_exception_tables(address);
23 if(fixup != 0){ 23 if (fixup != 0) {
24 UPT_IP(regs) = fixup->fixup; 24 UPT_IP(regs) = fixup->fixup;
25 return(1); 25 return 1;
26 } 26 }
27 return(0); 27 return 0;
28} 28}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index 906c2a4e7279..0bf7572a80a3 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -1,34 +1,26 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h" 6#include "linux/mm.h"
7#include "linux/slab.h"
8#include "linux/types.h"
9#include "linux/errno.h"
10#include "linux/spinlock.h"
11#include "asm/uaccess.h"
12#include "asm/smp.h"
13#include "asm/ldt.h"
14#include "asm/unistd.h" 7#include "asm/unistd.h"
15#include "kern.h"
16#include "os.h" 8#include "os.h"
17 9#include "proc_mm.h"
18extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
19
20#include "skas.h" 10#include "skas.h"
21#include "skas_ptrace.h" 11#include "skas_ptrace.h"
22#include "asm/mmu_context.h" 12#include "sysdep/tls.h"
23#include "proc_mm.h" 13
14extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
24 15
25long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, 16long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
26 void **addr, int done) 17 void **addr, int done)
27{ 18{
28 long res; 19 long res;
29 20
30 if(proc_mm){ 21 if (proc_mm) {
31 /* This is a special handling for the case, that the mm to 22 /*
23 * This is a special handling for the case, that the mm to
32 * modify isn't current->active_mm. 24 * modify isn't current->active_mm.
33 * If this is called directly by modify_ldt, 25 * If this is called directly by modify_ldt,
34 * (current->active_mm->context.skas.u == mm_idp) 26 * (current->active_mm->context.skas.u == mm_idp)
@@ -40,12 +32,12 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
40 * 32 *
41 * Note: I'm unsure: should interrupts be disabled here? 33 * Note: I'm unsure: should interrupts be disabled here?
42 */ 34 */
43 if(!current->active_mm || current->active_mm == &init_mm || 35 if (!current->active_mm || current->active_mm == &init_mm ||
44 mm_idp != &current->active_mm->context.skas.id) 36 mm_idp != &current->active_mm->context.skas.id)
45 __switch_mm(mm_idp); 37 __switch_mm(mm_idp);
46 } 38 }
47 39
48 if(ptrace_ldt) { 40 if (ptrace_ldt) {
49 struct ptrace_ldt ldt_op = (struct ptrace_ldt) { 41 struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
50 .func = func, 42 .func = func,
51 .ptr = desc, 43 .ptr = desc,
@@ -53,7 +45,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
53 u32 cpu; 45 u32 cpu;
54 int pid; 46 int pid;
55 47
56 if(!proc_mm) 48 if (!proc_mm)
57 pid = mm_idp->u.pid; 49 pid = mm_idp->u.pid;
58 else { 50 else {
59 cpu = get_cpu(); 51 cpu = get_cpu();
@@ -62,7 +54,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
62 54
63 res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op); 55 res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op);
64 56
65 if(proc_mm) 57 if (proc_mm)
66 put_cpu(); 58 put_cpu();
67 } 59 }
68 else { 60 else {
@@ -71,7 +63,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
71 (sizeof(*desc) + sizeof(long) - 1) & 63 (sizeof(*desc) + sizeof(long) - 1) &
72 ~(sizeof(long) - 1), 64 ~(sizeof(long) - 1),
73 addr, &stub_addr); 65 addr, &stub_addr);
74 if(!res){ 66 if (!res) {
75 unsigned long args[] = { func, 67 unsigned long args[] = { func,
76 (unsigned long)stub_addr, 68 (unsigned long)stub_addr,
77 sizeof(*desc), 69 sizeof(*desc),
@@ -81,12 +73,13 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
81 } 73 }
82 } 74 }
83 75
84 if(proc_mm){ 76 if (proc_mm) {
85 /* This is the second part of special handling, that makes 77 /*
78 * This is the second part of special handling, that makes
86 * PTRACE_LDT possible to implement. 79 * PTRACE_LDT possible to implement.
87 */ 80 */
88 if(current->active_mm && current->active_mm != &init_mm && 81 if (current->active_mm && current->active_mm != &init_mm &&
89 mm_idp != &current->active_mm->context.skas.id) 82 mm_idp != &current->active_mm->context.skas.id)
90 __switch_mm(&current->active_mm->context.skas.id); 83 __switch_mm(&current->active_mm->context.skas.id);
91 } 84 }
92 85
@@ -102,21 +95,22 @@ static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
102 .ptr = kmalloc(bytecount, GFP_KERNEL)}; 95 .ptr = kmalloc(bytecount, GFP_KERNEL)};
103 u32 cpu; 96 u32 cpu;
104 97
105 if(ptrace_ldt.ptr == NULL) 98 if (ptrace_ldt.ptr == NULL)
106 return -ENOMEM; 99 return -ENOMEM;
107 100
108 /* This is called from sys_modify_ldt only, so userspace_pid gives 101 /*
102 * This is called from sys_modify_ldt only, so userspace_pid gives
109 * us the right number 103 * us the right number
110 */ 104 */
111 105
112 cpu = get_cpu(); 106 cpu = get_cpu();
113 res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt); 107 res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt);
114 put_cpu(); 108 put_cpu();
115 if(res < 0) 109 if (res < 0)
116 goto out; 110 goto out;
117 111
118 n = copy_to_user(ptr, ptrace_ldt.ptr, res); 112 n = copy_to_user(ptr, ptrace_ldt.ptr, res);
119 if(n != 0) 113 if (n != 0)
120 res = -EFAULT; 114 res = -EFAULT;
121 115
122 out: 116 out:
@@ -143,33 +137,32 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
143 unsigned long size; 137 unsigned long size;
144 uml_ldt_t * ldt = &current->mm->context.skas.ldt; 138 uml_ldt_t * ldt = &current->mm->context.skas.ldt;
145 139
146 if(!ldt->entry_count) 140 if (!ldt->entry_count)
147 goto out; 141 goto out;
148 if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) 142 if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
149 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; 143 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
150 err = bytecount; 144 err = bytecount;
151 145
152 if(ptrace_ldt){ 146 if (ptrace_ldt)
153 return read_ldt_from_host(ptr, bytecount); 147 return read_ldt_from_host(ptr, bytecount);
154 }
155 148
156 down(&ldt->semaphore); 149 down(&ldt->semaphore);
157 if(ldt->entry_count <= LDT_DIRECT_ENTRIES){ 150 if (ldt->entry_count <= LDT_DIRECT_ENTRIES) {
158 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; 151 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
159 if(size > bytecount) 152 if (size > bytecount)
160 size = bytecount; 153 size = bytecount;
161 if(copy_to_user(ptr, ldt->u.entries, size)) 154 if (copy_to_user(ptr, ldt->u.entries, size))
162 err = -EFAULT; 155 err = -EFAULT;
163 bytecount -= size; 156 bytecount -= size;
164 ptr += size; 157 ptr += size;
165 } 158 }
166 else { 159 else {
167 for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount; 160 for (i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
168 i++){ 161 i++) {
169 size = PAGE_SIZE; 162 size = PAGE_SIZE;
170 if(size > bytecount) 163 if (size > bytecount)
171 size = bytecount; 164 size = bytecount;
172 if(copy_to_user(ptr, ldt->u.pages[i], size)){ 165 if (copy_to_user(ptr, ldt->u.pages[i], size)) {
173 err = -EFAULT; 166 err = -EFAULT;
174 break; 167 break;
175 } 168 }
@@ -179,10 +172,10 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
179 } 172 }
180 up(&ldt->semaphore); 173 up(&ldt->semaphore);
181 174
182 if(bytecount == 0 || err == -EFAULT) 175 if (bytecount == 0 || err == -EFAULT)
183 goto out; 176 goto out;
184 177
185 if(clear_user(ptr, bytecount)) 178 if (clear_user(ptr, bytecount))
186 err = -EFAULT; 179 err = -EFAULT;
187 180
188out: 181out:
@@ -193,15 +186,16 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount)
193{ 186{
194 int err; 187 int err;
195 188
196 if(bytecount > 5*LDT_ENTRY_SIZE) 189 if (bytecount > 5*LDT_ENTRY_SIZE)
197 bytecount = 5*LDT_ENTRY_SIZE; 190 bytecount = 5*LDT_ENTRY_SIZE;
198 191
199 err = bytecount; 192 err = bytecount;
200 /* UML doesn't support lcall7 and lcall27. 193 /*
194 * UML doesn't support lcall7 and lcall27.
201 * So, we don't really have a default ldt, but emulate 195 * So, we don't really have a default ldt, but emulate
202 * an empty ldt of common host default ldt size. 196 * an empty ldt of common host default ldt size.
203 */ 197 */
204 if(clear_user(ptr, bytecount)) 198 if (clear_user(ptr, bytecount))
205 err = -EFAULT; 199 err = -EFAULT;
206 200
207 return err; 201 return err;
@@ -217,52 +211,52 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
217 void *addr = NULL; 211 void *addr = NULL;
218 212
219 err = -EINVAL; 213 err = -EINVAL;
220 if(bytecount != sizeof(ldt_info)) 214 if (bytecount != sizeof(ldt_info))
221 goto out; 215 goto out;
222 err = -EFAULT; 216 err = -EFAULT;
223 if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) 217 if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
224 goto out; 218 goto out;
225 219
226 err = -EINVAL; 220 err = -EINVAL;
227 if(ldt_info.entry_number >= LDT_ENTRIES) 221 if (ldt_info.entry_number >= LDT_ENTRIES)
228 goto out; 222 goto out;
229 if(ldt_info.contents == 3){ 223 if (ldt_info.contents == 3) {
230 if (func == 1) 224 if (func == 1)
231 goto out; 225 goto out;
232 if (ldt_info.seg_not_present == 0) 226 if (ldt_info.seg_not_present == 0)
233 goto out; 227 goto out;
234 } 228 }
235 229
236 if(!ptrace_ldt) 230 if (!ptrace_ldt)
237 down(&ldt->semaphore); 231 down(&ldt->semaphore);
238 232
239 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); 233 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
240 if(err) 234 if (err)
241 goto out_unlock; 235 goto out_unlock;
242 else if(ptrace_ldt) { 236 else if (ptrace_ldt) {
243 /* With PTRACE_LDT available, this is used as a flag only */ 237 /* With PTRACE_LDT available, this is used as a flag only */
244 ldt->entry_count = 1; 238 ldt->entry_count = 1;
245 goto out; 239 goto out;
246 } 240 }
247 241
248 if(ldt_info.entry_number >= ldt->entry_count && 242 if (ldt_info.entry_number >= ldt->entry_count &&
249 ldt_info.entry_number >= LDT_DIRECT_ENTRIES){ 243 ldt_info.entry_number >= LDT_DIRECT_ENTRIES) {
250 for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; 244 for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
251 i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; 245 i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
252 i++){ 246 i++) {
253 if(i == 0) 247 if (i == 0)
254 memcpy(&entry0, ldt->u.entries, 248 memcpy(&entry0, ldt->u.entries,
255 sizeof(entry0)); 249 sizeof(entry0));
256 ldt->u.pages[i] = (struct ldt_entry *) 250 ldt->u.pages[i] = (struct ldt_entry *)
257 __get_free_page(GFP_KERNEL|__GFP_ZERO); 251 __get_free_page(GFP_KERNEL|__GFP_ZERO);
258 if(!ldt->u.pages[i]){ 252 if (!ldt->u.pages[i]) {
259 err = -ENOMEM; 253 err = -ENOMEM;
260 /* Undo the change in host */ 254 /* Undo the change in host */
261 memset(&ldt_info, 0, sizeof(ldt_info)); 255 memset(&ldt_info, 0, sizeof(ldt_info));
262 write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); 256 write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
263 goto out_unlock; 257 goto out_unlock;
264 } 258 }
265 if(i == 0) { 259 if (i == 0) {
266 memcpy(ldt->u.pages[0], &entry0, 260 memcpy(ldt->u.pages[0], &entry0,
267 sizeof(entry0)); 261 sizeof(entry0));
268 memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, 262 memcpy(ldt->u.pages[0]+1, ldt->u.entries+1,
@@ -271,17 +265,17 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
271 ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; 265 ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
272 } 266 }
273 } 267 }
274 if(ldt->entry_count <= ldt_info.entry_number) 268 if (ldt->entry_count <= ldt_info.entry_number)
275 ldt->entry_count = ldt_info.entry_number + 1; 269 ldt->entry_count = ldt_info.entry_number + 1;
276 270
277 if(ldt->entry_count <= LDT_DIRECT_ENTRIES) 271 if (ldt->entry_count <= LDT_DIRECT_ENTRIES)
278 ldt_p = ldt->u.entries + ldt_info.entry_number; 272 ldt_p = ldt->u.entries + ldt_info.entry_number;
279 else 273 else
280 ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + 274 ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
281 ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; 275 ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
282 276
283 if(ldt_info.base_addr == 0 && ldt_info.limit == 0 && 277 if (ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
284 (func == 1 || LDT_empty(&ldt_info))){ 278 (func == 1 || LDT_empty(&ldt_info))) {
285 ldt_p->a = 0; 279 ldt_p->a = 0;
286 ldt_p->b = 0; 280 ldt_p->b = 0;
287 } 281 }
@@ -332,7 +326,7 @@ static void ldt_get_host_info(void)
332 326
333 spin_lock(&host_ldt_lock); 327 spin_lock(&host_ldt_lock);
334 328
335 if(host_ldt_entries != NULL){ 329 if (host_ldt_entries != NULL) {
336 spin_unlock(&host_ldt_lock); 330 spin_unlock(&host_ldt_lock);
337 return; 331 return;
338 } 332 }
@@ -340,49 +334,49 @@ static void ldt_get_host_info(void)
340 334
341 spin_unlock(&host_ldt_lock); 335 spin_unlock(&host_ldt_lock);
342 336
343 for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++); 337 for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++)
338 ;
344 339
345 ldt = (struct ldt_entry *) 340 ldt = (struct ldt_entry *)
346 __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); 341 __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
347 if(ldt == NULL) { 342 if (ldt == NULL) {
348 printk("ldt_get_host_info: couldn't allocate buffer for host " 343 printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer "
349 "ldt\n"); 344 "for host ldt\n");
350 return; 345 return;
351 } 346 }
352 347
353 ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE); 348 ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
354 if(ret < 0) { 349 if (ret < 0) {
355 printk("ldt_get_host_info: couldn't read host ldt\n"); 350 printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n");
356 goto out_free; 351 goto out_free;
357 } 352 }
358 if(ret == 0) { 353 if (ret == 0) {
359 /* default_ldt is active, simply write an empty entry 0 */ 354 /* default_ldt is active, simply write an empty entry 0 */
360 host_ldt_entries = dummy_list; 355 host_ldt_entries = dummy_list;
361 goto out_free; 356 goto out_free;
362 } 357 }
363 358
364 for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){ 359 for (i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++) {
365 if(ldt[i].a != 0 || ldt[i].b != 0) 360 if (ldt[i].a != 0 || ldt[i].b != 0)
366 size++; 361 size++;
367 } 362 }
368 363
369 if(size < ARRAY_SIZE(dummy_list)) 364 if (size < ARRAY_SIZE(dummy_list))
370 host_ldt_entries = dummy_list; 365 host_ldt_entries = dummy_list;
371 else { 366 else {
372 size = (size + 1) * sizeof(dummy_list[0]); 367 size = (size + 1) * sizeof(dummy_list[0]);
373 tmp = kmalloc(size, GFP_KERNEL); 368 tmp = kmalloc(size, GFP_KERNEL);
374 if(tmp == NULL) { 369 if (tmp == NULL) {
375 printk("ldt_get_host_info: couldn't allocate host ldt " 370 printk(KERN_ERR "ldt_get_host_info: couldn't allocate "
376 "list\n"); 371 "host ldt list\n");
377 goto out_free; 372 goto out_free;
378 } 373 }
379 host_ldt_entries = tmp; 374 host_ldt_entries = tmp;
380 } 375 }
381 376
382 for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){ 377 for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) {
383 if(ldt[i].a != 0 || ldt[i].b != 0) { 378 if (ldt[i].a != 0 || ldt[i].b != 0)
384 host_ldt_entries[k++] = i; 379 host_ldt_entries[k++] = i;
385 }
386 } 380 }
387 host_ldt_entries[k] = -1; 381 host_ldt_entries[k] = -1;
388 382
@@ -401,15 +395,15 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
401 struct proc_mm_op copy; 395 struct proc_mm_op copy;
402 396
403 397
404 if(!ptrace_ldt) 398 if (!ptrace_ldt)
405 init_MUTEX(&new_mm->ldt.semaphore); 399 init_MUTEX(&new_mm->ldt.semaphore);
406 400
407 if(!from_mm){ 401 if (!from_mm) {
408 memset(&desc, 0, sizeof(desc)); 402 memset(&desc, 0, sizeof(desc));
409 /* 403 /*
410 * We have to initialize a clean ldt. 404 * We have to initialize a clean ldt.
411 */ 405 */
412 if(proc_mm) { 406 if (proc_mm) {
413 /* 407 /*
414 * If the new mm was created using proc_mm, host's 408 * If the new mm was created using proc_mm, host's
415 * default-ldt currently is assigned, which normally 409 * default-ldt currently is assigned, which normally
@@ -417,8 +411,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
417 * To remove these gates, we simply write an empty 411 * To remove these gates, we simply write an empty
418 * entry as number 0 to the host. 412 * entry as number 0 to the host.
419 */ 413 */
420 err = write_ldt_entry(&new_mm->id, 1, &desc, 414 err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1);
421 &addr, 1);
422 } 415 }
423 else{ 416 else{
424 /* 417 /*
@@ -427,11 +420,11 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
427 * will be reset in the following loop 420 * will be reset in the following loop
428 */ 421 */
429 ldt_get_host_info(); 422 ldt_get_host_info();
430 for(num_p=host_ldt_entries; *num_p != -1; num_p++){ 423 for (num_p=host_ldt_entries; *num_p != -1; num_p++) {
431 desc.entry_number = *num_p; 424 desc.entry_number = *num_p;
432 err = write_ldt_entry(&new_mm->id, 1, &desc, 425 err = write_ldt_entry(&new_mm->id, 1, &desc,
433 &addr, *(num_p + 1) == -1); 426 &addr, *(num_p + 1) == -1);
434 if(err) 427 if (err)
435 break; 428 break;
436 } 429 }
437 } 430 }
@@ -440,8 +433,9 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
440 goto out; 433 goto out;
441 } 434 }
442 435
443 if(proc_mm){ 436 if (proc_mm) {
444 /* We have a valid from_mm, so we now have to copy the LDT of 437 /*
438 * We have a valid from_mm, so we now have to copy the LDT of
445 * from_mm to new_mm, because using proc_mm an new mm with 439 * from_mm to new_mm, because using proc_mm an new mm with
446 * an empty/default LDT was created in new_mm() 440 * an empty/default LDT was created in new_mm()
447 */ 441 */
@@ -450,27 +444,27 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
450 { .copy_segments = 444 { .copy_segments =
451 from_mm->id.u.mm_fd } } ); 445 from_mm->id.u.mm_fd } } );
452 i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy)); 446 i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy));
453 if(i != sizeof(copy)) 447 if (i != sizeof(copy))
454 printk("new_mm : /proc/mm copy_segments failed, " 448 printk(KERN_ERR "new_mm : /proc/mm copy_segments "
455 "err = %d\n", -i); 449 "failed, err = %d\n", -i);
456 } 450 }
457 451
458 if(!ptrace_ldt) { 452 if (!ptrace_ldt) {
459 /* Our local LDT is used to supply the data for 453 /*
454 * Our local LDT is used to supply the data for
460 * modify_ldt(READLDT), if PTRACE_LDT isn't available, 455 * modify_ldt(READLDT), if PTRACE_LDT isn't available,
461 * i.e., we have to use the stub for modify_ldt, which 456 * i.e., we have to use the stub for modify_ldt, which
462 * can't handle the big read buffer of up to 64kB. 457 * can't handle the big read buffer of up to 64kB.
463 */ 458 */
464 down(&from_mm->ldt.semaphore); 459 down(&from_mm->ldt.semaphore);
465 if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){ 460 if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES)
466 memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, 461 memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries,
467 sizeof(new_mm->ldt.u.entries)); 462 sizeof(new_mm->ldt.u.entries));
468 } 463 else {
469 else{
470 i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; 464 i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
471 while(i-->0){ 465 while (i-->0) {
472 page = __get_free_page(GFP_KERNEL|__GFP_ZERO); 466 page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
473 if (!page){ 467 if (!page) {
474 err = -ENOMEM; 468 err = -ENOMEM;
475 break; 469 break;
476 } 470 }
@@ -493,11 +487,10 @@ void free_ldt(struct mmu_context_skas * mm)
493{ 487{
494 int i; 488 int i;
495 489
496 if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){ 490 if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) {
497 i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; 491 i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
498 while(i-- > 0){ 492 while (i-- > 0)
499 free_page((long )mm->ldt.u.pages[i]); 493 free_page((long) mm->ldt.u.pages[i]);
500 }
501 } 494 }
502 mm->ldt.entry_count = 0; 495 mm->ldt.entry_count = 0;
503} 496}
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index dcf0c6b310c8..178f894384f4 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -1,18 +1,11 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/compiler.h>
7#include "linux/sched.h"
8#include "linux/mm.h" 6#include "linux/mm.h"
9#include "asm/elf.h" 7#include "linux/sched.h"
10#include "asm/ptrace.h"
11#include "asm/uaccess.h" 8#include "asm/uaccess.h"
12#include "asm/unistd.h"
13#include "sysdep/ptrace.h"
14#include "sysdep/sigcontext.h"
15#include "sysdep/sc.h"
16 9
17extern int arch_switch_tls(struct task_struct *from, struct task_struct *to); 10extern int arch_switch_tls(struct task_struct *from, struct task_struct *to);
18 11
@@ -23,7 +16,8 @@ void arch_switch_to(struct task_struct *from, struct task_struct *to)
23 return; 16 return;
24 17
25 if (err != -EINVAL) 18 if (err != -EINVAL)
26 printk(KERN_WARNING "arch_switch_tls failed, errno %d, not EINVAL\n", -err); 19 printk(KERN_WARNING "arch_switch_tls failed, errno %d, "
20 "not EINVAL\n", -err);
27 else 21 else
28 printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n"); 22 printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n");
29} 23}
@@ -34,21 +28,21 @@ int is_syscall(unsigned long addr)
34 int n; 28 int n;
35 29
36 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); 30 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
37 if(n){ 31 if (n) {
38 /* access_process_vm() grants access to vsyscall and stub, 32 /* access_process_vm() grants access to vsyscall and stub,
39 * while copy_from_user doesn't. Maybe access_process_vm is 33 * while copy_from_user doesn't. Maybe access_process_vm is
40 * slow, but that doesn't matter, since it will be called only 34 * slow, but that doesn't matter, since it will be called only
41 * in case of singlestepping, if copy_from_user failed. 35 * in case of singlestepping, if copy_from_user failed.
42 */ 36 */
43 n = access_process_vm(current, addr, &instr, sizeof(instr), 0); 37 n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
44 if(n != sizeof(instr)) { 38 if (n != sizeof(instr)) {
45 printk("is_syscall : failed to read instruction from " 39 printk(KERN_ERR "is_syscall : failed to read "
46 "0x%lx\n", addr); 40 "instruction from 0x%lx\n", addr);
47 return(1); 41 return 1;
48 } 42 }
49 } 43 }
50 /* int 0x80 or sysenter */ 44 /* int 0x80 or sysenter */
51 return((instr == 0x80cd) || (instr == 0x340f)); 45 return (instr == 0x80cd) || (instr == 0x340f);
52} 46}
53 47
54/* determines which flags the user has access to. */ 48/* determines which flags the user has access to. */
@@ -92,21 +86,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
92 86
93int poke_user(struct task_struct *child, long addr, long data) 87int poke_user(struct task_struct *child, long addr, long data)
94{ 88{
95 if ((addr & 3) || addr < 0) 89 if ((addr & 3) || addr < 0)
96 return -EIO; 90 return -EIO;
97 91
98 if (addr < MAX_REG_OFFSET) 92 if (addr < MAX_REG_OFFSET)
99 return putreg(child, addr, data); 93 return putreg(child, addr, data);
100 94 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
101 else if((addr >= offsetof(struct user, u_debugreg[0])) && 95 (addr <= offsetof(struct user, u_debugreg[7]))) {
102 (addr <= offsetof(struct user, u_debugreg[7]))){ 96 addr -= offsetof(struct user, u_debugreg[0]);
103 addr -= offsetof(struct user, u_debugreg[0]); 97 addr = addr >> 2;
104 addr = addr >> 2; 98 if ((addr == 4) || (addr == 5))
105 if((addr == 4) || (addr == 5)) return -EIO; 99 return -EIO;
106 child->thread.arch.debugregs[addr] = data; 100 child->thread.arch.debugregs[addr] = data;
107 return 0; 101 return 0;
108 } 102 }
109 return -EIO; 103 return -EIO;
110} 104}
111 105
112unsigned long getreg(struct task_struct *child, int regno) 106unsigned long getreg(struct task_struct *child, int regno)
@@ -129,20 +123,20 @@ unsigned long getreg(struct task_struct *child, int regno)
129 return retval; 123 return retval;
130} 124}
131 125
126/* read the word at location addr in the USER area. */
132int peek_user(struct task_struct *child, long addr, long data) 127int peek_user(struct task_struct *child, long addr, long data)
133{ 128{
134/* read the word at location addr in the USER area. */
135 unsigned long tmp; 129 unsigned long tmp;
136 130
137 if ((addr & 3) || addr < 0) 131 if ((addr & 3) || addr < 0)
138 return -EIO; 132 return -EIO;
139 133
140 tmp = 0; /* Default return condition */ 134 tmp = 0; /* Default return condition */
141 if(addr < MAX_REG_OFFSET){ 135 if (addr < MAX_REG_OFFSET) {
142 tmp = getreg(child, addr); 136 tmp = getreg(child, addr);
143 } 137 }
144 else if((addr >= offsetof(struct user, u_debugreg[0])) && 138 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
145 (addr <= offsetof(struct user, u_debugreg[7]))){ 139 (addr <= offsetof(struct user, u_debugreg[7]))) {
146 addr -= offsetof(struct user, u_debugreg[0]); 140 addr -= offsetof(struct user, u_debugreg[0]);
147 addr = addr >> 2; 141 addr = addr >> 2;
148 tmp = child->thread.arch.debugregs[addr]; 142 tmp = child->thread.arch.debugregs[addr];
@@ -173,15 +167,15 @@ struct i387_fxsave_struct {
173static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) 167static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
174{ 168{
175 unsigned int tmp; /* to avoid 16 bit prefixes in the code */ 169 unsigned int tmp; /* to avoid 16 bit prefixes in the code */
176 170
177 /* Transform each pair of bits into 01 (valid) or 00 (empty) */ 171 /* Transform each pair of bits into 01 (valid) or 00 (empty) */
178 tmp = ~twd; 172 tmp = ~twd;
179 tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ 173 tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
180 /* and move the valid bits to the lower byte. */ 174 /* and move the valid bits to the lower byte. */
181 tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ 175 tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
182 tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ 176 tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
183 tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ 177 tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
184 return tmp; 178 return tmp;
185} 179}
186 180
187static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) 181static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave )
@@ -235,7 +229,7 @@ static inline int convert_fxsr_to_user(struct _fpstate __user *buf,
235 return 0; 229 return 0;
236} 230}
237 231
238static inline int convert_fxsr_from_user(struct pt_regs *regs, 232static inline int convert_fxsr_from_user(struct pt_regs *regs,
239 struct _fpstate __user *buf) 233 struct _fpstate __user *buf)
240{ 234{
241 return 0; 235 return 0;
@@ -247,18 +241,20 @@ int get_fpregs(unsigned long buf, struct task_struct *child)
247 241
248 err = convert_fxsr_to_user((struct _fpstate __user *) buf, 242 err = convert_fxsr_to_user((struct _fpstate __user *) buf,
249 &child->thread.regs); 243 &child->thread.regs);
250 if(err) return(-EFAULT); 244 if (err)
251 else return(0); 245 return -EFAULT;
246 return 0;
252} 247}
253 248
254int set_fpregs(unsigned long buf, struct task_struct *child) 249int set_fpregs(unsigned long buf, struct task_struct *child)
255{ 250{
256 int err; 251 int err;
257 252
258 err = convert_fxsr_from_user(&child->thread.regs, 253 err = convert_fxsr_from_user(&child->thread.regs,
259 (struct _fpstate __user *) buf); 254 (struct _fpstate __user *) buf);
260 if(err) return(-EFAULT); 255 if (err)
261 else return(0); 256 return -EFAULT;
257 return 0;
262} 258}
263 259
264int get_fpxregs(unsigned long buf, struct task_struct *tsk) 260int get_fpxregs(unsigned long buf, struct task_struct *tsk)
@@ -284,7 +280,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
284 fpu->fos = 0; 280 fpu->fos = 0;
285 memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)), 281 memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
286 sizeof(fpu->st_space)); 282 sizeof(fpu->st_space));
287 return(1); 283 return 1;
288} 284}
289#endif 285#endif
290 286
@@ -292,14 +288,3 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
292{ 288{
293 return 1; 289 return 1;
294} 290}
295
296/*
297 * Overrides for Emacs so that we follow Linus's tabbing style.
298 * Emacs will notice this stuff at the end of the file and automatically
299 * adjust the settings for this buffer only. This must remain at the end
300 * of the file.
301 * ---------------------------------------------------------------------------
302 * Local variables:
303 * c-file-style: "linux"
304 * End:
305 */
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index c64d48734e3a..c82e5f562ec6 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -1,17 +1,13 @@
1/* 1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/signal.h"
7#include "linux/ptrace.h" 6#include "linux/ptrace.h"
8#include "asm/current.h"
9#include "asm/ucontext.h"
10#include "asm/uaccess.h"
11#include "asm/unistd.h" 7#include "asm/unistd.h"
8#include "asm/uaccess.h"
9#include "asm/ucontext.h"
12#include "frame_kern.h" 10#include "frame_kern.h"
13#include "sigcontext.h"
14#include "registers.h"
15#include "skas.h" 11#include "skas.h"
16 12
17void copy_sc(struct uml_pt_regs *regs, void *from) 13void copy_sc(struct uml_pt_regs *regs, void *from)
@@ -39,21 +35,21 @@ void copy_sc(struct uml_pt_regs *regs, void *from)
39static int copy_sc_from_user(struct pt_regs *regs, 35static int copy_sc_from_user(struct pt_regs *regs,
40 struct sigcontext __user *from) 36 struct sigcontext __user *from)
41{ 37{
42 struct sigcontext sc; 38 struct sigcontext sc;
43 unsigned long fpregs[HOST_FP_SIZE]; 39 unsigned long fpregs[HOST_FP_SIZE];
44 int err; 40 int err;
45 41
46 err = copy_from_user(&sc, from, sizeof(sc)); 42 err = copy_from_user(&sc, from, sizeof(sc));
47 err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); 43 err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs));
48 if(err) 44 if (err)
49 return err; 45 return err;
50 46
51 copy_sc(&regs->regs, &sc); 47 copy_sc(&regs->regs, &sc);
52 48
53 err = restore_fp_registers(userspace_pid[0], fpregs); 49 err = restore_fp_registers(userspace_pid[0], fpregs);
54 if(err < 0) { 50 if (err < 0) {
55 printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " 51 printk(KERN_ERR "copy_sc_from_user_skas - PTRACE_SETFPREGS "
56 "errno = %d\n", -err); 52 "failed, errno = %d\n", -err);
57 return err; 53 return err;
58 } 54 }
59 55
@@ -64,7 +60,7 @@ static int copy_sc_to_user(struct sigcontext __user *to,
64 struct _fpstate __user *to_fp, struct pt_regs *regs, 60 struct _fpstate __user *to_fp, struct pt_regs *regs,
65 unsigned long sp) 61 unsigned long sp)
66{ 62{
67 struct sigcontext sc; 63 struct sigcontext sc;
68 unsigned long fpregs[HOST_FP_SIZE]; 64 unsigned long fpregs[HOST_FP_SIZE];
69 struct faultinfo * fi = &current->thread.arch.faultinfo; 65 struct faultinfo * fi = &current->thread.arch.faultinfo;
70 int err; 66 int err;
@@ -86,28 +82,29 @@ static int copy_sc_to_user(struct sigcontext __user *to,
86 sc.eflags = REGS_EFLAGS(regs->regs.regs); 82 sc.eflags = REGS_EFLAGS(regs->regs.regs);
87 sc.esp_at_signal = regs->regs.regs[UESP]; 83 sc.esp_at_signal = regs->regs.regs[UESP];
88 sc.ss = regs->regs.regs[SS]; 84 sc.ss = regs->regs.regs[SS];
89 sc.cr2 = fi->cr2; 85 sc.cr2 = fi->cr2;
90 sc.err = fi->error_code; 86 sc.err = fi->error_code;
91 sc.trapno = fi->trap_no; 87 sc.trapno = fi->trap_no;
92 88
93 err = save_fp_registers(userspace_pid[0], fpregs); 89 err = save_fp_registers(userspace_pid[0], fpregs);
94 if(err < 0){ 90 if (err < 0) {
95 printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, " 91 printk(KERN_ERR "copy_sc_to_user_skas - PTRACE_GETFPREGS "
96 "errno = %d\n", err); 92 "failed, errno = %d\n", err);
97 return 1; 93 return 1;
98 } 94 }
99 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1)); 95 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
100 sc.fpstate = to_fp; 96 sc.fpstate = to_fp;
101 97
102 if(err) 98 if (err)
103 return err; 99 return err;
104 100
105 return copy_to_user(to, &sc, sizeof(sc)) || 101 return copy_to_user(to, &sc, sizeof(sc)) ||
106 copy_to_user(to_fp, fpregs, sizeof(fpregs)); 102 copy_to_user(to_fp, fpregs, sizeof(fpregs));
107} 103}
108 104
109static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, 105static int copy_ucontext_to_user(struct ucontext __user *uc,
110 sigset_t *set, unsigned long sp) 106 struct _fpstate __user *fp, sigset_t *set,
107 unsigned long sp)
111{ 108{
112 int err = 0; 109 int err = 0;
113 110
@@ -157,7 +154,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
157 return 1; 154 return 1;
158 155
159 restorer = frame->retcode; 156 restorer = frame->retcode;
160 if(ka->sa.sa_flags & SA_RESTORER) 157 if (ka->sa.sa_flags & SA_RESTORER)
161 restorer = ka->sa.sa_restorer; 158 restorer = ka->sa.sa_restorer;
162 159
163 /* Update SP now because the page fault handler refuses to extend 160 /* Update SP now because the page fault handler refuses to extend
@@ -189,7 +186,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
189 err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); 186 err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
190 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); 187 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
191 188
192 if(err) 189 if (err)
193 goto err; 190 goto err;
194 191
195 PT_REGS_SP(regs) = (unsigned long) frame; 192 PT_REGS_SP(regs) = (unsigned long) frame;
@@ -222,7 +219,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
222 return 1; 219 return 1;
223 220
224 restorer = frame->retcode; 221 restorer = frame->retcode;
225 if(ka->sa.sa_flags & SA_RESTORER) 222 if (ka->sa.sa_flags & SA_RESTORER)
226 restorer = ka->sa.sa_restorer; 223 restorer = ka->sa.sa_restorer;
227 224
228 /* See comment above about why this is here */ 225 /* See comment above about why this is here */
@@ -247,7 +244,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
247 err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); 244 err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
248 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); 245 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
249 246
250 if(err) 247 if (err)
251 goto err; 248 goto err;
252 249
253 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; 250 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -274,8 +271,8 @@ long sys_sigreturn(struct pt_regs regs)
274 unsigned long __user *extramask = frame->extramask; 271 unsigned long __user *extramask = frame->extramask;
275 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); 272 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
276 273
277 if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || 274 if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
278 copy_from_user(&set.sig[1], extramask, sig_size)) 275 copy_from_user(&set.sig[1], extramask, sig_size))
279 goto segfault; 276 goto segfault;
280 277
281 sigdelsetmask(&set, ~_BLOCKABLE); 278 sigdelsetmask(&set, ~_BLOCKABLE);
@@ -285,7 +282,7 @@ long sys_sigreturn(struct pt_regs regs)
285 recalc_sigpending(); 282 recalc_sigpending();
286 spin_unlock_irq(&current->sighand->siglock); 283 spin_unlock_irq(&current->sighand->siglock);
287 284
288 if(copy_sc_from_user(&current->thread.regs, sc)) 285 if (copy_sc_from_user(&current->thread.regs, sc))
289 goto segfault; 286 goto segfault;
290 287
291 /* Avoid ERESTART handling */ 288 /* Avoid ERESTART handling */
@@ -300,12 +297,13 @@ long sys_sigreturn(struct pt_regs regs)
300long sys_rt_sigreturn(struct pt_regs regs) 297long sys_rt_sigreturn(struct pt_regs regs)
301{ 298{
302 unsigned long sp = PT_REGS_SP(&current->thread.regs); 299 unsigned long sp = PT_REGS_SP(&current->thread.regs);
303 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4); 300 struct rt_sigframe __user *frame =
301 (struct rt_sigframe __user *) (sp - 4);
304 sigset_t set; 302 sigset_t set;
305 struct ucontext __user *uc = &frame->uc; 303 struct ucontext __user *uc = &frame->uc;
306 int sig_size = _NSIG_WORDS * sizeof(unsigned long); 304 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
307 305
308 if(copy_from_user(&set, &uc->uc_sigmask, sig_size)) 306 if (copy_from_user(&set, &uc->uc_sigmask, sig_size))
309 goto segfault; 307 goto segfault;
310 308
311 sigdelsetmask(&set, ~_BLOCKABLE); 309 sigdelsetmask(&set, ~_BLOCKABLE);
@@ -315,7 +313,7 @@ long sys_rt_sigreturn(struct pt_regs regs)
315 recalc_sigpending(); 313 recalc_sigpending();
316 spin_unlock_irq(&current->sighand->siglock); 314 spin_unlock_irq(&current->sighand->siglock);
317 315
318 if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext)) 316 if (copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
319 goto segfault; 317 goto segfault;
320 318
321 /* Avoid ERESTART handling */ 319 /* Avoid ERESTART handling */
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index 6cb7cbd137a0..b02266ab5c55 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -3,19 +3,12 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h" 6#include "linux/percpu.h"
7#include "linux/sched.h" 7#include "linux/sched.h"
8#include "linux/slab.h"
9#include "linux/types.h"
10#include "asm/uaccess.h" 8#include "asm/uaccess.h"
11#include "asm/ptrace.h"
12#include "asm/segment.h"
13#include "asm/smp.h"
14#include "asm/desc.h"
15#include "kern.h"
16#include "kern_util.h"
17#include "os.h" 9#include "os.h"
18#include "skas.h" 10#include "skas.h"
11#include "sysdep/tls.h"
19 12
20/* 13/*
21 * If needed we can detect when it's uninitialized. 14 * If needed we can detect when it's uninitialized.
@@ -74,7 +67,8 @@ static inline void clear_user_desc(struct user_desc* info)
74 /* Postcondition: LDT_empty(info) returns true. */ 67 /* Postcondition: LDT_empty(info) returns true. */
75 memset(info, 0, sizeof(*info)); 68 memset(info, 0, sizeof(*info));
76 69
77 /* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain 70 /*
71 * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
78 * indeed an empty user_desc. 72 * indeed an empty user_desc.
79 */ 73 */
80 info->read_exec_only = 1; 74 info->read_exec_only = 1;
@@ -89,10 +83,13 @@ static int load_TLS(int flags, struct task_struct *to)
89 int idx; 83 int idx;
90 84
91 for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { 85 for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) {
92 struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; 86 struct uml_tls_struct* curr =
87 &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
93 88
94 /* Actually, now if it wasn't flushed it gets cleared and 89 /*
95 * flushed to the host, which will clear it.*/ 90 * Actually, now if it wasn't flushed it gets cleared and
91 * flushed to the host, which will clear it.
92 */
96 if (!curr->present) { 93 if (!curr->present) {
97 if (!curr->flushed) { 94 if (!curr->flushed) {
98 clear_user_desc(&curr->tls); 95 clear_user_desc(&curr->tls);
@@ -116,7 +113,8 @@ out:
116 return ret; 113 return ret;
117} 114}
118 115
119/* Verify if we need to do a flush for the new process, i.e. if there are any 116/*
117 * Verify if we need to do a flush for the new process, i.e. if there are any
120 * present desc's, only if they haven't been flushed. 118 * present desc's, only if they haven't been flushed.
121 */ 119 */
122static inline int needs_TLS_update(struct task_struct *task) 120static inline int needs_TLS_update(struct task_struct *task)
@@ -125,10 +123,13 @@ static inline int needs_TLS_update(struct task_struct *task)
125 int ret = 0; 123 int ret = 0;
126 124
127 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { 125 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
128 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; 126 struct uml_tls_struct* curr =
127 &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
129 128
130 /* Can't test curr->present, we may need to clear a descriptor 129 /*
131 * which had a value. */ 130 * Can't test curr->present, we may need to clear a descriptor
131 * which had a value.
132 */
132 if (curr->flushed) 133 if (curr->flushed)
133 continue; 134 continue;
134 ret = 1; 135 ret = 1;
@@ -137,7 +138,8 @@ static inline int needs_TLS_update(struct task_struct *task)
137 return ret; 138 return ret;
138} 139}
139 140
140/* On a newly forked process, the TLS descriptors haven't yet been flushed. So 141/*
142 * On a newly forked process, the TLS descriptors haven't yet been flushed. So
141 * we mark them as such and the first switch_to will do the job. 143 * we mark them as such and the first switch_to will do the job.
142 */ 144 */
143void clear_flushed_tls(struct task_struct *task) 145void clear_flushed_tls(struct task_struct *task)
@@ -145,10 +147,13 @@ void clear_flushed_tls(struct task_struct *task)
145 int i; 147 int i;
146 148
147 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { 149 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
148 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; 150 struct uml_tls_struct* curr =
151 &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
149 152
150 /* Still correct to do this, if it wasn't present on the host it 153 /*
151 * will remain as flushed as it was. */ 154 * Still correct to do this, if it wasn't present on the host it
155 * will remain as flushed as it was.
156 */
152 if (!curr->present) 157 if (!curr->present)
153 continue; 158 continue;
154 159
@@ -156,23 +161,27 @@ void clear_flushed_tls(struct task_struct *task)
156 } 161 }
157} 162}
158 163
159/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a 164/*
165 * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
160 * common host process. So this is needed in SKAS0 too. 166 * common host process. So this is needed in SKAS0 too.
161 * 167 *
162 * However, if each thread had a different host process (and this was discussed 168 * However, if each thread had a different host process (and this was discussed
163 * for SMP support) this won't be needed. 169 * for SMP support) this won't be needed.
164 * 170 *
165 * And this will not need be used when (and if) we'll add support to the host 171 * And this will not need be used when (and if) we'll add support to the host
166 * SKAS patch. */ 172 * SKAS patch.
173 */
167 174
168int arch_switch_tls(struct task_struct *from, struct task_struct *to) 175int arch_switch_tls(struct task_struct *from, struct task_struct *to)
169{ 176{
170 if (!host_supports_tls) 177 if (!host_supports_tls)
171 return 0; 178 return 0;
172 179
173 /* We have no need whatsoever to switch TLS for kernel threads; beyond 180 /*
181 * We have no need whatsoever to switch TLS for kernel threads; beyond
174 * that, that would also result in us calling os_set_thread_area with 182 * that, that would also result in us calling os_set_thread_area with
175 * userspace_pid[cpu] == 0, which gives an error. */ 183 * userspace_pid[cpu] == 0, which gives an error.
184 */
176 if (likely(to->mm)) 185 if (likely(to->mm))
177 return load_TLS(O_FORCE, to); 186 return load_TLS(O_FORCE, to);
178 187
@@ -232,17 +241,20 @@ static int get_tls_entry(struct task_struct* task, struct user_desc *info, int i
232 *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; 241 *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls;
233 242
234out: 243out:
235 /* Temporary debugging check, to make sure that things have been 244 /*
245 * Temporary debugging check, to make sure that things have been
236 * flushed. This could be triggered if load_TLS() failed. 246 * flushed. This could be triggered if load_TLS() failed.
237 */ 247 */
238 if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { 248 if (unlikely(task == current &&
249 !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
239 printk(KERN_ERR "get_tls_entry: task with pid %d got here " 250 printk(KERN_ERR "get_tls_entry: task with pid %d got here "
240 "without flushed TLS.", current->pid); 251 "without flushed TLS.", current->pid);
241 } 252 }
242 253
243 return 0; 254 return 0;
244clear: 255clear:
245 /* When the TLS entry has not been set, the values read to user in the 256 /*
257 * When the TLS entry has not been set, the values read to user in the
246 * tls_array are 0 (because it's cleared at boot, see 258 * tls_array are 0 (because it's cleared at boot, see
247 * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. 259 * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that.
248 */ 260 */
@@ -344,8 +356,10 @@ out:
344} 356}
345 357
346 358
347/* XXX: This part is probably common to i386 and x86-64. Don't create a common 359/*
348 * file for now, do that when implementing x86-64 support.*/ 360 * XXX: This part is probably common to i386 and x86-64. Don't create a common
361 * file for now, do that when implementing x86-64 support.
362 */
349static int __init __setup_host_supports_tls(void) 363static int __init __setup_host_supports_tls(void)
350{ 364{
351 check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); 365 check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);