aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux/skas/mem.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux/skas/mem.c')
-rw-r--r--arch/um/os-Linux/skas/mem.c75
1 files changed, 44 insertions, 31 deletions
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 9383e8751ae7..8e490fff3d47 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -6,6 +6,7 @@
6#include <signal.h> 6#include <signal.h>
7#include <errno.h> 7#include <errno.h>
8#include <string.h> 8#include <string.h>
9#include <unistd.h>
9#include <sys/mman.h> 10#include <sys/mman.h>
10#include <sys/wait.h> 11#include <sys/wait.h>
11#include <asm/page.h> 12#include <asm/page.h>
@@ -17,17 +18,17 @@
17#include "os.h" 18#include "os.h"
18#include "proc_mm.h" 19#include "proc_mm.h"
19#include "ptrace_user.h" 20#include "ptrace_user.h"
20#include "user_util.h"
21#include "kern_util.h" 21#include "kern_util.h"
22#include "task.h" 22#include "task.h"
23#include "registers.h" 23#include "registers.h"
24#include "uml-config.h" 24#include "uml-config.h"
25#include "sysdep/ptrace.h" 25#include "sysdep/ptrace.h"
26#include "sysdep/stub.h" 26#include "sysdep/stub.h"
27#include "init.h"
27 28
28extern unsigned long batch_syscall_stub, __syscall_stub_start; 29extern unsigned long batch_syscall_stub, __syscall_stub_start;
29 30
30extern void wait_stub_done(int pid, int sig, char * fname); 31extern void wait_stub_done(int pid);
31 32
32static inline unsigned long *check_init_stack(struct mm_id * mm_idp, 33static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
33 unsigned long *stack) 34 unsigned long *stack)
@@ -39,6 +40,19 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
39 return stack; 40 return stack;
40} 41}
41 42
43static unsigned long syscall_regs[MAX_REG_NR];
44
45static int __init init_syscall_regs(void)
46{
47 get_safe_registers(syscall_regs, NULL);
48 syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
49 ((unsigned long) &batch_syscall_stub -
50 (unsigned long) &__syscall_stub_start);
51 return 0;
52}
53
54__initcall(init_syscall_regs);
55
42extern int proc_mm; 56extern int proc_mm;
43 57
44int single_count = 0; 58int single_count = 0;
@@ -47,12 +61,11 @@ int multi_op_count = 0;
47 61
48static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr) 62static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
49{ 63{
50 unsigned long regs[MAX_REG_NR];
51 int n, i; 64 int n, i;
52 long ret, offset; 65 long ret, offset;
53 unsigned long * data; 66 unsigned long * data;
54 unsigned long * syscall; 67 unsigned long * syscall;
55 int pid = mm_idp->u.pid; 68 int err, pid = mm_idp->u.pid;
56 69
57 if(proc_mm) 70 if(proc_mm)
58#warning Need to look up userspace_pid by cpu 71#warning Need to look up userspace_pid by cpu
@@ -60,21 +73,21 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
60 73
61 multi_count++; 74 multi_count++;
62 75
63 get_safe_registers(regs, NULL); 76 n = ptrace_setregs(pid, syscall_regs);
64 regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
65 ((unsigned long) &batch_syscall_stub -
66 (unsigned long) &__syscall_stub_start);
67
68 n = ptrace_setregs(pid, regs);
69 if(n < 0){ 77 if(n < 0){
70 printk("Registers - \n"); 78 printk("Registers - \n");
71 for(i = 0; i < MAX_REG_NR; i++) 79 for(i = 0; i < MAX_REG_NR; i++)
72 printk("\t%d\t0x%lx\n", i, regs[i]); 80 printk("\t%d\t0x%lx\n", i, syscall_regs[i]);
73 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", 81 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
74 -n); 82 -n);
75 } 83 }
76 84
77 wait_stub_done(pid, 0, "do_syscall_stub"); 85 err = ptrace(PTRACE_CONT, pid, 0, 0);
86 if(err)
87 panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
88 errno);
89
90 wait_stub_done(pid);
78 91
79 /* When the stub stops, we find the following values on the 92 /* When the stub stops, we find the following values on the
80 * beginning of the stack: 93 * beginning of the stack:
@@ -176,14 +189,10 @@ long syscall_stub_data(struct mm_id * mm_idp,
176 return 0; 189 return 0;
177} 190}
178 191
179int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, 192int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
180 int r, int w, int x, int phys_fd, unsigned long long offset, 193 int phys_fd, unsigned long long offset, int done, void **data)
181 int done, void **data)
182{ 194{
183 int prot, ret; 195 int ret;
184
185 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
186 (x ? PROT_EXEC : 0);
187 196
188 if(proc_mm){ 197 if(proc_mm){
189 struct proc_mm_op map; 198 struct proc_mm_op map;
@@ -200,9 +209,11 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
200 .fd = phys_fd, 209 .fd = phys_fd,
201 .offset= offset 210 .offset= offset
202 } } } ); 211 } } } );
203 ret = os_write_file(fd, &map, sizeof(map)); 212 CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
204 if(ret != sizeof(map)) 213 if(ret != sizeof(map)){
214 ret = -errno;
205 printk("map : /proc/mm map failed, err = %d\n", -ret); 215 printk("map : /proc/mm map failed, err = %d\n", -ret);
216 }
206 else ret = 0; 217 else ret = 0;
207 } 218 }
208 else { 219 else {
@@ -217,8 +228,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
217 return ret; 228 return ret;
218} 229}
219 230
220int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done, 231int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
221 void **data) 232 int done, void **data)
222{ 233{
223 int ret; 234 int ret;
224 235
@@ -232,9 +243,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
232 { .addr = 243 { .addr =
233 (unsigned long) addr, 244 (unsigned long) addr,
234 .len = len } } } ); 245 .len = len } } } );
235 ret = os_write_file(fd, &unmap, sizeof(unmap)); 246 CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
236 if(ret != sizeof(unmap)) 247 if(ret != sizeof(unmap)){
248 ret = -errno;
237 printk("unmap - proc_mm write returned %d\n", ret); 249 printk("unmap - proc_mm write returned %d\n", ret);
250 }
238 else ret = 0; 251 else ret = 0;
239 } 252 }
240 else { 253 else {
@@ -249,13 +262,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
249} 262}
250 263
251int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len, 264int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
252 int r, int w, int x, int done, void **data) 265 unsigned int prot, int done, void **data)
253{ 266{
254 struct proc_mm_op protect; 267 struct proc_mm_op protect;
255 int prot, ret; 268 int ret;
256 269
257 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
258 (x ? PROT_EXEC : 0);
259 if(proc_mm){ 270 if(proc_mm){
260 int fd = mm_idp->u.mm_fd; 271 int fd = mm_idp->u.mm_fd;
261 272
@@ -267,9 +278,11 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
267 .len = len, 278 .len = len,
268 .prot = prot } } } ); 279 .prot = prot } } } );
269 280
270 ret = os_write_file(fd, &protect, sizeof(protect)); 281 CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
271 if(ret != sizeof(protect)) 282 if(ret != sizeof(protect)){
283 ret = -errno;
272 printk("protect failed, err = %d", -ret); 284 printk("protect failed, err = %d", -ret);
285 }
273 else ret = 0; 286 else ret = 0;
274 } 287 }
275 else { 288 else {