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>
This commit is contained in:
committed by
Linus Torvalds
parent
77bf440031
commit
ba180fd437
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <sched.h>
|
||||
#include <sys/syscall.h>
|
||||
#include "os.h"
|
||||
#include <sys/time.h>
|
||||
#include <asm/unistd.h>
|
||||
#include "aio.h"
|
||||
#include "init.h"
|
||||
#include "user.h"
|
||||
#include "kern_constants.h"
|
||||
#include "os.h"
|
||||
#include "user.h"
|
||||
|
||||
struct aio_thread_req {
|
||||
enum aio_type type;
|
||||
@@ -27,7 +27,8 @@ struct aio_thread_req {
|
||||
#if defined(HAVE_AIO_ABI)
|
||||
#include <linux/aio_abi.h>
|
||||
|
||||
/* If we have the headers, we are going to build with AIO enabled.
|
||||
/*
|
||||
* If we have the headers, we are going to build with AIO enabled.
|
||||
* If we don't have aio in libc, we define the necessary stubs here.
|
||||
*/
|
||||
|
||||
@@ -51,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
|
||||
|
||||
#endif
|
||||
|
||||
/* The AIO_MMAP cases force the mmapped page into memory here
|
||||
/*
|
||||
* The AIO_MMAP cases force the mmapped page into memory here
|
||||
* rather than in whatever place first touches the data. I used
|
||||
* to do this by touching the page, but that's delicate because
|
||||
* gcc is prone to optimizing that away. So, what's done here
|
||||
@@ -105,12 +107,12 @@ static int aio_thread(void *arg)
|
||||
|
||||
signal(SIGWINCH, SIG_IGN);
|
||||
|
||||
while(1){
|
||||
while (1) {
|
||||
n = io_getevents(ctx, 1, 1, &event, NULL);
|
||||
if(n < 0){
|
||||
if(errno == EINTR)
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
printk("aio_thread - io_getevents failed, "
|
||||
printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
|
||||
"errno = %d\n", errno);
|
||||
}
|
||||
else {
|
||||
@@ -119,9 +121,9 @@ static int aio_thread(void *arg)
|
||||
.err = event.res });
|
||||
reply_fd = ((struct aio_context *) reply.data)->reply_fd;
|
||||
err = write(reply_fd, &reply, sizeof(reply));
|
||||
if(err != sizeof(reply))
|
||||
printk("aio_thread - write failed, fd = %d, "
|
||||
"err = %d\n", reply_fd, errno);
|
||||
if (err != sizeof(reply))
|
||||
printk(UM_KERN_ERR "aio_thread - write failed, "
|
||||
"fd = %d, err = %d\n", reply_fd, errno);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@@ -136,10 +138,10 @@ static int do_not_aio(struct aio_thread_req *req)
|
||||
int n;
|
||||
|
||||
actual = lseek64(req->io_fd, req->offset, SEEK_SET);
|
||||
if(actual != req->offset)
|
||||
if (actual != req->offset)
|
||||
return -errno;
|
||||
|
||||
switch(req->type){
|
||||
switch(req->type) {
|
||||
case AIO_READ:
|
||||
n = read(req->io_fd, req->buf, req->len);
|
||||
break;
|
||||
@@ -150,11 +152,12 @@ static int do_not_aio(struct aio_thread_req *req)
|
||||
n = read(req->io_fd, &c, sizeof(c));
|
||||
break;
|
||||
default:
|
||||
printk("do_not_aio - bad request type : %d\n", req->type);
|
||||
printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
|
||||
req->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if(n < 0)
|
||||
if (n < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
@@ -172,16 +175,18 @@ static int not_aio_thread(void *arg)
|
||||
int err;
|
||||
|
||||
signal(SIGWINCH, SIG_IGN);
|
||||
while(1){
|
||||
while (1) {
|
||||
err = read(aio_req_fd_r, &req, sizeof(req));
|
||||
if(err != sizeof(req)){
|
||||
if(err < 0)
|
||||
printk("not_aio_thread - read failed, "
|
||||
"fd = %d, err = %d\n", aio_req_fd_r,
|
||||
if (err != sizeof(req)) {
|
||||
if (err < 0)
|
||||
printk(UM_KERN_ERR "not_aio_thread - "
|
||||
"read failed, fd = %d, err = %d\n",
|
||||
aio_req_fd_r,
|
||||
errno);
|
||||
else {
|
||||
printk("not_aio_thread - short read, fd = %d, "
|
||||
"length = %d\n", aio_req_fd_r, err);
|
||||
printk(UM_KERN_ERR "not_aio_thread - short "
|
||||
"read, fd = %d, length = %d\n",
|
||||
aio_req_fd_r, err);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
@@ -189,9 +194,9 @@ static int not_aio_thread(void *arg)
|
||||
reply = ((struct aio_thread_reply) { .data = req.aio,
|
||||
.err = err });
|
||||
err = write(req.aio->reply_fd, &reply, sizeof(reply));
|
||||
if(err != sizeof(reply))
|
||||
printk("not_aio_thread - write failed, fd = %d, "
|
||||
"err = %d\n", req.aio->reply_fd, errno);
|
||||
if (err != sizeof(reply))
|
||||
printk(UM_KERN_ERR "not_aio_thread - write failed, "
|
||||
"fd = %d, err = %d\n", req.aio->reply_fd, errno);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -202,19 +207,19 @@ static int init_aio_24(void)
|
||||
int fds[2], err;
|
||||
|
||||
err = os_pipe(fds, 1, 1);
|
||||
if(err)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
aio_req_fd_w = fds[0];
|
||||
aio_req_fd_r = fds[1];
|
||||
|
||||
err = os_set_fd_block(aio_req_fd_w, 0);
|
||||
if(err)
|
||||
if (err)
|
||||
goto out_close_pipe;
|
||||
|
||||
err = run_helper_thread(not_aio_thread, NULL,
|
||||
CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
|
||||
if(err < 0)
|
||||
if (err < 0)
|
||||
goto out_close_pipe;
|
||||
|
||||
aio_pid = err;
|
||||
@@ -227,10 +232,11 @@ out_close_pipe:
|
||||
aio_req_fd_r = -1;
|
||||
out:
|
||||
#ifndef HAVE_AIO_ABI
|
||||
printk("/usr/include/linux/aio_abi.h not present during build\n");
|
||||
printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
|
||||
"build\n");
|
||||
#endif
|
||||
printk("2.6 host AIO support not used - falling back to I/O "
|
||||
"thread\n");
|
||||
printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
|
||||
"I/O thread\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -240,21 +246,21 @@ static int init_aio_26(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if(io_setup(256, &ctx)){
|
||||
if (io_setup(256, &ctx)) {
|
||||
err = -errno;
|
||||
printk("aio_thread failed to initialize context, err = %d\n",
|
||||
errno);
|
||||
printk(UM_KERN_ERR "aio_thread failed to initialize context, "
|
||||
"err = %d\n", errno);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = run_helper_thread(aio_thread, NULL,
|
||||
CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
|
||||
if(err < 0)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
aio_pid = err;
|
||||
|
||||
printk("Using 2.6 host AIO\n");
|
||||
printk(UM_KERN_INFO "Using 2.6 host AIO\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -265,13 +271,13 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
|
||||
int err;
|
||||
|
||||
err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
|
||||
if(err){
|
||||
if (err) {
|
||||
reply = ((struct aio_thread_reply) { .data = aio,
|
||||
.err = err });
|
||||
err = write(aio->reply_fd, &reply, sizeof(reply));
|
||||
if(err != sizeof(reply)){
|
||||
if (err != sizeof(reply)) {
|
||||
err = -errno;
|
||||
printk("submit_aio_26 - write failed, "
|
||||
printk(UM_KERN_ERR "submit_aio_26 - write failed, "
|
||||
"fd = %d, err = %d\n", aio->reply_fd, -err);
|
||||
}
|
||||
else err = 0;
|
||||
@@ -319,23 +325,24 @@ static int init_aio(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
if(!aio_24){
|
||||
if (!aio_24) {
|
||||
err = init_aio_26();
|
||||
if(err && (errno == ENOSYS)){
|
||||
printk("2.6 AIO not supported on the host - "
|
||||
"reverting to 2.4 AIO\n");
|
||||
if (err && (errno == ENOSYS)) {
|
||||
printk(UM_KERN_INFO "2.6 AIO not supported on the "
|
||||
"host - reverting to 2.4 AIO\n");
|
||||
aio_24 = 1;
|
||||
}
|
||||
else return err;
|
||||
}
|
||||
|
||||
if(aio_24)
|
||||
if (aio_24)
|
||||
return init_aio_24();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
|
||||
/*
|
||||
* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
|
||||
* needs to be called when the kernel is running because it calls run_helper,
|
||||
* which needs get_free_page. exit_aio is a __uml_exitcall because the generic
|
||||
* kernel does not run __exitcalls on shutdown, and can't because many of them
|
||||
@@ -366,7 +373,7 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
|
||||
int err;
|
||||
|
||||
err = write(aio_req_fd_w, &req, sizeof(req));
|
||||
if(err == sizeof(req))
|
||||
if (err == sizeof(req))
|
||||
err = 0;
|
||||
else err = -errno;
|
||||
|
||||
@@ -378,9 +385,8 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
|
||||
struct aio_context *aio)
|
||||
{
|
||||
aio->reply_fd = reply_fd;
|
||||
if(aio_24)
|
||||
if (aio_24)
|
||||
return submit_aio_24(type, io_fd, buf, len, offset, aio);
|
||||
else {
|
||||
else
|
||||
return submit_aio_26(type, io_fd, buf, len, offset, aio);
|
||||
}
|
||||
}
|
||||
|
@@ -267,9 +267,9 @@ void os_close_file(int fd)
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int os_seek_file(int fd, __u64 offset)
|
||||
int os_seek_file(int fd, unsigned long long offset)
|
||||
{
|
||||
__u64 actual;
|
||||
unsigned long long actual;
|
||||
|
||||
actual = lseek64(fd, offset, SEEK_SET);
|
||||
if(actual != offset)
|
||||
|
@@ -1,27 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/user.h>
|
||||
#include "kern_util.h"
|
||||
#include "as-layout.h"
|
||||
#include "mem_user.h"
|
||||
#include "irq_user.h"
|
||||
#include "user.h"
|
||||
#include "init.h"
|
||||
#include "uml-config.h"
|
||||
#include "kern_constants.h"
|
||||
#include "kern_util.h"
|
||||
#include "os.h"
|
||||
#include "um_malloc.h"
|
||||
#include "kern_constants.h"
|
||||
|
||||
#define PGD_BOUND (4 * 1024 * 1024)
|
||||
#define STACKSIZE (8 * 1024 * 1024)
|
||||
@@ -31,13 +25,13 @@ static void set_stklim(void)
|
||||
{
|
||||
struct rlimit lim;
|
||||
|
||||
if(getrlimit(RLIMIT_STACK, &lim) < 0){
|
||||
if (getrlimit(RLIMIT_STACK, &lim) < 0) {
|
||||
perror("getrlimit");
|
||||
exit(1);
|
||||
}
|
||||
if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){
|
||||
if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) {
|
||||
lim.rlim_cur = STACKSIZE;
|
||||
if(setrlimit(RLIMIT_STACK, &lim) < 0){
|
||||
if (setrlimit(RLIMIT_STACK, &lim) < 0) {
|
||||
perror("setrlimit");
|
||||
exit(1);
|
||||
}
|
||||
@@ -49,7 +43,7 @@ static __init void do_uml_initcalls(void)
|
||||
initcall_t *call;
|
||||
|
||||
call = &__uml_initcall_start;
|
||||
while (call < &__uml_initcall_end){
|
||||
while (call < &__uml_initcall_end) {
|
||||
(*call)();
|
||||
call++;
|
||||
}
|
||||
@@ -68,7 +62,8 @@ static void install_fatal_handler(int sig)
|
||||
/* All signals are enabled in this handler ... */
|
||||
sigemptyset(&action.sa_mask);
|
||||
|
||||
/* ... including the signal being handled, plus we want the
|
||||
/*
|
||||
* ... including the signal being handled, plus we want the
|
||||
* handler reset to the default behavior, so that if an exit
|
||||
* handler is hanging for some reason, the UML will just die
|
||||
* after this signal is sent a second time.
|
||||
@@ -76,7 +71,7 @@ static void install_fatal_handler(int sig)
|
||||
action.sa_flags = SA_RESETHAND | SA_NODEFER;
|
||||
action.sa_restorer = NULL;
|
||||
action.sa_handler = last_ditch_exit;
|
||||
if(sigaction(sig, &action, NULL) < 0){
|
||||
if (sigaction(sig, &action, NULL) < 0) {
|
||||
printf("failed to install handler for signal %d - errno = %d\n",
|
||||
errno);
|
||||
exit(1);
|
||||
@@ -92,7 +87,8 @@ static void setup_env_path(void)
|
||||
int path_len = 0;
|
||||
|
||||
old_path = getenv("PATH");
|
||||
/* if no PATH variable is set or it has an empty value
|
||||
/*
|
||||
* if no PATH variable is set or it has an empty value
|
||||
* just use the default + /usr/lib/uml
|
||||
*/
|
||||
if (!old_path || (path_len = strlen(old_path)) == 0) {
|
||||
@@ -125,38 +121,41 @@ int __init main(int argc, char **argv, char **envp)
|
||||
setup_env_path();
|
||||
|
||||
new_argv = malloc((argc + 1) * sizeof(char *));
|
||||
if(new_argv == NULL){
|
||||
if (new_argv == NULL) {
|
||||
perror("Mallocing argv");
|
||||
exit(1);
|
||||
}
|
||||
for(i=0;i<argc;i++){
|
||||
for (i = 0; i < argc; i++) {
|
||||
new_argv[i] = strdup(argv[i]);
|
||||
if(new_argv[i] == NULL){
|
||||
if (new_argv[i] == NULL) {
|
||||
perror("Mallocing an arg");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
new_argv[argc] = NULL;
|
||||
|
||||
/* Allow these signals to bring down a UML if all other
|
||||
/*
|
||||
* Allow these signals to bring down a UML if all other
|
||||
* methods of control fail.
|
||||
*/
|
||||
install_fatal_handler(SIGINT);
|
||||
install_fatal_handler(SIGTERM);
|
||||
install_fatal_handler(SIGHUP);
|
||||
|
||||
scan_elf_aux( envp);
|
||||
scan_elf_aux(envp);
|
||||
|
||||
do_uml_initcalls();
|
||||
ret = linux_main(argc, argv);
|
||||
|
||||
/* Disable SIGPROF - I have no idea why libc doesn't do this or turn
|
||||
/*
|
||||
* Disable SIGPROF - I have no idea why libc doesn't do this or turn
|
||||
* off the profiling time, but UML dies with a SIGPROF just before
|
||||
* exiting when profiling is active.
|
||||
*/
|
||||
change_sig(SIGPROF, 0);
|
||||
|
||||
/* This signal stuff used to be in the reboot case. However,
|
||||
/*
|
||||
* This signal stuff used to be in the reboot case. However,
|
||||
* sometimes a SIGVTALRM can come in when we're halting (reproducably
|
||||
* when writing out gcov information, presumably because that takes
|
||||
* some time) and cause a segfault.
|
||||
@@ -167,17 +166,18 @@ int __init main(int argc, char **argv, char **envp)
|
||||
|
||||
/* disable SIGIO for the fds and set SIGIO to be ignored */
|
||||
err = deactivate_all_fds();
|
||||
if(err)
|
||||
if (err)
|
||||
printf("deactivate_all_fds failed, errno = %d\n", -err);
|
||||
|
||||
/* Let any pending signals fire now. This ensures
|
||||
/*
|
||||
* Let any pending signals fire now. This ensures
|
||||
* that they won't be delivered after the exec, when
|
||||
* they are definitely not expected.
|
||||
*/
|
||||
unblock_signals();
|
||||
|
||||
/* Reboot */
|
||||
if(ret){
|
||||
if (ret) {
|
||||
printf("\n");
|
||||
execvp(new_argv[0], new_argv);
|
||||
perror("Failed to exec kernel");
|
||||
@@ -193,17 +193,18 @@ void *__wrap_malloc(int size)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if(!kmalloc_ok)
|
||||
if (!kmalloc_ok)
|
||||
return __real_malloc(size);
|
||||
else if(size <= UM_KERN_PAGE_SIZE)
|
||||
else if (size <= UM_KERN_PAGE_SIZE)
|
||||
/* finding contiguous pages can be hard*/
|
||||
ret = kmalloc(size, UM_GFP_KERNEL);
|
||||
else ret = vmalloc(size);
|
||||
|
||||
/* glibc people insist that if malloc fails, errno should be
|
||||
/*
|
||||
* glibc people insist that if malloc fails, errno should be
|
||||
* set by malloc as well. So we do.
|
||||
*/
|
||||
if(ret == NULL)
|
||||
if (ret == NULL)
|
||||
errno = ENOMEM;
|
||||
|
||||
return ret;
|
||||
@@ -213,7 +214,7 @@ void *__wrap_calloc(int n, int size)
|
||||
{
|
||||
void *ptr = __wrap_malloc(n * size);
|
||||
|
||||
if(ptr == NULL)
|
||||
if (ptr == NULL)
|
||||
return NULL;
|
||||
memset(ptr, 0, n * size);
|
||||
return ptr;
|
||||
@@ -227,7 +228,8 @@ void __wrap_free(void *ptr)
|
||||
{
|
||||
unsigned long addr = (unsigned long) ptr;
|
||||
|
||||
/* We need to know how the allocation happened, so it can be correctly
|
||||
/*
|
||||
* We need to know how the allocation happened, so it can be correctly
|
||||
* freed. This is done by seeing what region of memory the pointer is
|
||||
* in -
|
||||
* physical memory - kmalloc/kfree
|
||||
@@ -245,12 +247,12 @@ void __wrap_free(void *ptr)
|
||||
* there is a possibility for memory leaks.
|
||||
*/
|
||||
|
||||
if((addr >= uml_physmem) && (addr < high_physmem)){
|
||||
if(kmalloc_ok)
|
||||
if ((addr >= uml_physmem) && (addr < high_physmem)) {
|
||||
if (kmalloc_ok)
|
||||
kfree(ptr);
|
||||
}
|
||||
else if((addr >= start_vm) && (addr < end_vm)){
|
||||
if(kmalloc_ok)
|
||||
else if ((addr >= start_vm) && (addr < end_vm)) {
|
||||
if (kmalloc_ok)
|
||||
vfree(ptr);
|
||||
}
|
||||
else __real_free(ptr);
|
||||
|
@@ -1,27 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
|
||||
/*
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/syscall.h>
|
||||
#include "ptrace_user.h"
|
||||
#include "os.h"
|
||||
#include "user.h"
|
||||
#include "process.h"
|
||||
#include "irq_user.h"
|
||||
#include "kern_util.h"
|
||||
#include "longjmp.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "kern_constants.h"
|
||||
#include "uml-config.h"
|
||||
#include <asm/unistd.h>
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "longjmp.h"
|
||||
#include "os.h"
|
||||
#include "process.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "user.h"
|
||||
|
||||
#define ARBITRARY_ADDR -1
|
||||
#define FAILURE_PID -1
|
||||
@@ -37,24 +33,25 @@ unsigned long os_process_pc(int pid)
|
||||
|
||||
sprintf(proc_stat, "/proc/%d/stat", pid);
|
||||
fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
|
||||
if(fd < 0){
|
||||
printk("os_process_pc - couldn't open '%s', err = %d\n",
|
||||
proc_stat, -fd);
|
||||
if (fd < 0) {
|
||||
printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
|
||||
"err = %d\n", proc_stat, -fd);
|
||||
return ARBITRARY_ADDR;
|
||||
}
|
||||
CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
|
||||
if(err < 0){
|
||||
printk("os_process_pc - couldn't read '%s', err = %d\n",
|
||||
proc_stat, errno);
|
||||
if (err < 0) {
|
||||
printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
|
||||
"err = %d\n", proc_stat, errno);
|
||||
os_close_file(fd);
|
||||
return ARBITRARY_ADDR;
|
||||
}
|
||||
os_close_file(fd);
|
||||
pc = ARBITRARY_ADDR;
|
||||
if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
|
||||
if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
|
||||
"%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
|
||||
"%*d %*d %*d %*d %*d %lu", &pc) != 1){
|
||||
printk("os_process_pc - couldn't find pc in '%s'\n", buf);
|
||||
"%*d %*d %*d %*d %*d %lu", &pc) != 1) {
|
||||
printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n",
|
||||
buf);
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
@@ -65,28 +62,29 @@ int os_process_parent(int pid)
|
||||
char data[256];
|
||||
int parent, n, fd;
|
||||
|
||||
if(pid == -1)
|
||||
if (pid == -1)
|
||||
return -1;
|
||||
|
||||
snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
|
||||
fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
|
||||
if(fd < 0){
|
||||
printk("Couldn't open '%s', err = %d\n", stat, -fd);
|
||||
if (fd < 0) {
|
||||
printk(UM_KERN_ERR "Couldn't open '%s', err = %d\n", stat, -fd);
|
||||
return FAILURE_PID;
|
||||
}
|
||||
|
||||
CATCH_EINTR(n = read(fd, data, sizeof(data)));
|
||||
os_close_file(fd);
|
||||
|
||||
if(n < 0){
|
||||
printk("Couldn't read '%s', err = %d\n", stat, errno);
|
||||
if (n < 0) {
|
||||
printk(UM_KERN_ERR "Couldn't read '%s', err = %d\n", stat,
|
||||
errno);
|
||||
return FAILURE_PID;
|
||||
}
|
||||
|
||||
parent = FAILURE_PID;
|
||||
n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
|
||||
if(n != 1)
|
||||
printk("Failed to scan '%s'\n", data);
|
||||
if (n != 1)
|
||||
printk(UM_KERN_ERR "Failed to scan '%s'\n", data);
|
||||
|
||||
return parent;
|
||||
}
|
||||
@@ -99,9 +97,8 @@ void os_stop_process(int pid)
|
||||
void os_kill_process(int pid, int reap_child)
|
||||
{
|
||||
kill(pid, SIGKILL);
|
||||
if(reap_child)
|
||||
if (reap_child)
|
||||
CATCH_EINTR(waitpid(pid, NULL, 0));
|
||||
|
||||
}
|
||||
|
||||
/* This is here uniquely to have access to the userspace errno, i.e. the one
|
||||
@@ -129,7 +126,7 @@ void os_kill_ptraced_process(int pid, int reap_child)
|
||||
kill(pid, SIGKILL);
|
||||
ptrace(PTRACE_KILL, pid);
|
||||
ptrace(PTRACE_CONT, pid);
|
||||
if(reap_child)
|
||||
if (reap_child)
|
||||
CATCH_EINTR(waitpid(pid, NULL, 0));
|
||||
}
|
||||
|
||||
@@ -153,34 +150,35 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
|
||||
void *loc;
|
||||
int prot;
|
||||
|
||||
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
||||
prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
||||
(x ? PROT_EXEC : 0);
|
||||
|
||||
loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
|
||||
fd, off);
|
||||
if(loc == MAP_FAILED)
|
||||
if (loc == MAP_FAILED)
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
|
||||
{
|
||||
int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
||||
int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
|
||||
(x ? PROT_EXEC : 0));
|
||||
|
||||
if(mprotect(addr, len, prot) < 0)
|
||||
if (mprotect(addr, len, prot) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int os_unmap_memory(void *addr, int len)
|
||||
{
|
||||
int err;
|
||||
int err;
|
||||
|
||||
err = munmap(addr, len);
|
||||
if(err < 0)
|
||||
err = munmap(addr, len);
|
||||
if (err < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef MADV_REMOVE
|
||||
@@ -192,7 +190,7 @@ int os_drop_memory(void *addr, int length)
|
||||
int err;
|
||||
|
||||
err = madvise(addr, length, MADV_REMOVE);
|
||||
if(err < 0)
|
||||
if (err < 0)
|
||||
err = -errno;
|
||||
return err;
|
||||
}
|
||||
@@ -202,22 +200,24 @@ int __init can_drop_memory(void)
|
||||
void *addr;
|
||||
int fd, ok = 0;
|
||||
|
||||
printk("Checking host MADV_REMOVE support...");
|
||||
printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
|
||||
fd = create_mem_file(UM_KERN_PAGE_SIZE);
|
||||
if(fd < 0){
|
||||
printk("Creating test memory file failed, err = %d\n", -fd);
|
||||
if (fd < 0) {
|
||||
printk(UM_KERN_ERR "Creating test memory file failed, "
|
||||
"err = %d\n", -fd);
|
||||
goto out;
|
||||
}
|
||||
|
||||
addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0);
|
||||
if(addr == MAP_FAILED){
|
||||
printk("Mapping test memory file failed, err = %d\n", -errno);
|
||||
if (addr == MAP_FAILED) {
|
||||
printk(UM_KERN_ERR "Mapping test memory file failed, "
|
||||
"err = %d\n", -errno);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){
|
||||
printk("MADV_REMOVE failed, err = %d\n", -errno);
|
||||
if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
|
||||
printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
|
||||
goto out_unmap;
|
||||
}
|
||||
|
||||
@@ -256,7 +256,7 @@ int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
|
||||
|
||||
*jmp_ptr = &buf;
|
||||
n = UML_SETJMP(&buf);
|
||||
if(n != 0)
|
||||
if (n != 0)
|
||||
return n;
|
||||
(*fn)(arg);
|
||||
return 0;
|
||||
|
@@ -1,13 +1,14 @@
|
||||
/*
|
||||
* Copyright (C) 2004 PathScale, Inc
|
||||
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include "user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "user.h"
|
||||
|
||||
/* This is set once at boot time and not changed thereafter */
|
||||
|
||||
@@ -23,7 +24,7 @@ void save_registers(int pid, struct uml_pt_regs *regs)
|
||||
int err;
|
||||
|
||||
err = ptrace(PTRACE_GETREGS, pid, 0, regs->regs);
|
||||
if(err < 0)
|
||||
if (err < 0)
|
||||
panic("save_registers - saving registers failed, errno = %d\n",
|
||||
errno);
|
||||
}
|
||||
@@ -33,7 +34,7 @@ void restore_registers(int pid, struct uml_pt_regs *regs)
|
||||
int err;
|
||||
|
||||
err = ptrace(PTRACE_SETREGS, pid, 0, regs->regs);
|
||||
if(err < 0)
|
||||
if (err < 0)
|
||||
panic("restore_registers - saving registers failed, "
|
||||
"errno = %d\n", errno);
|
||||
}
|
||||
@@ -43,7 +44,7 @@ void init_registers(int pid)
|
||||
int err;
|
||||
|
||||
err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
|
||||
errno);
|
||||
}
|
||||
|
@@ -1,24 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2004 PathScale, Inc
|
||||
* Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include "user.h"
|
||||
#include "signal_kern.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "sysdep/barrier.h"
|
||||
#include "sigcontext.h"
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <strings.h>
|
||||
#include "os.h"
|
||||
#include "sysdep/barrier.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "user.h"
|
||||
|
||||
/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
|
||||
/*
|
||||
* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled
|
||||
* together under SIGVTALRM_BIT. SIGPROF is excluded because we want to
|
||||
* be able to profile all of UML, not just the non-critical sections. If
|
||||
* profiling is not thread-safe, then that is not my problem. We can disable
|
||||
@@ -33,7 +30,8 @@
|
||||
#define SIGALRM_BIT 2
|
||||
#define SIGALRM_MASK (1 << SIGALRM_BIT)
|
||||
|
||||
/* These are used by both the signal handlers and
|
||||
/*
|
||||
* These are used by both the signal handlers and
|
||||
* block/unblock_signals. I don't want modifications cached in a
|
||||
* register - they must go straight to memory.
|
||||
*/
|
||||
@@ -45,7 +43,7 @@ void sig_handler(int sig, struct sigcontext *sc)
|
||||
int enabled;
|
||||
|
||||
enabled = signals_enabled;
|
||||
if(!enabled && (sig == SIGIO)){
|
||||
if (!enabled && (sig == SIGIO)) {
|
||||
pending |= SIGIO_MASK;
|
||||
return;
|
||||
}
|
||||
@@ -61,16 +59,16 @@ static void real_alarm_handler(int sig, struct sigcontext *sc)
|
||||
{
|
||||
struct uml_pt_regs regs;
|
||||
|
||||
if(sig == SIGALRM)
|
||||
if (sig == SIGALRM)
|
||||
switch_timers(0);
|
||||
|
||||
if(sc != NULL)
|
||||
if (sc != NULL)
|
||||
copy_sc(®s, sc);
|
||||
regs.is_user = 0;
|
||||
unblock_signals();
|
||||
timer_handler(sig, ®s);
|
||||
|
||||
if(sig == SIGALRM)
|
||||
if (sig == SIGALRM)
|
||||
switch_timers(1);
|
||||
}
|
||||
|
||||
@@ -79,8 +77,8 @@ void alarm_handler(int sig, struct sigcontext *sc)
|
||||
int enabled;
|
||||
|
||||
enabled = signals_enabled;
|
||||
if(!signals_enabled){
|
||||
if(sig == SIGVTALRM)
|
||||
if (!signals_enabled) {
|
||||
if (sig == SIGVTALRM)
|
||||
pending |= SIGVTALRM_MASK;
|
||||
else pending |= SIGALRM_MASK;
|
||||
|
||||
@@ -99,7 +97,7 @@ void set_sigstack(void *sig_stack, int size)
|
||||
.ss_sp = (__ptr_t) sig_stack,
|
||||
.ss_size = size - sizeof(void *) });
|
||||
|
||||
if(sigaltstack(&stack, NULL) != 0)
|
||||
if (sigaltstack(&stack, NULL) != 0)
|
||||
panic("enabling signal stack failed, errno = %d\n", errno);
|
||||
}
|
||||
|
||||
@@ -109,7 +107,7 @@ void remove_sigstack(void)
|
||||
.ss_sp = NULL,
|
||||
.ss_size = 0 });
|
||||
|
||||
if(sigaltstack(&stack, NULL) != 0)
|
||||
if (sigaltstack(&stack, NULL) != 0)
|
||||
panic("disabling signal stack failed, errno = %d\n", errno);
|
||||
}
|
||||
|
||||
@@ -133,26 +131,27 @@ void handle_signal(int sig, struct sigcontext *sc)
|
||||
* with this interrupt.
|
||||
*/
|
||||
bail = to_irq_stack(&pending);
|
||||
if(bail)
|
||||
if (bail)
|
||||
return;
|
||||
|
||||
nested = pending & 1;
|
||||
pending &= ~1;
|
||||
|
||||
while((sig = ffs(pending)) != 0){
|
||||
while ((sig = ffs(pending)) != 0){
|
||||
sig--;
|
||||
pending &= ~(1 << sig);
|
||||
(*handlers[sig])(sig, sc);
|
||||
}
|
||||
|
||||
/* Again, pending comes back with a mask of signals
|
||||
/*
|
||||
* Again, pending comes back with a mask of signals
|
||||
* that arrived while tearing down the stack. If this
|
||||
* is non-zero, we just go back, set up the stack
|
||||
* again, and handle the new interrupts.
|
||||
*/
|
||||
if(!nested)
|
||||
if (!nested)
|
||||
pending = from_irq_stack(nested);
|
||||
} while(pending);
|
||||
} while (pending);
|
||||
}
|
||||
|
||||
extern void hard_handler(int sig);
|
||||
@@ -170,18 +169,18 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
|
||||
sigemptyset(&action.sa_mask);
|
||||
|
||||
va_start(ap, flags);
|
||||
while((mask = va_arg(ap, int)) != -1)
|
||||
while ((mask = va_arg(ap, int)) != -1)
|
||||
sigaddset(&action.sa_mask, mask);
|
||||
va_end(ap);
|
||||
|
||||
action.sa_flags = flags;
|
||||
action.sa_restorer = NULL;
|
||||
if(sigaction(sig, &action, NULL) < 0)
|
||||
if (sigaction(sig, &action, NULL) < 0)
|
||||
panic("sigaction failed - errno = %d\n", errno);
|
||||
|
||||
sigemptyset(&sig_mask);
|
||||
sigaddset(&sig_mask, sig);
|
||||
if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
|
||||
if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
|
||||
panic("sigprocmask failed - errno = %d\n", errno);
|
||||
}
|
||||
|
||||
@@ -192,13 +191,14 @@ int change_sig(int signal, int on)
|
||||
sigemptyset(&sigset);
|
||||
sigaddset(&sigset, signal);
|
||||
sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
|
||||
return(!sigismember(&old, signal));
|
||||
return !sigismember(&old, signal);
|
||||
}
|
||||
|
||||
void block_signals(void)
|
||||
{
|
||||
signals_enabled = 0;
|
||||
/* This must return with signals disabled, so this barrier
|
||||
/*
|
||||
* This must return with signals disabled, so this barrier
|
||||
* ensures that writes are flushed out before the return.
|
||||
* This might matter if gcc figures out how to inline this and
|
||||
* decides to shuffle this code into the caller.
|
||||
@@ -210,27 +210,31 @@ void unblock_signals(void)
|
||||
{
|
||||
int save_pending;
|
||||
|
||||
if(signals_enabled == 1)
|
||||
if (signals_enabled == 1)
|
||||
return;
|
||||
|
||||
/* We loop because the IRQ handler returns with interrupts off. So,
|
||||
/*
|
||||
* We loop because the IRQ handler returns with interrupts off. So,
|
||||
* interrupts may have arrived and we need to re-enable them and
|
||||
* recheck pending.
|
||||
*/
|
||||
while(1){
|
||||
/* Save and reset save_pending after enabling signals. This
|
||||
while(1) {
|
||||
/*
|
||||
* Save and reset save_pending after enabling signals. This
|
||||
* way, pending won't be changed while we're reading it.
|
||||
*/
|
||||
signals_enabled = 1;
|
||||
|
||||
/* Setting signals_enabled and reading pending must
|
||||
/*
|
||||
* Setting signals_enabled and reading pending must
|
||||
* happen in this order.
|
||||
*/
|
||||
mb();
|
||||
|
||||
save_pending = pending;
|
||||
if(save_pending == 0){
|
||||
/* This must return with signals enabled, so
|
||||
if (save_pending == 0) {
|
||||
/*
|
||||
* This must return with signals enabled, so
|
||||
* this barrier ensures that writes are
|
||||
* flushed out before the return. This might
|
||||
* matter if gcc figures out how to inline
|
||||
@@ -243,24 +247,26 @@ void unblock_signals(void)
|
||||
|
||||
pending = 0;
|
||||
|
||||
/* We have pending interrupts, so disable signals, as the
|
||||
/*
|
||||
* We have pending interrupts, so disable signals, as the
|
||||
* handlers expect them off when they are called. They will
|
||||
* be enabled again above.
|
||||
*/
|
||||
|
||||
signals_enabled = 0;
|
||||
|
||||
/* Deal with SIGIO first because the alarm handler might
|
||||
/*
|
||||
* Deal with SIGIO first because the alarm handler might
|
||||
* schedule, leaving the pending SIGIO stranded until we come
|
||||
* back here.
|
||||
*/
|
||||
if(save_pending & SIGIO_MASK)
|
||||
if (save_pending & SIGIO_MASK)
|
||||
sig_handler_common_skas(SIGIO, NULL);
|
||||
|
||||
if(save_pending & SIGALRM_MASK)
|
||||
if (save_pending & SIGALRM_MASK)
|
||||
real_alarm_handler(SIGALRM, NULL);
|
||||
|
||||
if(save_pending & SIGVTALRM_MASK)
|
||||
if (save_pending & SIGVTALRM_MASK)
|
||||
real_alarm_handler(SIGVTALRM, NULL);
|
||||
}
|
||||
}
|
||||
@@ -273,11 +279,11 @@ int get_signals(void)
|
||||
int set_signals(int enable)
|
||||
{
|
||||
int ret;
|
||||
if(signals_enabled == enable)
|
||||
if (signals_enabled == enable)
|
||||
return enable;
|
||||
|
||||
ret = signals_enabled;
|
||||
if(enable)
|
||||
if (enable)
|
||||
unblock_signals();
|
||||
else block_signals();
|
||||
|
||||
|
@@ -1,30 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/wait.h>
|
||||
#include <asm/unistd.h>
|
||||
#include "mem_user.h"
|
||||
#include "mem.h"
|
||||
#include "skas.h"
|
||||
#include "user.h"
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "mm_id.h"
|
||||
#include "os.h"
|
||||
#include "proc_mm.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "kern_util.h"
|
||||
#include "task.h"
|
||||
#include "registers.h"
|
||||
#include "uml-config.h"
|
||||
#include "skas.h"
|
||||
#include "user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "sysdep/stub.h"
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "uml-config.h"
|
||||
|
||||
extern unsigned long batch_syscall_stub, __syscall_stub_start;
|
||||
|
||||
@@ -33,7 +28,7 @@ extern void wait_stub_done(int pid);
|
||||
static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
|
||||
unsigned long *stack)
|
||||
{
|
||||
if(stack == NULL) {
|
||||
if (stack == NULL) {
|
||||
stack = (unsigned long *) mm_idp->stack + 2;
|
||||
*stack = 0;
|
||||
}
|
||||
@@ -67,29 +62,30 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
|
||||
unsigned long * syscall;
|
||||
int err, pid = mm_idp->u.pid;
|
||||
|
||||
if(proc_mm)
|
||||
if (proc_mm)
|
||||
/* FIXME: Need to look up userspace_pid by cpu */
|
||||
pid = userspace_pid[0];
|
||||
|
||||
multi_count++;
|
||||
|
||||
n = ptrace_setregs(pid, syscall_regs);
|
||||
if(n < 0){
|
||||
printk("Registers - \n");
|
||||
for(i = 0; i < MAX_REG_NR; i++)
|
||||
printk("\t%d\t0x%lx\n", i, syscall_regs[i]);
|
||||
if (n < 0) {
|
||||
printk(UM_KERN_ERR "Registers - \n");
|
||||
for (i = 0; i < MAX_REG_NR; i++)
|
||||
printk(UM_KERN_ERR "\t%d\t0x%lx\n", i, syscall_regs[i]);
|
||||
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
|
||||
-n);
|
||||
}
|
||||
|
||||
err = ptrace(PTRACE_CONT, pid, 0, 0);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
|
||||
errno);
|
||||
|
||||
wait_stub_done(pid);
|
||||
|
||||
/* When the stub stops, we find the following values on the
|
||||
/*
|
||||
* When the stub stops, we find the following values on the
|
||||
* beginning of the stack:
|
||||
* (long )return_value
|
||||
* (long )offset to failed sycall-data (0, if no error)
|
||||
@@ -99,24 +95,25 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
|
||||
if (offset) {
|
||||
data = (unsigned long *)(mm_idp->stack +
|
||||
offset - UML_CONFIG_STUB_DATA);
|
||||
printk("do_syscall_stub : ret = %ld, offset = %ld, "
|
||||
printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, "
|
||||
"data = %p\n", ret, offset, data);
|
||||
syscall = (unsigned long *)((unsigned long)data + data[0]);
|
||||
printk("do_syscall_stub: syscall %ld failed, return value = "
|
||||
"0x%lx, expected return value = 0x%lx\n",
|
||||
printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, "
|
||||
"return value = 0x%lx, expected return value = 0x%lx\n",
|
||||
syscall[0], ret, syscall[7]);
|
||||
printk(" syscall parameters: "
|
||||
printk(UM_KERN_ERR " syscall parameters: "
|
||||
"0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
|
||||
syscall[1], syscall[2], syscall[3],
|
||||
syscall[4], syscall[5], syscall[6]);
|
||||
for(n = 1; n < data[0]/sizeof(long); n++) {
|
||||
if(n == 1)
|
||||
printk(" additional syscall data:");
|
||||
if(n % 4 == 1)
|
||||
printk("\n ");
|
||||
for (n = 1; n < data[0]/sizeof(long); n++) {
|
||||
if (n == 1)
|
||||
printk(UM_KERN_ERR " additional syscall "
|
||||
"data:");
|
||||
if (n % 4 == 1)
|
||||
printk("\n" UM_KERN_ERR " ");
|
||||
printk(" 0x%lx", data[n]);
|
||||
}
|
||||
if(n > 1)
|
||||
if (n > 1)
|
||||
printk("\n");
|
||||
}
|
||||
else ret = 0;
|
||||
@@ -132,7 +129,7 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
|
||||
{
|
||||
unsigned long *stack = check_init_stack(mm_idp, *addr);
|
||||
|
||||
if(done && *addr == NULL)
|
||||
if (done && *addr == NULL)
|
||||
single_count++;
|
||||
|
||||
*stack += sizeof(long);
|
||||
@@ -149,8 +146,8 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
|
||||
*stack = 0;
|
||||
multi_op_count++;
|
||||
|
||||
if(!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
|
||||
UM_KERN_PAGE_SIZE - 10 * sizeof(long))){
|
||||
if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
|
||||
UM_KERN_PAGE_SIZE - 10 * sizeof(long))) {
|
||||
*addr = stack;
|
||||
return 0;
|
||||
}
|
||||
@@ -165,14 +162,15 @@ long syscall_stub_data(struct mm_id * mm_idp,
|
||||
unsigned long *stack;
|
||||
int ret = 0;
|
||||
|
||||
/* If *addr still is uninitialized, it *must* contain NULL.
|
||||
/*
|
||||
* If *addr still is uninitialized, it *must* contain NULL.
|
||||
* Thus in this case do_syscall_stub correctly won't be called.
|
||||
*/
|
||||
if((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
|
||||
if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
|
||||
UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) {
|
||||
ret = do_syscall_stub(mm_idp, addr);
|
||||
/* in case of error, don't overwrite data on stack */
|
||||
if(ret)
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -194,7 +192,7 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(proc_mm){
|
||||
if (proc_mm) {
|
||||
struct proc_mm_op map;
|
||||
int fd = mm_idp->u.mm_fd;
|
||||
|
||||
@@ -210,9 +208,10 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
|
||||
.offset= offset
|
||||
} } } );
|
||||
CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
|
||||
if(ret != sizeof(map)){
|
||||
if (ret != sizeof(map)) {
|
||||
ret = -errno;
|
||||
printk("map : /proc/mm map failed, err = %d\n", -ret);
|
||||
printk(UM_KERN_ERR "map : /proc/mm map failed, "
|
||||
"err = %d\n", -ret);
|
||||
}
|
||||
else ret = 0;
|
||||
}
|
||||
@@ -233,7 +232,7 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if(proc_mm){
|
||||
if (proc_mm) {
|
||||
struct proc_mm_op unmap;
|
||||
int fd = mm_idp->u.mm_fd;
|
||||
|
||||
@@ -244,9 +243,10 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
|
||||
(unsigned long) addr,
|
||||
.len = len } } } );
|
||||
CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
|
||||
if(ret != sizeof(unmap)){
|
||||
if (ret != sizeof(unmap)) {
|
||||
ret = -errno;
|
||||
printk("unmap - proc_mm write returned %d\n", ret);
|
||||
printk(UM_KERN_ERR "unmap - proc_mm write returned "
|
||||
"%d\n", ret);
|
||||
}
|
||||
else ret = 0;
|
||||
}
|
||||
@@ -267,7 +267,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
|
||||
struct proc_mm_op protect;
|
||||
int ret;
|
||||
|
||||
if(proc_mm){
|
||||
if (proc_mm) {
|
||||
int fd = mm_idp->u.mm_fd;
|
||||
|
||||
protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
|
||||
@@ -279,9 +279,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
|
||||
.prot = prot } } } );
|
||||
|
||||
CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
|
||||
if(ret != sizeof(protect)){
|
||||
if (ret != sizeof(protect)) {
|
||||
ret = -errno;
|
||||
printk("protect failed, err = %d", -ret);
|
||||
printk(UM_KERN_ERR "protect failed, err = %d", -ret);
|
||||
}
|
||||
else ret = 0;
|
||||
}
|
||||
|
@@ -1,48 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include "ptrace_user.h"
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <asm/types.h>
|
||||
#include "user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "kern_util.h"
|
||||
#include "skas.h"
|
||||
#include "stub-data.h"
|
||||
#include "mm_id.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "sysdep/stub.h"
|
||||
#include "os.h"
|
||||
#include "proc_mm.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "chan_user.h"
|
||||
#include "registers.h"
|
||||
#include "mem.h"
|
||||
#include "uml-config.h"
|
||||
#include "process.h"
|
||||
#include "longjmp.h"
|
||||
#include "kern_constants.h"
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/wait.h>
|
||||
#include <asm/unistd.h>
|
||||
#include "as-layout.h"
|
||||
#include "chan_user.h"
|
||||
#include "kern_constants.h"
|
||||
#include "mem.h"
|
||||
#include "os.h"
|
||||
#include "process.h"
|
||||
#include "proc_mm.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "registers.h"
|
||||
#include "skas.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "user.h"
|
||||
#include "sysdep/stub.h"
|
||||
|
||||
int is_skas_winch(int pid, int fd, void *data)
|
||||
{
|
||||
if(pid != os_getpgrp())
|
||||
return(0);
|
||||
if (pid != os_getpgrp())
|
||||
return 0;
|
||||
|
||||
register_winch_irq(-1, fd, -1, data, 0);
|
||||
return(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ptrace_dump_regs(int pid)
|
||||
@@ -50,13 +40,12 @@ static int ptrace_dump_regs(int pid)
|
||||
unsigned long regs[MAX_REG_NR];
|
||||
int i;
|
||||
|
||||
if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
|
||||
if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
|
||||
return -errno;
|
||||
else {
|
||||
printk("Stub registers -\n");
|
||||
for(i = 0; i < ARRAY_SIZE(regs); i++)
|
||||
printk("\t%d - %lx\n", i, regs[i]);
|
||||
}
|
||||
|
||||
printk(UM_KERN_ERR "Stub registers -\n");
|
||||
for (i = 0; i < ARRAY_SIZE(regs); i++)
|
||||
printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -74,27 +63,28 @@ void wait_stub_done(int pid)
|
||||
{
|
||||
int n, status, err;
|
||||
|
||||
while(1){
|
||||
while (1) {
|
||||
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||
if((n < 0) || !WIFSTOPPED(status))
|
||||
if ((n < 0) || !WIFSTOPPED(status))
|
||||
goto bad_wait;
|
||||
|
||||
if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
|
||||
if (((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
|
||||
break;
|
||||
|
||||
err = ptrace(PTRACE_CONT, pid, 0, 0);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("wait_stub_done : continue failed, errno = %d\n",
|
||||
errno);
|
||||
}
|
||||
|
||||
if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
|
||||
if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
|
||||
return;
|
||||
|
||||
bad_wait:
|
||||
err = ptrace_dump_regs(pid);
|
||||
if(err)
|
||||
printk("Failed to get registers from stub, errno = %d\n", -err);
|
||||
if (err)
|
||||
printk(UM_KERN_ERR "Failed to get registers from stub, "
|
||||
"errno = %d\n", -err);
|
||||
panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
|
||||
"n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
|
||||
}
|
||||
@@ -105,9 +95,9 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
|
||||
{
|
||||
int err;
|
||||
|
||||
if(ptrace_faultinfo){
|
||||
if (ptrace_faultinfo) {
|
||||
err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
|
||||
"errno = %d\n", errno);
|
||||
|
||||
@@ -119,12 +109,13 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
|
||||
}
|
||||
else {
|
||||
err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("Failed to continue stub, pid = %d, errno = %d\n",
|
||||
pid, errno);
|
||||
wait_stub_done(pid);
|
||||
|
||||
/* faultinfo is prepared by the stub-segv-handler at start of
|
||||
/*
|
||||
* faultinfo is prepared by the stub-segv-handler at start of
|
||||
* the stub stack page. We just have to copy it.
|
||||
*/
|
||||
memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
|
||||
@@ -137,8 +128,12 @@ static void handle_segv(int pid, struct uml_pt_regs * regs)
|
||||
segv(regs->faultinfo, 0, 1, NULL);
|
||||
}
|
||||
|
||||
/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/
|
||||
static void handle_trap(int pid, struct uml_pt_regs *regs, int local_using_sysemu)
|
||||
/*
|
||||
* To use the same value of using_sysemu as the caller, ask it that value
|
||||
* (in local_using_sysemu
|
||||
*/
|
||||
static void handle_trap(int pid, struct uml_pt_regs *regs,
|
||||
int local_using_sysemu)
|
||||
{
|
||||
int err, status;
|
||||
|
||||
@@ -149,22 +144,22 @@ static void handle_trap(int pid, struct uml_pt_regs *regs, int local_using_sysem
|
||||
{
|
||||
err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
|
||||
__NR_getpid);
|
||||
if(err < 0)
|
||||
panic("handle_trap - nullifying syscall failed errno = %d\n",
|
||||
errno);
|
||||
|
||||
err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
|
||||
if(err < 0)
|
||||
panic("handle_trap - continuing to end of syscall failed, "
|
||||
if (err < 0)
|
||||
panic("handle_trap - nullifying syscall failed, "
|
||||
"errno = %d\n", errno);
|
||||
|
||||
err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
|
||||
if (err < 0)
|
||||
panic("handle_trap - continuing to end of syscall "
|
||||
"failed, errno = %d\n", errno);
|
||||
|
||||
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
|
||||
if((err < 0) || !WIFSTOPPED(status) ||
|
||||
(WSTOPSIG(status) != SIGTRAP + 0x80)){
|
||||
if ((err < 0) || !WIFSTOPPED(status) ||
|
||||
(WSTOPSIG(status) != SIGTRAP + 0x80)) {
|
||||
err = ptrace_dump_regs(pid);
|
||||
if(err)
|
||||
printk("Failed to get registers from process, "
|
||||
"errno = %d\n", -err);
|
||||
if (err)
|
||||
printk(UM_KERN_ERR "Failed to get registers "
|
||||
"from process, errno = %d\n", -err);
|
||||
panic("handle_trap - failed to wait at end of syscall, "
|
||||
"errno = %d, status = %d\n", errno, status);
|
||||
}
|
||||
@@ -184,38 +179,39 @@ static int userspace_tramp(void *stack)
|
||||
|
||||
init_new_thread_signals();
|
||||
err = set_interval(1);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("userspace_tramp - setting timer failed, errno = %d\n",
|
||||
err);
|
||||
|
||||
if(!proc_mm){
|
||||
/* This has a pte, but it can't be mapped in with the usual
|
||||
if (!proc_mm) {
|
||||
/*
|
||||
* This has a pte, but it can't be mapped in with the usual
|
||||
* tlb_flush mechanism because this is part of that mechanism
|
||||
*/
|
||||
int fd;
|
||||
__u64 offset;
|
||||
unsigned long long offset;
|
||||
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
|
||||
addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE,
|
||||
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
|
||||
if(addr == MAP_FAILED){
|
||||
printk("mapping mmap stub failed, errno = %d\n",
|
||||
errno);
|
||||
if (addr == MAP_FAILED) {
|
||||
printk(UM_KERN_ERR "mapping mmap stub failed, "
|
||||
"errno = %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(stack != NULL){
|
||||
if (stack != NULL) {
|
||||
fd = phys_mapping(to_phys(stack), &offset);
|
||||
addr = mmap((void *) UML_CONFIG_STUB_DATA,
|
||||
UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_FIXED | MAP_SHARED, fd, offset);
|
||||
if(addr == MAP_FAILED){
|
||||
printk("mapping segfault stack failed, "
|
||||
"errno = %d\n", errno);
|
||||
if (addr == MAP_FAILED) {
|
||||
printk(UM_KERN_ERR "mapping segfault stack "
|
||||
"failed, errno = %d\n", errno);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!ptrace_faultinfo && (stack != NULL)){
|
||||
if (!ptrace_faultinfo && (stack != NULL)) {
|
||||
struct sigaction sa;
|
||||
|
||||
unsigned long v = UML_CONFIG_STUB_CODE +
|
||||
@@ -232,13 +228,13 @@ static int userspace_tramp(void *stack)
|
||||
sa.sa_flags = SA_ONSTACK;
|
||||
sa.sa_handler = (void *) v;
|
||||
sa.sa_restorer = NULL;
|
||||
if(sigaction(SIGSEGV, &sa, NULL) < 0)
|
||||
if (sigaction(SIGSEGV, &sa, NULL) < 0)
|
||||
panic("userspace_tramp - setting SIGSEGV handler "
|
||||
"failed - errno = %d\n", errno);
|
||||
}
|
||||
|
||||
os_stop_process(os_getpid());
|
||||
return(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Each element set once, and only accessed by a single processor anyway */
|
||||
@@ -255,35 +251,38 @@ int start_userspace(unsigned long stub_stack)
|
||||
stack = mmap(NULL, UM_KERN_PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if(stack == MAP_FAILED)
|
||||
if (stack == MAP_FAILED)
|
||||
panic("start_userspace : mmap failed, errno = %d", errno);
|
||||
sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
|
||||
|
||||
flags = CLONE_FILES | SIGCHLD;
|
||||
if(proc_mm) flags |= CLONE_VM;
|
||||
if (proc_mm)
|
||||
flags |= CLONE_VM;
|
||||
|
||||
pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
|
||||
if(pid < 0)
|
||||
if (pid < 0)
|
||||
panic("start_userspace : clone failed, errno = %d", errno);
|
||||
|
||||
do {
|
||||
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||
if(n < 0)
|
||||
if (n < 0)
|
||||
panic("start_userspace : wait failed, errno = %d",
|
||||
errno);
|
||||
} while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
|
||||
} while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
|
||||
|
||||
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
|
||||
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
|
||||
panic("start_userspace : expected SIGSTOP, got status = %d",
|
||||
status);
|
||||
|
||||
if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0)
|
||||
panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n",
|
||||
errno);
|
||||
if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
|
||||
(void *) PTRACE_O_TRACESYSGOOD) < 0)
|
||||
panic("start_userspace : PTRACE_OLDSETOPTIONS failed, "
|
||||
"errno = %d\n", errno);
|
||||
|
||||
if(munmap(stack, UM_KERN_PAGE_SIZE) < 0)
|
||||
if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
|
||||
panic("start_userspace : munmap failed, errno = %d\n", errno);
|
||||
|
||||
return(pid);
|
||||
return pid;
|
||||
}
|
||||
|
||||
void userspace(struct uml_pt_regs *regs)
|
||||
@@ -292,7 +291,7 @@ void userspace(struct uml_pt_regs *regs)
|
||||
/* To prevent races if using_sysemu changes under us.*/
|
||||
int local_using_sysemu;
|
||||
|
||||
while(1){
|
||||
while (1) {
|
||||
restore_registers(pid, regs);
|
||||
|
||||
/* Now we set local_using_sysemu to be used for one loop */
|
||||
@@ -302,13 +301,13 @@ void userspace(struct uml_pt_regs *regs)
|
||||
singlestepping(NULL));
|
||||
|
||||
err = ptrace(op, pid, 0, 0);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("userspace - could not resume userspace process, "
|
||||
"pid=%d, ptrace operation = %d, errno = %d\n",
|
||||
pid, op, errno);
|
||||
|
||||
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
|
||||
if(err < 0)
|
||||
if (err < 0)
|
||||
panic("userspace - waitpid failed, errno = %d\n",
|
||||
errno);
|
||||
|
||||
@@ -316,12 +315,14 @@ void userspace(struct uml_pt_regs *regs)
|
||||
save_registers(pid, regs);
|
||||
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
|
||||
|
||||
if(WIFSTOPPED(status)){
|
||||
if (WIFSTOPPED(status)) {
|
||||
int sig = WSTOPSIG(status);
|
||||
switch(sig){
|
||||
switch(sig) {
|
||||
case SIGSEGV:
|
||||
if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){
|
||||
get_skas_faultinfo(pid, ®s->faultinfo);
|
||||
if (PTRACE_FULL_FAULTINFO ||
|
||||
!ptrace_faultinfo) {
|
||||
get_skas_faultinfo(pid,
|
||||
®s->faultinfo);
|
||||
(*sig_info[SIGSEGV])(SIGSEGV, regs);
|
||||
}
|
||||
else handle_segv(pid, regs);
|
||||
@@ -343,14 +344,14 @@ void userspace(struct uml_pt_regs *regs)
|
||||
unblock_signals();
|
||||
break;
|
||||
default:
|
||||
printk("userspace - child stopped with signal "
|
||||
"%d\n", sig);
|
||||
printk(UM_KERN_ERR "userspace - child stopped "
|
||||
"with signal %d\n", sig);
|
||||
}
|
||||
pid = userspace_pid[0];
|
||||
interrupt_end();
|
||||
|
||||
/* Avoid -ERESTARTSYS handling in host */
|
||||
if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
|
||||
if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
|
||||
PT_SYSCALL_NR(regs->regs) = -1;
|
||||
}
|
||||
}
|
||||
@@ -384,7 +385,8 @@ int copy_context_skas0(unsigned long new_stack, int pid)
|
||||
__u64 new_offset;
|
||||
int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
|
||||
|
||||
/* prepare offset and fd of child's stack as argument for parent's
|
||||
/*
|
||||
* prepare offset and fd of child's stack as argument for parent's
|
||||
* and child's mmap2 calls
|
||||
*/
|
||||
*data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
|
||||
@@ -393,28 +395,30 @@ int copy_context_skas0(unsigned long new_stack, int pid)
|
||||
{ { 0, 1000000 / hz() },
|
||||
{ 0, 1000000 / hz() }})});
|
||||
err = ptrace_setregs(pid, thread_regs);
|
||||
if(err < 0)
|
||||
if (err < 0)
|
||||
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
|
||||
"pid = %d, errno = %d\n", pid, -err);
|
||||
|
||||
/* set a well known return code for detection of child write failure */
|
||||
child_data->err = 12345678;
|
||||
|
||||
/* Wait, until parent has finished its work: read child's pid from
|
||||
/*
|
||||
* Wait, until parent has finished its work: read child's pid from
|
||||
* parent's stack, and check, if bad result.
|
||||
*/
|
||||
err = ptrace(PTRACE_CONT, pid, 0, 0);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("Failed to continue new process, pid = %d, "
|
||||
"errno = %d\n", pid, errno);
|
||||
wait_stub_done(pid);
|
||||
|
||||
pid = data->err;
|
||||
if(pid < 0)
|
||||
if (pid < 0)
|
||||
panic("copy_context_skas0 - stub-parent reports error %d\n",
|
||||
-pid);
|
||||
|
||||
/* Wait, until child has finished too: read child's result from
|
||||
/*
|
||||
* Wait, until child has finished too: read child's result from
|
||||
* child's stack and check it.
|
||||
*/
|
||||
wait_stub_done(pid);
|
||||
@@ -455,15 +459,16 @@ void map_stub_pages(int fd, unsigned long code,
|
||||
.offset = code_offset
|
||||
} } });
|
||||
CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
|
||||
if(n != sizeof(mmop)){
|
||||
if (n != sizeof(mmop)) {
|
||||
n = errno;
|
||||
printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n",
|
||||
code, code_fd, (unsigned long long) code_offset);
|
||||
printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
|
||||
"offset = %llx\n", code, code_fd,
|
||||
(unsigned long long) code_offset);
|
||||
panic("map_stub_pages : /proc/mm map for code failed, "
|
||||
"err = %d\n", n);
|
||||
}
|
||||
|
||||
if ( stack ) {
|
||||
if (stack) {
|
||||
__u64 map_offset;
|
||||
int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
|
||||
mmop = ((struct proc_mm_op)
|
||||
@@ -478,7 +483,7 @@ void map_stub_pages(int fd, unsigned long code,
|
||||
.offset = map_offset
|
||||
} } });
|
||||
CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
|
||||
if(n != sizeof(mmop))
|
||||
if (n != sizeof(mmop))
|
||||
panic("map_stub_pages : /proc/mm map for data failed, "
|
||||
"err = %d\n", errno);
|
||||
}
|
||||
@@ -498,7 +503,7 @@ void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
|
||||
|
||||
void switch_threads(jmp_buf *me, jmp_buf *you)
|
||||
{
|
||||
if(UML_SETJMP(me) == 0)
|
||||
if (UML_SETJMP(me) == 0)
|
||||
UML_LONGJMP(you, 1);
|
||||
}
|
||||
|
||||
@@ -526,7 +531,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
|
||||
* after returning to the jumper.
|
||||
*/
|
||||
n = setjmp(initial_jmpbuf);
|
||||
switch(n){
|
||||
switch(n) {
|
||||
case INIT_JMP_NEW_THREAD:
|
||||
(*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
|
||||
(*switch_buf)[0].JB_SP = (unsigned long) stack +
|
||||
@@ -538,10 +543,10 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
|
||||
break;
|
||||
case INIT_JMP_HALT:
|
||||
kmalloc_ok = 0;
|
||||
return(0);
|
||||
return 0;
|
||||
case INIT_JMP_REBOOT:
|
||||
kmalloc_ok = 0;
|
||||
return(1);
|
||||
return 1;
|
||||
default:
|
||||
panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
|
||||
}
|
||||
@@ -557,7 +562,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
|
||||
cb_back = &here;
|
||||
|
||||
block_signals();
|
||||
if(UML_SETJMP(&here) == 0)
|
||||
if (UML_SETJMP(&here) == 0)
|
||||
UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
|
||||
unblock_signals();
|
||||
|
||||
@@ -583,10 +588,10 @@ void __switch_mm(struct mm_id *mm_idp)
|
||||
int err;
|
||||
|
||||
/* FIXME: need cpu pid in __switch_mm */
|
||||
if(proc_mm){
|
||||
if (proc_mm) {
|
||||
err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
|
||||
mm_idp->u.mm_fd);
|
||||
if(err)
|
||||
if (err)
|
||||
panic("__switch_mm - PTRACE_SWITCH_MM failed, "
|
||||
"errno = %d\n", errno);
|
||||
}
|
||||
|
@@ -1,19 +1,23 @@
|
||||
/*
|
||||
* Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#if 0
|
||||
#include "kern_util.h"
|
||||
#include "as-layout.h"
|
||||
#include "task.h"
|
||||
#include "sigcontext.h"
|
||||
#include "skas.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "sysdep/ptrace_user.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "kern_constants.h"
|
||||
#include "as-layout.h"
|
||||
#include "os.h"
|
||||
#include "sigcontext.h"
|
||||
#include "task.h"
|
||||
|
||||
static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
|
||||
|
||||
@@ -24,14 +28,16 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
|
||||
void (*handler)(int, struct uml_pt_regs *);
|
||||
int save_user, save_errno = errno;
|
||||
|
||||
/* This is done because to allow SIGSEGV to be delivered inside a SEGV
|
||||
/*
|
||||
* This is done because to allow SIGSEGV to be delivered inside a SEGV
|
||||
* handler. This can happen in copy_user, and if SEGV is disabled,
|
||||
* the process will die.
|
||||
* XXX Figure out why this is better than SA_NODEFER
|
||||
*/
|
||||
if(sig == SIGSEGV) {
|
||||
if (sig == SIGSEGV) {
|
||||
change_sig(SIGSEGV, 1);
|
||||
/* For segfaults, we want the data from the
|
||||
/*
|
||||
* For segfaults, we want the data from the
|
||||
* sigcontext. In this case, we don't want to mangle
|
||||
* the process registers, so use a static set of
|
||||
* registers. For other signals, the process
|
||||
@@ -44,11 +50,9 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
|
||||
|
||||
save_user = r->is_user;
|
||||
r->is_user = 0;
|
||||
if ( sig == SIGFPE || sig == SIGSEGV ||
|
||||
sig == SIGBUS || sig == SIGILL ||
|
||||
sig == SIGTRAP ) {
|
||||
if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
|
||||
(sig == SIGILL) || (sig == SIGTRAP))
|
||||
GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
|
||||
}
|
||||
|
||||
change_sig(SIGUSR1, 1);
|
||||
|
||||
|
@@ -1,41 +1,29 @@
|
||||
/*
|
||||
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <pty.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fcntl.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include "kern_util.h"
|
||||
#include "user.h"
|
||||
#include "signal_kern.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
#include "sysdep/sigcontext.h"
|
||||
#include "irq_user.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "mem_user.h"
|
||||
#include "init.h"
|
||||
#include "os.h"
|
||||
#include "uml-config.h"
|
||||
#include "tempfile.h"
|
||||
#include "kern_constants.h"
|
||||
#include "skas.h"
|
||||
#include "skas_ptrace.h"
|
||||
#include "os.h"
|
||||
#include "mem_user.h"
|
||||
#include "ptrace_user.h"
|
||||
#include "registers.h"
|
||||
#include "skas_ptrace.h"
|
||||
|
||||
static int ptrace_child(void *arg)
|
||||
{
|
||||
@@ -44,26 +32,33 @@ static int ptrace_child(void *arg)
|
||||
int sc_result;
|
||||
|
||||
change_sig(SIGWINCH, 0);
|
||||
if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
|
||||
if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
|
||||
perror("ptrace");
|
||||
os_kill_process(pid, 0);
|
||||
}
|
||||
kill(pid, SIGSTOP);
|
||||
|
||||
/*This syscall will be intercepted by the parent. Don't call more than
|
||||
* once, please.*/
|
||||
/*
|
||||
* This syscall will be intercepted by the parent. Don't call more than
|
||||
* once, please.
|
||||
*/
|
||||
sc_result = os_getpid();
|
||||
|
||||
if (sc_result == pid)
|
||||
ret = 1; /*Nothing modified by the parent, we are running
|
||||
normally.*/
|
||||
/* Nothing modified by the parent, we are running normally. */
|
||||
ret = 1;
|
||||
else if (sc_result == ppid)
|
||||
ret = 0; /*Expected in check_ptrace and check_sysemu when they
|
||||
succeed in modifying the stack frame*/
|
||||
/*
|
||||
* Expected in check_ptrace and check_sysemu when they succeed
|
||||
* in modifying the stack frame
|
||||
*/
|
||||
ret = 0;
|
||||
else
|
||||
ret = 2; /*Serious trouble! This could be caused by a bug in
|
||||
host 2.6 SKAS3/2.6 patch before release -V6, together
|
||||
with a bug in the UML code itself.*/
|
||||
/* Serious trouble! This could be caused by a bug in host 2.6
|
||||
* SKAS3/2.6 patch before release -V6, together with a bug in
|
||||
* the UML code itself.
|
||||
*/
|
||||
ret = 2;
|
||||
_exit(ret);
|
||||
}
|
||||
|
||||
@@ -104,16 +99,18 @@ static int start_ptraced_child(void **stack_out)
|
||||
stack = mmap(NULL, UM_KERN_PAGE_SIZE,
|
||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
if(stack == MAP_FAILED)
|
||||
if (stack == MAP_FAILED)
|
||||
fatal_perror("check_ptrace : mmap failed");
|
||||
|
||||
sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
|
||||
pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
|
||||
if(pid < 0)
|
||||
if (pid < 0)
|
||||
fatal_perror("start_ptraced_child : clone failed");
|
||||
|
||||
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||
if(n < 0)
|
||||
if (n < 0)
|
||||
fatal_perror("check_ptrace : clone failed");
|
||||
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
|
||||
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
|
||||
fatal("check_ptrace : expected SIGSTOP, got status = %d",
|
||||
status);
|
||||
|
||||
@@ -132,10 +129,10 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
|
||||
{
|
||||
int status, n, ret = 0;
|
||||
|
||||
if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
|
||||
if (ptrace(PTRACE_CONT, pid, 0, 0) < 0)
|
||||
fatal_perror("stop_ptraced_child : ptrace failed");
|
||||
CATCH_EINTR(n = waitpid(pid, &status, 0));
|
||||
if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
|
||||
if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
|
||||
int exit_with = WEXITSTATUS(status);
|
||||
if (exit_with == 2)
|
||||
non_fatal("check_ptrace : child exited with status 2. "
|
||||
@@ -148,7 +145,7 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
if(munmap(stack, UM_KERN_PAGE_SIZE) < 0)
|
||||
if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
|
||||
fatal_perror("check_ptrace : munmap failed");
|
||||
return ret;
|
||||
}
|
||||
@@ -209,26 +206,26 @@ static void __init check_sysemu(void)
|
||||
sysemu_supported = 0;
|
||||
pid = start_ptraced_child(&stack);
|
||||
|
||||
if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
|
||||
if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
|
||||
goto fail;
|
||||
|
||||
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||
if (n < 0)
|
||||
fatal_perror("check_sysemu : wait failed");
|
||||
if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
|
||||
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
|
||||
fatal("check_sysemu : expected SIGTRAP, got status = %d",
|
||||
status);
|
||||
|
||||
if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
|
||||
if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
|
||||
fatal_perror("check_sysemu : PTRACE_GETREGS failed");
|
||||
if(PT_SYSCALL_NR(regs) != __NR_getpid){
|
||||
if (PT_SYSCALL_NR(regs) != __NR_getpid) {
|
||||
non_fatal("check_sysemu got system call number %d, "
|
||||
"expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
|
||||
if(n < 0){
|
||||
if (n < 0) {
|
||||
non_fatal("check_sysemu : failed to modify system call "
|
||||
"return");
|
||||
goto fail;
|
||||
@@ -244,30 +241,31 @@ static void __init check_sysemu(void)
|
||||
non_fatal("Checking advanced syscall emulation patch for ptrace...");
|
||||
pid = start_ptraced_child(&stack);
|
||||
|
||||
if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
|
||||
if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
|
||||
(void *) PTRACE_O_TRACESYSGOOD) < 0))
|
||||
fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
|
||||
|
||||
while(1){
|
||||
while (1) {
|
||||
count++;
|
||||
if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
|
||||
if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
|
||||
goto fail;
|
||||
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||
if(n < 0)
|
||||
if (n < 0)
|
||||
fatal_perror("check_ptrace : wait failed");
|
||||
|
||||
if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){
|
||||
if (WIFSTOPPED(status) &&
|
||||
(WSTOPSIG(status) == (SIGTRAP|0x80))) {
|
||||
if (!count)
|
||||
fatal("check_ptrace : SYSEMU_SINGLESTEP "
|
||||
"doesn't singlestep");
|
||||
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
|
||||
os_getpid());
|
||||
if(n < 0)
|
||||
if (n < 0)
|
||||
fatal_perror("check_sysemu : failed to modify "
|
||||
"system call return");
|
||||
break;
|
||||
}
|
||||
else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
|
||||
else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
|
||||
count++;
|
||||
else
|
||||
fatal("check_ptrace : expected SIGTRAP or "
|
||||
@@ -279,7 +277,7 @@ static void __init check_sysemu(void)
|
||||
sysemu_supported = 2;
|
||||
non_fatal("OK\n");
|
||||
|
||||
if ( !force_sysemu_disabled )
|
||||
if (!force_sysemu_disabled)
|
||||
set_using_sysemu(sysemu_supported);
|
||||
return;
|
||||
|
||||
@@ -297,29 +295,29 @@ static void __init check_ptrace(void)
|
||||
non_fatal("Checking that ptrace can change system call numbers...");
|
||||
pid = start_ptraced_child(&stack);
|
||||
|
||||
if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
|
||||
if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
|
||||
(void *) PTRACE_O_TRACESYSGOOD) < 0))
|
||||
fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
|
||||
|
||||
while(1){
|
||||
if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
|
||||
while (1) {
|
||||
if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
|
||||
fatal_perror("check_ptrace : ptrace failed");
|
||||
|
||||
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
|
||||
if(n < 0)
|
||||
if (n < 0)
|
||||
fatal_perror("check_ptrace : wait failed");
|
||||
|
||||
if(!WIFSTOPPED(status) ||
|
||||
if (!WIFSTOPPED(status) ||
|
||||
(WSTOPSIG(status) != (SIGTRAP | 0x80)))
|
||||
fatal("check_ptrace : expected (SIGTRAP|0x80), "
|
||||
"got status = %d", status);
|
||||
|
||||
syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
|
||||
0);
|
||||
if(syscall == __NR_getpid){
|
||||
if (syscall == __NR_getpid) {
|
||||
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
|
||||
__NR_getppid);
|
||||
if(n < 0)
|
||||
if (n < 0)
|
||||
fatal_perror("check_ptrace : failed to modify "
|
||||
"system call");
|
||||
break;
|
||||
@@ -337,18 +335,18 @@ static void __init check_coredump_limit(void)
|
||||
struct rlimit lim;
|
||||
int err = getrlimit(RLIMIT_CORE, &lim);
|
||||
|
||||
if(err){
|
||||
if (err) {
|
||||
perror("Getting core dump limit");
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Core dump limits :\n\tsoft - ");
|
||||
if(lim.rlim_cur == RLIM_INFINITY)
|
||||
if (lim.rlim_cur == RLIM_INFINITY)
|
||||
printf("NONE\n");
|
||||
else printf("%lu\n", lim.rlim_cur);
|
||||
|
||||
printf("\thard - ");
|
||||
if(lim.rlim_max == RLIM_INFINITY)
|
||||
if (lim.rlim_max == RLIM_INFINITY)
|
||||
printf("NONE\n");
|
||||
else printf("%lu\n", lim.rlim_max);
|
||||
}
|
||||
@@ -414,7 +412,7 @@ static inline void check_skas3_ptrace_faultinfo(void)
|
||||
n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
|
||||
if (n < 0) {
|
||||
ptrace_faultinfo = 0;
|
||||
if(errno == EIO)
|
||||
if (errno == EIO)
|
||||
non_fatal("not found\n");
|
||||
else
|
||||
perror("not found");
|
||||
@@ -446,7 +444,7 @@ static inline void check_skas3_ptrace_ldt(void)
|
||||
|
||||
n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
|
||||
if (n < 0) {
|
||||
if(errno == EIO)
|
||||
if (errno == EIO)
|
||||
non_fatal("not found\n");
|
||||
else {
|
||||
perror("not found");
|
||||
@@ -454,7 +452,7 @@ static inline void check_skas3_ptrace_ldt(void)
|
||||
ptrace_ldt = 0;
|
||||
}
|
||||
else {
|
||||
if(ptrace_ldt)
|
||||
if (ptrace_ldt)
|
||||
non_fatal("found\n");
|
||||
else
|
||||
non_fatal("found, but use is disabled\n");
|
||||
@@ -477,12 +475,9 @@ static inline void check_skas3_proc_mm(void)
|
||||
proc_mm = 0;
|
||||
perror("not found");
|
||||
}
|
||||
else {
|
||||
if (!proc_mm)
|
||||
non_fatal("found but disabled on command line\n");
|
||||
else
|
||||
non_fatal("found\n");
|
||||
}
|
||||
else if (!proc_mm)
|
||||
non_fatal("found but disabled on command line\n");
|
||||
else non_fatal("found\n");
|
||||
}
|
||||
|
||||
int can_do_skas(void)
|
||||
@@ -493,7 +488,7 @@ int can_do_skas(void)
|
||||
check_skas3_ptrace_faultinfo();
|
||||
check_skas3_ptrace_ldt();
|
||||
|
||||
if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
|
||||
if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
|
||||
skas_needs_stub = 1;
|
||||
|
||||
return 1;
|
||||
@@ -508,25 +503,25 @@ int __init parse_iomem(char *str, int *add)
|
||||
|
||||
driver = str;
|
||||
file = strchr(str,',');
|
||||
if(file == NULL){
|
||||
if (file == NULL) {
|
||||
printf("parse_iomem : failed to parse iomem\n");
|
||||
goto out;
|
||||
}
|
||||
*file = '\0';
|
||||
file++;
|
||||
fd = open(file, O_RDWR, 0);
|
||||
if(fd < 0){
|
||||
if (fd < 0) {
|
||||
os_print_error(fd, "parse_iomem - Couldn't open io file");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(fstat64(fd, &buf) < 0){
|
||||
if (fstat64(fd, &buf) < 0) {
|
||||
perror("parse_iomem - cannot stat_fd file");
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
new = malloc(sizeof(*new));
|
||||
if(new == NULL){
|
||||
if (new == NULL) {
|
||||
perror("Couldn't allocate iomem_region struct");
|
||||
goto out_close;
|
||||
}
|
||||
|
@@ -1,13 +1,11 @@
|
||||
/*
|
||||
* Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
|
||||
* Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <signal.h>
|
||||
#include "kern_util.h"
|
||||
#include "os.h"
|
||||
#include "longjmp.h"
|
||||
#include "sysdep/ptrace.h"
|
||||
|
||||
/* Initialized from linux_main() */
|
||||
void (*sig_info[NSIG])(int, struct uml_pt_regs *);
|
||||
|
@@ -1,14 +1,19 @@
|
||||
/*
|
||||
* Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
|
||||
* Licensed under the GPL
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#include "init.h"
|
||||
#include "kern_constants.h"
|
||||
#include "os.h"
|
||||
#include "user.h"
|
||||
|
||||
@@ -27,13 +32,13 @@ static int __init make_uml_dir(void)
|
||||
char dir[512] = { '\0' };
|
||||
int len, err;
|
||||
|
||||
if(*uml_dir == '~'){
|
||||
if (*uml_dir == '~') {
|
||||
char *home = getenv("HOME");
|
||||
|
||||
err = -ENOENT;
|
||||
if(home == NULL){
|
||||
printk("make_uml_dir : no value in environment for "
|
||||
"$HOME\n");
|
||||
if (home == NULL) {
|
||||
printk(UM_KERN_ERR "make_uml_dir : no value in "
|
||||
"environment for $HOME\n");
|
||||
goto err;
|
||||
}
|
||||
strlcpy(dir, home, sizeof(dir));
|
||||
@@ -52,7 +57,7 @@ static int __init make_uml_dir(void)
|
||||
}
|
||||
strcpy(uml_dir, dir);
|
||||
|
||||
if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
|
||||
if ((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)) {
|
||||
printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
|
||||
err = -errno;
|
||||
goto err_free;
|
||||
@@ -69,8 +74,8 @@ err:
|
||||
/*
|
||||
* Unlinks the files contained in @dir and then removes @dir.
|
||||
* Doesn't handle directory trees, so it's not like rm -rf, but almost such. We
|
||||
* ignore ENOENT errors for anything (they happen, strangely enough - possibly due
|
||||
* to races between multiple dying UML threads).
|
||||
* ignore ENOENT errors for anything (they happen, strangely enough - possibly
|
||||
* due to races between multiple dying UML threads).
|
||||
*/
|
||||
static int remove_files_and_dir(char *dir)
|
||||
{
|
||||
@@ -115,7 +120,8 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This says that there isn't already a user of the specified directory even if
|
||||
/*
|
||||
* This says that there isn't already a user of the specified directory even if
|
||||
* there are errors during the checking. This is because if these errors
|
||||
* happen, the directory is unusable by the pre-existing UML, so we might as
|
||||
* well take it over. This could happen either by
|
||||
@@ -133,44 +139,45 @@ static inline int is_umdir_used(char *dir)
|
||||
int dead, fd, p, n, err;
|
||||
|
||||
n = snprintf(file, sizeof(file), "%s/pid", dir);
|
||||
if(n >= sizeof(file)){
|
||||
printk("is_umdir_used - pid filename too long\n");
|
||||
if (n >= sizeof(file)) {
|
||||
printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n");
|
||||
err = -E2BIG;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dead = 0;
|
||||
fd = open(file, O_RDONLY);
|
||||
if(fd < 0) {
|
||||
if (fd < 0) {
|
||||
fd = -errno;
|
||||
if(fd != -ENOENT){
|
||||
printk("is_umdir_used : couldn't open pid file '%s', "
|
||||
"err = %d\n", file, -fd);
|
||||
if (fd != -ENOENT) {
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't open pid "
|
||||
"file '%s', err = %d\n", file, -fd);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
n = read(fd, pid, sizeof(pid));
|
||||
if(n < 0){
|
||||
printk("is_umdir_used : couldn't read pid file '%s', "
|
||||
"err = %d\n", file, errno);
|
||||
if (n < 0) {
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
|
||||
"'%s', err = %d\n", file, errno);
|
||||
goto out_close;
|
||||
} else if(n == 0){
|
||||
printk("is_umdir_used : couldn't read pid file '%s', "
|
||||
"0-byte read\n", file);
|
||||
} else if (n == 0) {
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
|
||||
"'%s', 0-byte read\n", file);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
p = strtoul(pid, &end, 0);
|
||||
if(end == pid){
|
||||
printk("is_umdir_used : couldn't parse pid file '%s', "
|
||||
"errno = %d\n", file, errno);
|
||||
if (end == pid) {
|
||||
printk(UM_KERN_ERR "is_umdir_used : couldn't parse pid file "
|
||||
"'%s', errno = %d\n", file, errno);
|
||||
goto out_close;
|
||||
}
|
||||
|
||||
if((kill(p, 0) == 0) || (errno != ESRCH)){
|
||||
printk("umid \"%s\" is already in use by pid %d\n", umid, p);
|
||||
if ((kill(p, 0) == 0) || (errno != ESRCH)) {
|
||||
printk(UM_KERN_ERR "umid \"%s\" is already in use by pid %d\n",
|
||||
umid, p);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -194,8 +201,8 @@ static int umdir_take_if_dead(char *dir)
|
||||
|
||||
ret = remove_files_and_dir(dir);
|
||||
if (ret) {
|
||||
printk("is_umdir_used - remove_files_and_dir failed with "
|
||||
"err = %d\n", ret);
|
||||
printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir "
|
||||
"failed with err = %d\n", ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@@ -206,27 +213,28 @@ static void __init create_pid_file(void)
|
||||
char pid[sizeof("nnnnn\0")];
|
||||
int fd, n;
|
||||
|
||||
if(umid_file_name("pid", file, sizeof(file)))
|
||||
if (umid_file_name("pid", file, sizeof(file)))
|
||||
return;
|
||||
|
||||
fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
|
||||
if(fd < 0){
|
||||
printk("Open of machine pid file \"%s\" failed: %s\n",
|
||||
file, strerror(errno));
|
||||
if (fd < 0) {
|
||||
printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: "
|
||||
"%s\n", file, strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
snprintf(pid, sizeof(pid), "%d\n", getpid());
|
||||
n = write(fd, pid, strlen(pid));
|
||||
if(n != strlen(pid))
|
||||
printk("Write of pid file failed - err = %d\n", errno);
|
||||
if (n != strlen(pid))
|
||||
printk(UM_KERN_ERR "Write of pid file failed - err = %d\n",
|
||||
errno);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int __init set_umid(char *name)
|
||||
{
|
||||
if(strlen(name) > UMID_LEN - 1)
|
||||
if (strlen(name) > UMID_LEN - 1)
|
||||
return -E2BIG;
|
||||
|
||||
strlcpy(umid, name, sizeof(umid));
|
||||
@@ -242,18 +250,18 @@ int __init make_umid(void)
|
||||
int fd, err;
|
||||
char tmp[256];
|
||||
|
||||
if(umid_setup)
|
||||
if (umid_setup)
|
||||
return 0;
|
||||
|
||||
make_uml_dir();
|
||||
|
||||
if(*umid == '\0'){
|
||||
if (*umid == '\0') {
|
||||
strlcpy(tmp, uml_dir, sizeof(tmp));
|
||||
strlcat(tmp, "XXXXXX", sizeof(tmp));
|
||||
fd = mkstemp(tmp);
|
||||
if(fd < 0){
|
||||
printk("make_umid - mkstemp(%s) failed: %s\n",
|
||||
tmp, strerror(errno));
|
||||
if (fd < 0) {
|
||||
printk(UM_KERN_ERR "make_umid - mkstemp(%s) failed: "
|
||||
"%s\n", tmp, strerror(errno));
|
||||
err = -errno;
|
||||
goto err;
|
||||
}
|
||||
@@ -262,11 +270,12 @@ int __init make_umid(void)
|
||||
|
||||
set_umid(&tmp[strlen(uml_dir)]);
|
||||
|
||||
/* There's a nice tiny little race between this unlink and
|
||||
/*
|
||||
* There's a nice tiny little race between this unlink and
|
||||
* the mkdir below. It'd be nice if there were a mkstemp
|
||||
* for directories.
|
||||
*/
|
||||
if(unlink(tmp)){
|
||||
if (unlink(tmp)) {
|
||||
err = -errno;
|
||||
goto err;
|
||||
}
|
||||
@@ -274,9 +283,9 @@ int __init make_umid(void)
|
||||
|
||||
snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
|
||||
err = mkdir(tmp, 0777);
|
||||
if(err < 0){
|
||||
if (err < 0) {
|
||||
err = -errno;
|
||||
if(err != -EEXIST)
|
||||
if (err != -EEXIST)
|
||||
goto err;
|
||||
|
||||
if (umdir_take_if_dead(tmp) < 0)
|
||||
@@ -284,9 +293,10 @@ int __init make_umid(void)
|
||||
|
||||
err = mkdir(tmp, 0777);
|
||||
}
|
||||
if(err){
|
||||
if (err) {
|
||||
err = -errno;
|
||||
printk("Failed to create '%s' - err = %d\n", umid, -errno);
|
||||
printk(UM_KERN_ERR "Failed to create '%s' - err = %d\n", umid,
|
||||
errno);
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -301,14 +311,15 @@ int __init make_umid(void)
|
||||
|
||||
static int __init make_umid_init(void)
|
||||
{
|
||||
if(!make_umid())
|
||||
if (!make_umid())
|
||||
return 0;
|
||||
|
||||
/* If initializing with the given umid failed, then try again with
|
||||
/*
|
||||
* If initializing with the given umid failed, then try again with
|
||||
* a random one.
|
||||
*/
|
||||
printk("Failed to initialize umid \"%s\", trying with a random umid\n",
|
||||
umid);
|
||||
printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a "
|
||||
"random umid\n", umid);
|
||||
*umid = '\0';
|
||||
make_umid();
|
||||
|
||||
@@ -322,12 +333,12 @@ int __init umid_file_name(char *name, char *buf, int len)
|
||||
int n, err;
|
||||
|
||||
err = make_umid();
|
||||
if(err)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
|
||||
if(n >= len){
|
||||
printk("umid_file_name : buffer too short\n");
|
||||
if (n >= len) {
|
||||
printk(UM_KERN_ERR "umid_file_name : buffer too short\n");
|
||||
return -E2BIG;
|
||||
}
|
||||
|
||||
@@ -341,21 +352,22 @@ char *get_umid(void)
|
||||
|
||||
static int __init set_uml_dir(char *name, int *add)
|
||||
{
|
||||
if(*name == '\0'){
|
||||
if (*name == '\0') {
|
||||
printf("uml_dir can't be an empty string\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(name[strlen(name) - 1] == '/'){
|
||||
if (name[strlen(name) - 1] == '/') {
|
||||
uml_dir = name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uml_dir = malloc(strlen(name) + 2);
|
||||
if(uml_dir == NULL){
|
||||
if (uml_dir == NULL) {
|
||||
printf("Failed to malloc uml_dir - error = %d\n", errno);
|
||||
|
||||
/* Return 0 here because do_initcalls doesn't look at
|
||||
/*
|
||||
* Return 0 here because do_initcalls doesn't look at
|
||||
* the return value.
|
||||
*/
|
||||
return 0;
|
||||
@@ -376,7 +388,7 @@ static void remove_umid_dir(void)
|
||||
|
||||
sprintf(dir, "%s%s", uml_dir, umid);
|
||||
err = remove_files_and_dir(dir);
|
||||
if(err)
|
||||
if (err)
|
||||
printf("remove_umid_dir - remove_files_and_dir failed with "
|
||||
"err = %d\n", err);
|
||||
}
|
||||
|
Reference in New Issue
Block a user