diff options
Diffstat (limited to 'arch/um')
| -rw-r--r-- | arch/um/include/shared/frame_kern.h | 8 | ||||
| -rw-r--r-- | arch/um/kernel/signal.c | 4 | ||||
| -rw-r--r-- | arch/um/kernel/skas/mmu.c | 2 | ||||
| -rw-r--r-- | arch/um/kernel/skas/uaccess.c | 2 | ||||
| -rw-r--r-- | arch/um/os-Linux/mem.c | 230 | ||||
| -rw-r--r-- | arch/um/os-Linux/signal.c | 8 | ||||
| -rw-r--r-- | arch/um/os-Linux/skas/process.c | 19 |
7 files changed, 213 insertions, 60 deletions
diff --git a/arch/um/include/shared/frame_kern.h b/arch/um/include/shared/frame_kern.h index e584e40ee832..f2ca5702a4e2 100644 --- a/arch/um/include/shared/frame_kern.h +++ b/arch/um/include/shared/frame_kern.h | |||
| @@ -6,13 +6,13 @@ | |||
| 6 | #ifndef __FRAME_KERN_H_ | 6 | #ifndef __FRAME_KERN_H_ |
| 7 | #define __FRAME_KERN_H_ | 7 | #define __FRAME_KERN_H_ |
| 8 | 8 | ||
| 9 | extern int setup_signal_stack_sc(unsigned long stack_top, int sig, | 9 | extern int setup_signal_stack_sc(unsigned long stack_top, int sig, |
| 10 | struct k_sigaction *ka, | 10 | struct k_sigaction *ka, |
| 11 | struct pt_regs *regs, | 11 | struct pt_regs *regs, |
| 12 | sigset_t *mask); | 12 | sigset_t *mask); |
| 13 | extern int setup_signal_stack_si(unsigned long stack_top, int sig, | 13 | extern int setup_signal_stack_si(unsigned long stack_top, int sig, |
| 14 | struct k_sigaction *ka, | 14 | struct k_sigaction *ka, |
| 15 | struct pt_regs *regs, siginfo_t *info, | 15 | struct pt_regs *regs, struct siginfo *info, |
| 16 | sigset_t *mask); | 16 | sigset_t *mask); |
| 17 | 17 | ||
| 18 | #endif | 18 | #endif |
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c index 3e831b3fd07b..f57e02e7910f 100644 --- a/arch/um/kernel/signal.c +++ b/arch/um/kernel/signal.c | |||
| @@ -19,7 +19,7 @@ EXPORT_SYMBOL(unblock_signals); | |||
| 19 | * OK, we're invoking a handler | 19 | * OK, we're invoking a handler |
| 20 | */ | 20 | */ |
| 21 | static void handle_signal(struct pt_regs *regs, unsigned long signr, | 21 | static void handle_signal(struct pt_regs *regs, unsigned long signr, |
| 22 | struct k_sigaction *ka, siginfo_t *info) | 22 | struct k_sigaction *ka, struct siginfo *info) |
| 23 | { | 23 | { |
| 24 | sigset_t *oldset = sigmask_to_save(); | 24 | sigset_t *oldset = sigmask_to_save(); |
| 25 | int singlestep = 0; | 25 | int singlestep = 0; |
| @@ -71,7 +71,7 @@ static void handle_signal(struct pt_regs *regs, unsigned long signr, | |||
| 71 | static int kern_do_signal(struct pt_regs *regs) | 71 | static int kern_do_signal(struct pt_regs *regs) |
| 72 | { | 72 | { |
| 73 | struct k_sigaction ka_copy; | 73 | struct k_sigaction ka_copy; |
| 74 | siginfo_t info; | 74 | struct siginfo info; |
| 75 | int sig, handled_sig = 0; | 75 | int sig, handled_sig = 0; |
| 76 | 76 | ||
| 77 | while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { | 77 | while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) { |
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index ff03067a3b14..007d5503f49b 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c | |||
| @@ -123,7 +123,7 @@ void uml_setup_stubs(struct mm_struct *mm) | |||
| 123 | /* dup_mmap already holds mmap_sem */ | 123 | /* dup_mmap already holds mmap_sem */ |
| 124 | err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START, | 124 | err = install_special_mapping(mm, STUB_START, STUB_END - STUB_START, |
| 125 | VM_READ | VM_MAYREAD | VM_EXEC | | 125 | VM_READ | VM_MAYREAD | VM_EXEC | |
| 126 | VM_MAYEXEC | VM_DONTCOPY, | 126 | VM_MAYEXEC | VM_DONTCOPY | VM_PFNMAP, |
| 127 | mm->context.stub_pages); | 127 | mm->context.stub_pages); |
| 128 | if (err) { | 128 | if (err) { |
| 129 | printk(KERN_ERR "install_special_mapping returned %d\n", err); | 129 | printk(KERN_ERR "install_special_mapping returned %d\n", err); |
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 1d3e0c17340b..4ffb644d6c07 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c | |||
| @@ -254,6 +254,6 @@ int strnlen_user(const void __user *str, int len) | |||
| 254 | n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); | 254 | n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); |
| 255 | if (n == 0) | 255 | if (n == 0) |
| 256 | return count + 1; | 256 | return count + 1; |
| 257 | return -EFAULT; | 257 | return 0; |
| 258 | } | 258 | } |
| 259 | EXPORT_SYMBOL(strnlen_user); | 259 | EXPORT_SYMBOL(strnlen_user); |
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index ba4398056fe9..3c4af77e51a2 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c | |||
| @@ -53,6 +53,25 @@ static void __init find_tempdir(void) | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | /* | 55 | /* |
| 56 | * Remove bytes from the front of the buffer and refill it so that if there's a | ||
| 57 | * partial string that we care about, it will be completed, and we can recognize | ||
| 58 | * it. | ||
| 59 | */ | ||
| 60 | static int pop(int fd, char *buf, size_t size, size_t npop) | ||
| 61 | { | ||
| 62 | ssize_t n; | ||
| 63 | size_t len = strlen(&buf[npop]); | ||
| 64 | |||
| 65 | memmove(buf, &buf[npop], len + 1); | ||
| 66 | n = read(fd, &buf[len], size - len - 1); | ||
| 67 | if (n < 0) | ||
| 68 | return -errno; | ||
| 69 | |||
| 70 | buf[len + n] = '\0'; | ||
| 71 | return 1; | ||
| 72 | } | ||
| 73 | |||
| 74 | /* | ||
| 56 | * This will return 1, with the first character in buf being the | 75 | * This will return 1, with the first character in buf being the |
| 57 | * character following the next instance of c in the file. This will | 76 | * character following the next instance of c in the file. This will |
| 58 | * read the file as needed. If there's an error, -errno is returned; | 77 | * read the file as needed. If there's an error, -errno is returned; |
| @@ -61,7 +80,6 @@ static void __init find_tempdir(void) | |||
| 61 | static int next(int fd, char *buf, size_t size, char c) | 80 | static int next(int fd, char *buf, size_t size, char c) |
| 62 | { | 81 | { |
| 63 | ssize_t n; | 82 | ssize_t n; |
| 64 | size_t len; | ||
| 65 | char *ptr; | 83 | char *ptr; |
| 66 | 84 | ||
| 67 | while ((ptr = strchr(buf, c)) == NULL) { | 85 | while ((ptr = strchr(buf, c)) == NULL) { |
| @@ -74,20 +92,129 @@ static int next(int fd, char *buf, size_t size, char c) | |||
| 74 | buf[n] = '\0'; | 92 | buf[n] = '\0'; |
| 75 | } | 93 | } |
| 76 | 94 | ||
| 77 | ptr++; | 95 | return pop(fd, buf, size, ptr - buf + 1); |
| 78 | len = strlen(ptr); | 96 | } |
| 79 | memmove(buf, ptr, len + 1); | 97 | |
| 98 | /* | ||
| 99 | * Decode an octal-escaped and space-terminated path of the form used by | ||
| 100 | * /proc/mounts. May be used to decode a path in-place. "out" must be at least | ||
| 101 | * as large as the input. The output is always null-terminated. "len" gets the | ||
| 102 | * length of the output, excluding the trailing null. Returns 0 if a full path | ||
| 103 | * was successfully decoded, otherwise an error. | ||
| 104 | */ | ||
| 105 | static int decode_path(const char *in, char *out, size_t *len) | ||
| 106 | { | ||
| 107 | char *first = out; | ||
| 108 | int c; | ||
| 109 | int i; | ||
| 110 | int ret = -EINVAL; | ||
| 111 | while (1) { | ||
| 112 | switch (*in) { | ||
| 113 | case '\0': | ||
| 114 | goto out; | ||
| 115 | |||
| 116 | case ' ': | ||
| 117 | ret = 0; | ||
| 118 | goto out; | ||
| 119 | |||
| 120 | case '\\': | ||
| 121 | in++; | ||
| 122 | c = 0; | ||
| 123 | for (i = 0; i < 3; i++) { | ||
| 124 | if (*in < '0' || *in > '7') | ||
| 125 | goto out; | ||
| 126 | c = (c << 3) | (*in++ - '0'); | ||
| 127 | } | ||
| 128 | *(unsigned char *)out++ = (unsigned char) c; | ||
| 129 | break; | ||
| 130 | |||
| 131 | default: | ||
| 132 | *out++ = *in++; | ||
| 133 | break; | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | out: | ||
| 138 | *out = '\0'; | ||
| 139 | *len = out - first; | ||
| 140 | return ret; | ||
| 141 | } | ||
| 142 | |||
| 143 | /* | ||
| 144 | * Computes the length of s when encoded with three-digit octal escape sequences | ||
| 145 | * for the characters in chars. | ||
| 146 | */ | ||
| 147 | static size_t octal_encoded_length(const char *s, const char *chars) | ||
| 148 | { | ||
| 149 | size_t len = strlen(s); | ||
| 150 | while ((s = strpbrk(s, chars)) != NULL) { | ||
| 151 | len += 3; | ||
| 152 | s++; | ||
| 153 | } | ||
| 154 | |||
| 155 | return len; | ||
| 156 | } | ||
| 157 | |||
| 158 | enum { | ||
| 159 | OUTCOME_NOTHING_MOUNTED, | ||
| 160 | OUTCOME_TMPFS_MOUNT, | ||
| 161 | OUTCOME_NON_TMPFS_MOUNT, | ||
| 162 | }; | ||
| 163 | |||
| 164 | /* Read a line of /proc/mounts data looking for a tmpfs mount at "path". */ | ||
| 165 | static int read_mount(int fd, char *buf, size_t bufsize, const char *path, | ||
| 166 | int *outcome) | ||
| 167 | { | ||
| 168 | int found; | ||
| 169 | int match; | ||
| 170 | char *space; | ||
| 171 | size_t len; | ||
| 172 | |||
| 173 | enum { | ||
| 174 | MATCH_NONE, | ||
| 175 | MATCH_EXACT, | ||
| 176 | MATCH_PARENT, | ||
| 177 | }; | ||
| 178 | |||
| 179 | found = next(fd, buf, bufsize, ' '); | ||
| 180 | if (found != 1) | ||
| 181 | return found; | ||
| 80 | 182 | ||
| 81 | /* | 183 | /* |
| 82 | * Refill the buffer so that if there's a partial string that we care | 184 | * If there's no following space in the buffer, then this path is |
| 83 | * about, it will be completed, and we can recognize it. | 185 | * truncated, so it can't be the one we're looking for. |
| 84 | */ | 186 | */ |
| 85 | n = read(fd, &buf[len], size - len - 1); | 187 | space = strchr(buf, ' '); |
| 86 | if (n < 0) | 188 | if (space) { |
| 87 | return -errno; | 189 | match = MATCH_NONE; |
| 190 | if (!decode_path(buf, buf, &len)) { | ||
| 191 | if (!strcmp(buf, path)) | ||
| 192 | match = MATCH_EXACT; | ||
| 193 | else if (!strncmp(buf, path, len) | ||
| 194 | && (path[len] == '/' || !strcmp(buf, "/"))) | ||
| 195 | match = MATCH_PARENT; | ||
| 196 | } | ||
| 197 | |||
| 198 | found = pop(fd, buf, bufsize, space - buf + 1); | ||
| 199 | if (found != 1) | ||
| 200 | return found; | ||
| 201 | |||
| 202 | switch (match) { | ||
| 203 | case MATCH_EXACT: | ||
| 204 | if (!strncmp(buf, "tmpfs", strlen("tmpfs"))) | ||
| 205 | *outcome = OUTCOME_TMPFS_MOUNT; | ||
| 206 | else | ||
| 207 | *outcome = OUTCOME_NON_TMPFS_MOUNT; | ||
| 208 | break; | ||
| 88 | 209 | ||
| 89 | buf[len + n] = '\0'; | 210 | case MATCH_PARENT: |
| 90 | return 1; | 211 | /* This mount obscures any previous ones. */ |
| 212 | *outcome = OUTCOME_NOTHING_MOUNTED; | ||
| 213 | break; | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | return next(fd, buf, bufsize, '\n'); | ||
| 91 | } | 218 | } |
| 92 | 219 | ||
| 93 | /* which_tmpdir is called only during early boot */ | 220 | /* which_tmpdir is called only during early boot */ |
| @@ -106,8 +233,12 @@ static int checked_tmpdir = 0; | |||
| 106 | */ | 233 | */ |
| 107 | static void which_tmpdir(void) | 234 | static void which_tmpdir(void) |
| 108 | { | 235 | { |
| 109 | int fd, found; | 236 | int fd; |
| 110 | char buf[128] = { '\0' }; | 237 | int found; |
| 238 | int outcome; | ||
| 239 | char *path; | ||
| 240 | char *buf; | ||
| 241 | size_t bufsize; | ||
| 111 | 242 | ||
| 112 | if (checked_tmpdir) | 243 | if (checked_tmpdir) |
| 113 | return; | 244 | return; |
| @@ -116,49 +247,66 @@ static void which_tmpdir(void) | |||
| 116 | 247 | ||
| 117 | printf("Checking for tmpfs mount on /dev/shm..."); | 248 | printf("Checking for tmpfs mount on /dev/shm..."); |
| 118 | 249 | ||
| 250 | path = realpath("/dev/shm", NULL); | ||
| 251 | if (!path) { | ||
| 252 | printf("failed to check real path, errno = %d\n", errno); | ||
| 253 | return; | ||
| 254 | } | ||
| 255 | printf("%s...", path); | ||
| 256 | |||
| 257 | /* | ||
| 258 | * The buffer needs to be able to fit the full octal-escaped path, a | ||
| 259 | * space, and a trailing null in order to successfully decode it. | ||
| 260 | */ | ||
| 261 | bufsize = octal_encoded_length(path, " \t\n\\") + 2; | ||
| 262 | |||
| 263 | if (bufsize < 128) | ||
| 264 | bufsize = 128; | ||
| 265 | |||
| 266 | buf = malloc(bufsize); | ||
| 267 | if (!buf) { | ||
| 268 | printf("malloc failed, errno = %d\n", errno); | ||
| 269 | goto out; | ||
| 270 | } | ||
| 271 | buf[0] = '\0'; | ||
| 272 | |||
| 119 | fd = open("/proc/mounts", O_RDONLY); | 273 | fd = open("/proc/mounts", O_RDONLY); |
| 120 | if (fd < 0) { | 274 | if (fd < 0) { |
| 121 | printf("failed to open /proc/mounts, errno = %d\n", errno); | 275 | printf("failed to open /proc/mounts, errno = %d\n", errno); |
| 122 | return; | 276 | goto out1; |
| 123 | } | 277 | } |
| 124 | 278 | ||
| 279 | outcome = OUTCOME_NOTHING_MOUNTED; | ||
| 125 | while (1) { | 280 | while (1) { |
| 126 | found = next(fd, buf, ARRAY_SIZE(buf), ' '); | 281 | found = read_mount(fd, buf, bufsize, path, &outcome); |
| 127 | if (found != 1) | ||
| 128 | break; | ||
| 129 | |||
| 130 | if (!strncmp(buf, "/dev/shm", strlen("/dev/shm"))) | ||
| 131 | goto found; | ||
| 132 | |||
| 133 | found = next(fd, buf, ARRAY_SIZE(buf), '\n'); | ||
| 134 | if (found != 1) | 282 | if (found != 1) |
| 135 | break; | 283 | break; |
| 136 | } | 284 | } |
| 137 | 285 | ||
| 138 | err: | 286 | if (found < 0) { |
| 139 | if (found == 0) | ||
| 140 | printf("nothing mounted on /dev/shm\n"); | ||
| 141 | else if (found < 0) | ||
| 142 | printf("read returned errno %d\n", -found); | 287 | printf("read returned errno %d\n", -found); |
| 288 | } else { | ||
| 289 | switch (outcome) { | ||
| 290 | case OUTCOME_TMPFS_MOUNT: | ||
| 291 | printf("OK\n"); | ||
| 292 | default_tmpdir = "/dev/shm"; | ||
| 293 | break; | ||
| 143 | 294 | ||
| 144 | out: | 295 | case OUTCOME_NON_TMPFS_MOUNT: |
| 145 | close(fd); | 296 | printf("not tmpfs\n"); |
| 146 | 297 | break; | |
| 147 | return; | ||
| 148 | |||
| 149 | found: | ||
| 150 | found = next(fd, buf, ARRAY_SIZE(buf), ' '); | ||
| 151 | if (found != 1) | ||
| 152 | goto err; | ||
| 153 | 298 | ||
| 154 | if (strncmp(buf, "tmpfs", strlen("tmpfs"))) { | 299 | default: |
| 155 | printf("not tmpfs\n"); | 300 | printf("nothing mounted on /dev/shm\n"); |
| 156 | goto out; | 301 | break; |
| 302 | } | ||
| 157 | } | 303 | } |
| 158 | 304 | ||
| 159 | printf("OK\n"); | 305 | close(fd); |
| 160 | default_tmpdir = "/dev/shm"; | 306 | out1: |
| 161 | goto out; | 307 | free(buf); |
| 308 | out: | ||
| 309 | free(path); | ||
| 162 | } | 310 | } |
| 163 | 311 | ||
| 164 | static int __init make_tempfile(const char *template, char **out_tempname, | 312 | static int __init make_tempfile(const char *template, char **out_tempname, |
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 9d9f1b4bf826..905924b773d3 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
| @@ -25,7 +25,7 @@ void (*sig_info[NSIG])(int, struct siginfo *, struct uml_pt_regs *) = { | |||
| 25 | [SIGIO] = sigio_handler, | 25 | [SIGIO] = sigio_handler, |
| 26 | [SIGVTALRM] = timer_handler }; | 26 | [SIGVTALRM] = timer_handler }; |
| 27 | 27 | ||
| 28 | static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc) | 28 | static void sig_handler_common(int sig, struct siginfo *si, mcontext_t *mc) |
| 29 | { | 29 | { |
| 30 | struct uml_pt_regs r; | 30 | struct uml_pt_regs r; |
| 31 | int save_errno = errno; | 31 | int save_errno = errno; |
| @@ -61,7 +61,7 @@ static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc) | |||
| 61 | static int signals_enabled; | 61 | static int signals_enabled; |
| 62 | static unsigned int signals_pending; | 62 | static unsigned int signals_pending; |
| 63 | 63 | ||
| 64 | void sig_handler(int sig, siginfo_t *si, mcontext_t *mc) | 64 | void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) |
| 65 | { | 65 | { |
| 66 | int enabled; | 66 | int enabled; |
| 67 | 67 | ||
| @@ -120,7 +120,7 @@ void set_sigstack(void *sig_stack, int size) | |||
| 120 | panic("enabling signal stack failed, errno = %d\n", errno); | 120 | panic("enabling signal stack failed, errno = %d\n", errno); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = { | 123 | static void (*handlers[_NSIG])(int sig, struct siginfo *si, mcontext_t *mc) = { |
| 124 | [SIGSEGV] = sig_handler, | 124 | [SIGSEGV] = sig_handler, |
| 125 | [SIGBUS] = sig_handler, | 125 | [SIGBUS] = sig_handler, |
| 126 | [SIGILL] = sig_handler, | 126 | [SIGILL] = sig_handler, |
| @@ -162,7 +162,7 @@ static void hard_handler(int sig, siginfo_t *si, void *p) | |||
| 162 | while ((sig = ffs(pending)) != 0){ | 162 | while ((sig = ffs(pending)) != 0){ |
| 163 | sig--; | 163 | sig--; |
| 164 | pending &= ~(1 << sig); | 164 | pending &= ~(1 << sig); |
| 165 | (*handlers[sig])(sig, si, mc); | 165 | (*handlers[sig])(sig, (struct siginfo *)si, mc); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | /* | 168 | /* |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 4625949bf1e4..d531879a4617 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
| @@ -54,7 +54,7 @@ static int ptrace_dump_regs(int pid) | |||
| 54 | 54 | ||
| 55 | void wait_stub_done(int pid) | 55 | void wait_stub_done(int pid) |
| 56 | { | 56 | { |
| 57 | int n, status, err; | 57 | int n, status, err, bad_stop = 0; |
| 58 | 58 | ||
| 59 | while (1) { | 59 | while (1) { |
| 60 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); | 60 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED | __WALL)); |
| @@ -74,6 +74,8 @@ void wait_stub_done(int pid) | |||
| 74 | 74 | ||
| 75 | if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) | 75 | if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) |
| 76 | return; | 76 | return; |
| 77 | else | ||
| 78 | bad_stop = 1; | ||
| 77 | 79 | ||
| 78 | bad_wait: | 80 | bad_wait: |
| 79 | err = ptrace_dump_regs(pid); | 81 | err = ptrace_dump_regs(pid); |
| @@ -83,7 +85,10 @@ bad_wait: | |||
| 83 | printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, " | 85 | printk(UM_KERN_ERR "wait_stub_done : failed to wait for SIGTRAP, " |
| 84 | "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno, | 86 | "pid = %d, n = %d, errno = %d, status = 0x%x\n", pid, n, errno, |
| 85 | status); | 87 | status); |
| 86 | fatal_sigsegv(); | 88 | if (bad_stop) |
| 89 | kill(pid, SIGKILL); | ||
| 90 | else | ||
| 91 | fatal_sigsegv(); | ||
| 87 | } | 92 | } |
| 88 | 93 | ||
| 89 | extern unsigned long current_stub_stack(void); | 94 | extern unsigned long current_stub_stack(void); |
| @@ -409,7 +414,7 @@ void userspace(struct uml_pt_regs *regs) | |||
| 409 | if (WIFSTOPPED(status)) { | 414 | if (WIFSTOPPED(status)) { |
| 410 | int sig = WSTOPSIG(status); | 415 | int sig = WSTOPSIG(status); |
| 411 | 416 | ||
| 412 | ptrace(PTRACE_GETSIGINFO, pid, 0, &si); | 417 | ptrace(PTRACE_GETSIGINFO, pid, 0, (struct siginfo *)&si); |
| 413 | 418 | ||
| 414 | switch (sig) { | 419 | switch (sig) { |
| 415 | case SIGSEGV: | 420 | case SIGSEGV: |
| @@ -417,7 +422,7 @@ void userspace(struct uml_pt_regs *regs) | |||
| 417 | !ptrace_faultinfo) { | 422 | !ptrace_faultinfo) { |
| 418 | get_skas_faultinfo(pid, | 423 | get_skas_faultinfo(pid, |
| 419 | ®s->faultinfo); | 424 | ®s->faultinfo); |
| 420 | (*sig_info[SIGSEGV])(SIGSEGV, &si, | 425 | (*sig_info[SIGSEGV])(SIGSEGV, (struct siginfo *)&si, |
| 421 | regs); | 426 | regs); |
| 422 | } | 427 | } |
| 423 | else handle_segv(pid, regs); | 428 | else handle_segv(pid, regs); |
| @@ -426,14 +431,14 @@ void userspace(struct uml_pt_regs *regs) | |||
| 426 | handle_trap(pid, regs, local_using_sysemu); | 431 | handle_trap(pid, regs, local_using_sysemu); |
| 427 | break; | 432 | break; |
| 428 | case SIGTRAP: | 433 | case SIGTRAP: |
| 429 | relay_signal(SIGTRAP, &si, regs); | 434 | relay_signal(SIGTRAP, (struct siginfo *)&si, regs); |
| 430 | break; | 435 | break; |
| 431 | case SIGVTALRM: | 436 | case SIGVTALRM: |
| 432 | now = os_nsecs(); | 437 | now = os_nsecs(); |
| 433 | if (now < nsecs) | 438 | if (now < nsecs) |
| 434 | break; | 439 | break; |
| 435 | block_signals(); | 440 | block_signals(); |
| 436 | (*sig_info[sig])(sig, &si, regs); | 441 | (*sig_info[sig])(sig, (struct siginfo *)&si, regs); |
| 437 | unblock_signals(); | 442 | unblock_signals(); |
| 438 | nsecs = timer.it_value.tv_sec * | 443 | nsecs = timer.it_value.tv_sec * |
| 439 | UM_NSEC_PER_SEC + | 444 | UM_NSEC_PER_SEC + |
| @@ -447,7 +452,7 @@ void userspace(struct uml_pt_regs *regs) | |||
| 447 | case SIGFPE: | 452 | case SIGFPE: |
| 448 | case SIGWINCH: | 453 | case SIGWINCH: |
| 449 | block_signals(); | 454 | block_signals(); |
| 450 | (*sig_info[sig])(sig, &si, regs); | 455 | (*sig_info[sig])(sig, (struct siginfo *)&si, regs); |
| 451 | unblock_signals(); | 456 | unblock_signals(); |
| 452 | break; | 457 | break; |
| 453 | default: | 458 | default: |
