summaryrefslogtreecommitdiffstats
path: root/arch/um/os-Linux
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/os-Linux')
-rw-r--r--arch/um/os-Linux/aio.c61
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c66
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c44
-rw-r--r--arch/um/os-Linux/file.c47
-rw-r--r--arch/um/os-Linux/helper.c31
-rw-r--r--arch/um/os-Linux/irq.c1
-rw-r--r--arch/um/os-Linux/main.c23
-rw-r--r--arch/um/os-Linux/mem.c15
-rw-r--r--arch/um/os-Linux/process.c47
-rw-r--r--arch/um/os-Linux/sigio.c164
-rw-r--r--arch/um/os-Linux/signal.c51
-rw-r--r--arch/um/os-Linux/skas/mem.c77
-rw-r--r--arch/um/os-Linux/skas/process.c205
-rw-r--r--arch/um/os-Linux/skas/trap.c49
-rw-r--r--arch/um/os-Linux/start_up.c173
-rw-r--r--arch/um/os-Linux/sys-i386/signal.c8
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c2
-rw-r--r--arch/um/os-Linux/sys-x86_64/signal.c6
-rw-r--r--arch/um/os-Linux/time.c1
-rw-r--r--arch/um/os-Linux/trap.c1
-rw-r--r--arch/um/os-Linux/tt.c4
-rw-r--r--arch/um/os-Linux/tty_log.c28
-rw-r--r--arch/um/os-Linux/util.c39
23 files changed, 598 insertions, 545 deletions
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 6ff12743a0bd..9bf944f6a1db 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -132,10 +132,10 @@ static int aio_thread(void *arg)
{ .data = (void *) (long) event.data,
.err = event.res });
reply_fd = ((struct aio_context *) reply.data)->reply_fd;
- err = os_write_file(reply_fd, &reply, sizeof(reply));
+ err = write(reply_fd, &reply, sizeof(reply));
if(err != sizeof(reply))
printk("aio_thread - write failed, fd = %d, "
- "err = %d\n", reply_fd, -err);
+ "err = %d\n", reply_fd, errno);
}
}
return 0;
@@ -146,38 +146,31 @@ static int aio_thread(void *arg)
static int do_not_aio(struct aio_thread_req *req)
{
char c;
- int err;
+ unsigned long long actual;
+ int n;
+
+ actual = lseek64(req->io_fd, req->offset, SEEK_SET);
+ if(actual != req->offset)
+ return -errno;
switch(req->type){
case AIO_READ:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_read_file(req->io_fd, req->buf, req->len);
+ n = read(req->io_fd, req->buf, req->len);
break;
case AIO_WRITE:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_write_file(req->io_fd, req->buf, req->len);
+ n = write(req->io_fd, req->buf, req->len);
break;
case AIO_MMAP:
- err = os_seek_file(req->io_fd, req->offset);
- if(err)
- goto out;
-
- err = os_read_file(req->io_fd, &c, sizeof(c));
+ n = read(req->io_fd, &c, sizeof(c));
break;
default:
printk("do_not_aio - bad request type : %d\n", req->type);
- err = -EINVAL;
- break;
+ return -EINVAL;
}
-out:
- return err;
+ if(n < 0)
+ return -errno;
+ return 0;
}
/* These are initialized in initcalls and not changed */
@@ -193,12 +186,12 @@ static int not_aio_thread(void *arg)
signal(SIGWINCH, SIG_IGN);
while(1){
- err = os_read_file(aio_req_fd_r, &req, sizeof(req));
+ 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,
- -err);
+ errno);
else {
printk("not_aio_thread - short read, fd = %d, "
"length = %d\n", aio_req_fd_r, err);
@@ -207,11 +200,11 @@ static int not_aio_thread(void *arg)
}
err = do_not_aio(&req);
reply = ((struct aio_thread_reply) { .data = req.aio,
- .err = err });
- err = os_write_file(req.aio->reply_fd, &reply, sizeof(reply));
+ .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, -err);
+ "err = %d\n", req.aio->reply_fd, errno);
}
return 0;
@@ -228,6 +221,11 @@ static int init_aio_24(void)
aio_req_fd_w = fds[0];
aio_req_fd_r = fds[1];
+
+ err = os_set_fd_block(aio_req_fd_w, 0);
+ if(err)
+ goto out_close_pipe;
+
err = run_helper_thread(not_aio_thread, NULL,
CLONE_FILES | CLONE_VM | SIGCHLD, &stack, 0);
if(err < 0)
@@ -285,10 +283,12 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
if(err){
reply = ((struct aio_thread_reply) { .data = aio,
.err = err });
- err = os_write_file(aio->reply_fd, &reply, sizeof(reply));
- if(err != sizeof(reply))
+ err = write(aio->reply_fd, &reply, sizeof(reply));
+ if(err != sizeof(reply)){
+ err = -errno;
printk("submit_aio_26 - write failed, "
"fd = %d, err = %d\n", aio->reply_fd, -err);
+ }
else err = 0;
}
@@ -383,9 +383,10 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
};
int err;
- err = os_write_file(aio_req_fd_w, &req, sizeof(req));
+ err = write(aio_req_fd_w, &req, sizeof(req));
if(err == sizeof(req))
err = 0;
+ else err = -errno;
return err;
}
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 863981ba1468..acba30161287 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
* James Leu (jleu@mindspring.net).
* Copyright (C) 2001 by various other people who didn't put their name here.
* Licensed under the GPL.
@@ -16,19 +16,20 @@
#include <net/if.h>
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "net_user.h"
#include "etap.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
#define MAX_PACKET ETH_MAX_PACKET
-void etap_user_init(void *data, void *dev)
+static int etap_user_init(void *data, void *dev)
{
struct ethertap_data *pri = data;
pri->dev = dev;
+ return 0;
}
struct addr_change {
@@ -47,13 +48,16 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
change.what = op;
memcpy(change.addr, addr, sizeof(change.addr));
memcpy(change.netmask, netmask, sizeof(change.netmask));
- n = os_write_file(fd, &change, sizeof(change));
- if(n != sizeof(change))
- printk("etap_change - request failed, err = %d\n", -n);
- output = um_kmalloc(page_size());
+ CATCH_EINTR(n = write(fd, &change, sizeof(change)));
+ if(n != sizeof(change)){
+ printk("etap_change - request failed, err = %d\n", errno);
+ return;
+ }
+
+ output = um_kmalloc(UM_KERN_PAGE_SIZE);
if(output == NULL)
printk("etap_change : Failed to allocate output buffer\n");
- read_output(fd, output, page_size());
+ read_output(fd, output, UM_KERN_PAGE_SIZE);
if(output != NULL){
printk("%s", output);
kfree(output);
@@ -115,13 +119,15 @@ static int etap_tramp(char *dev, char *gate, int control_me,
pe_data.data_me = data_me;
pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
- if(pid < 0) err = pid;
+ if(pid < 0)
+ err = pid;
os_close_file(data_remote);
os_close_file(control_remote);
- n = os_read_file(control_me, &c, sizeof(c));
+ CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
if(n != sizeof(c)){
- printk("etap_tramp : read of status failed, err = %d\n", -n);
- return(-EINVAL);
+ err = -errno;
+ printk("etap_tramp : read of status failed, err = %d\n", -err);
+ return err;
}
if(c != 1){
printk("etap_tramp : uml_net failed\n");
@@ -132,7 +138,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
printk("uml_net didn't exit with status 1\n");
}
- return(err);
+ return err;
}
static int etap_open(void *data)
@@ -142,23 +148,24 @@ static int etap_open(void *data)
int data_fds[2], control_fds[2], err, output_len;
err = tap_open_common(pri->dev, pri->gate_addr);
- if(err) return(err);
+ if(err)
+ return err;
err = os_pipe(data_fds, 0, 0);
if(err < 0){
printk("data os_pipe failed - err = %d\n", -err);
- return(err);
+ return err;
}
err = os_pipe(control_fds, 1, 0);
if(err < 0){
printk("control os_pipe failed - err = %d\n", -err);
- return(err);
+ return err;
}
-
+
err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
control_fds[1], data_fds[0], data_fds[1]);
- output_len = page_size();
+ output_len = UM_KERN_PAGE_SIZE;
output = um_kmalloc(output_len);
read_output(control_fds[0], output, output_len);
@@ -171,13 +178,13 @@ static int etap_open(void *data)
if(err < 0){
printk("etap_tramp failed - err = %d\n", -err);
- return(err);
+ return err;
}
pri->data_fd = data_fds[0];
pri->control_fd = control_fds[0];
iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
- return(data_fds[0]);
+ return data_fds[0];
}
static void etap_close(int fd, void *data)
@@ -195,7 +202,7 @@ static void etap_close(int fd, void *data)
static int etap_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -204,7 +211,8 @@ static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
struct ethertap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if(pri->control_fd == -1) return;
+ if(pri->control_fd == -1)
+ return;
etap_open_addr(addr, netmask, &pri->control_fd);
}
@@ -213,7 +221,8 @@ static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct ethertap_data *pri = data;
- if(pri->control_fd == -1) return;
+ if(pri->control_fd == -1)
+ return;
etap_close_addr(addr, netmask, &pri->control_fd);
}
@@ -227,14 +236,3 @@ const struct net_user_info ethertap_user_info = {
.delete_address = etap_del_addr,
.max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index e846b23f7558..11a9779dc9f1 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -18,17 +18,17 @@
#include "net_user.h"
#include "tuntap.h"
#include "kern_util.h"
-#include "user_util.h"
#include "user.h"
#include "os.h"
#define MAX_PACKET ETH_MAX_PACKET
-void tuntap_user_init(void *data, void *dev)
+static int tuntap_user_init(void *data, void *dev)
{
struct tuntap_data *pri = data;
pri->dev = dev;
+ return 0;
}
static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
@@ -37,7 +37,8 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
struct tuntap_data *pri = data;
tap_check_ips(pri->gate_addr, addr);
- if((pri->fd == -1) || pri->fixed_config) return;
+ if((pri->fd == -1) || pri->fixed_config)
+ return;
open_addr(addr, netmask, pri->dev_name);
}
@@ -46,7 +47,8 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
{
struct tuntap_data *pri = data;
- if((pri->fd == -1) || pri->fixed_config) return;
+ if((pri->fd == -1) || pri->fixed_config)
+ return;
close_addr(addr, netmask, pri->dev_name);
}
@@ -58,7 +60,7 @@ struct tuntap_pre_exec_data {
static void tuntap_pre_exec(void *arg)
{
struct tuntap_pre_exec_data *data = arg;
-
+
dup2(data->stdout, 1);
os_close_file(data->close_me);
}
@@ -83,7 +85,8 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
pid = run_helper(tuntap_pre_exec, &data, argv, NULL);
- if(pid < 0) return(-pid);
+ if(pid < 0)
+ return -pid;
os_close_file(remote);
@@ -114,16 +117,16 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
cmsg = CMSG_FIRSTHDR(&msg);
if(cmsg == NULL){
printk("tuntap_open_tramp : didn't receive a message\n");
- return(-EINVAL);
+ return -EINVAL;
}
if((cmsg->cmsg_level != SOL_SOCKET) ||
(cmsg->cmsg_type != SCM_RIGHTS)){
printk("tuntap_open_tramp : didn't receive a descriptor\n");
- return(-EINVAL);
+ return -EINVAL;
}
*fd_out = ((int *) CMSG_DATA(cmsg))[0];
os_set_exec_close(*fd_out, 1);
- return(0);
+ return 0;
}
static int tuntap_open(void *data)
@@ -135,7 +138,7 @@ static int tuntap_open(void *data)
err = tap_open_common(pri->dev, pri->gate_addr);
if(err < 0)
- return(err);
+ return err;
if(pri->fixed_config){
pri->fd = os_open_file("/dev/net/tun",
@@ -143,7 +146,7 @@ static int tuntap_open(void *data)
if(pri->fd < 0){
printk("Failed to open /dev/net/tun, err = %d\n",
-pri->fd);
- return(pri->fd);
+ return pri->fd;
}
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
@@ -160,7 +163,7 @@ static int tuntap_open(void *data)
if(err < 0){
printk("tuntap_open : os_pipe failed - err = %d\n",
-err);
- return(err);
+ return err;
}
buffer = get_output_buffer(&len);
@@ -175,7 +178,7 @@ static int tuntap_open(void *data)
printk("%s", output);
free_output_buffer(buffer);
printk("tuntap_open_tramp failed - err = %d\n", -err);
- return(err);
+ return err;
}
pri->dev_name = uml_strdup(buffer);
@@ -187,7 +190,7 @@ static int tuntap_open(void *data)
iter_addresses(pri->dev, open_addr, pri->dev_name);
}
- return(pri->fd);
+ return pri->fd;
}
static void tuntap_close(int fd, void *data)
@@ -202,7 +205,7 @@ static void tuntap_close(int fd, void *data)
static int tuntap_set_mtu(int mtu, void *data)
{
- return(mtu);
+ return mtu;
}
const struct net_user_info tuntap_user_info = {
@@ -215,14 +218,3 @@ const struct net_user_info tuntap_user_info = {
.delete_address = tuntap_del_addr,
.max_packet = MAX_PACKET
};
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only. This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index 371b4335f46d..6f92f732d253 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -18,7 +18,6 @@
#include "os.h"
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
static void copy_stat(struct uml_stat *dst, struct stat64 *src)
{
@@ -291,54 +290,22 @@ int os_seek_file(int fd, __u64 offset)
return 0;
}
-static int fault_buffer(void *start, int len,
- int (*copy_proc)(void *addr, void *buf, int len))
-{
- int page = getpagesize(), i;
- char c;
-
- for(i = 0; i < len; i += page){
- if((*copy_proc)(start + i, &c, sizeof(c)))
- return -EFAULT;
- }
- if((len % page) != 0){
- if((*copy_proc)(start + len - 1, &c, sizeof(c)))
- return -EFAULT;
- }
- return 0;
-}
-
-static int file_io(int fd, void *buf, int len,
- int (*io_proc)(int fd, void *buf, int len),
- int (*copy_user_proc)(void *addr, void *buf, int len))
+int os_read_file(int fd, void *buf, int len)
{
- int n, err;
-
- do {
- n = (*io_proc)(fd, buf, len);
- if((n < 0) && (errno == EFAULT)){
- err = fault_buffer(buf, len, copy_user_proc);
- if(err)
- return err;
- n = (*io_proc)(fd, buf, len);
- }
- } while((n < 0) && (errno == EINTR));
+ int n = read(fd, buf, len);
if(n < 0)
return -errno;
return n;
}
-int os_read_file(int fd, void *buf, int len)
-{
- return file_io(fd, buf, len, (int (*)(int, void *, int)) read,
- copy_from_user_proc);
-}
-
int os_write_file(int fd, const void *buf, int len)
{
- return file_io(fd, (void *) buf, len,
- (int (*)(int, void *, int)) write, copy_to_user_proc);
+ int n = write(fd, (void *) buf, len);
+
+ if(n < 0)
+ return -errno;
+ return n;
}
int os_file_size(char *file, unsigned long long *size_out)
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index c7ad6306e22f..97bed16bf4c7 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -13,9 +13,9 @@
#include <sys/wait.h>
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "um_malloc.h"
+#include "kern_constants.h"
struct helper_data {
void (*pre_exec)(void*);
@@ -25,28 +25,18 @@ struct helper_data {
char *buf;
};
-/* Debugging aid, changed only from gdb */
-int helper_pause = 0;
-
-static void helper_hup(int sig)
-{
-}
-
static int helper_child(void *arg)
{
struct helper_data *data = arg;
char **argv = data->argv;
int errval;
- if (helper_pause){
- signal(SIGHUP, helper_hup);
- pause();
- }
if (data->pre_exec != NULL)
(*data->pre_exec)(data->pre_data);
errval = execvp_noalloc(data->buf, argv[0], argv);
- printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval);
- os_write_file(data->fd, &errval, sizeof(errval));
+ printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0],
+ -errval);
+ write(data->fd, &errval, sizeof(errval));
kill(os_getpid(), SIGKILL);
return 0;
}
@@ -81,7 +71,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
goto out_close;
}
- sp = stack + page_size() - sizeof(void *);
+ sp = stack + UM_KERN_PAGE_SIZE - sizeof(void *);
data.pre_exec = pre_exec;
data.pre_data = pre_data;
data.argv = argv;
@@ -98,13 +88,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
close(fds[1]);
fds[1] = -1;
- /* Read the errno value from the child, if the exec failed, or get 0 if
- * the exec succeeded because the pipe fd was set as close-on-exec. */
- n = os_read_file(fds[0], &ret, sizeof(ret));
+ /*
+ * Read the errno value from the child, if the exec failed, or get 0 if
+ * the exec succeeded because the pipe fd was set as close-on-exec.
+ */
+ n = read(fds[0], &ret, sizeof(ret));
if (n == 0) {
ret = pid;
} else {
if (n < 0) {
+ n = -errno;
printk("run_helper : read on pipe failed, ret = %d\n",
-n);
ret = n;
@@ -135,7 +128,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
if (stack == 0)
return -ENOMEM;
- sp = stack + (page_size() << stack_order) - sizeof(void *);
+ sp = stack + (UM_KERN_PAGE_SIZE << stack_order) - sizeof(void *);
pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
if (pid < 0) {
err = -errno;
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index d1b61d474e0a..a633fa8e0a94 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -11,7 +11,6 @@
#include <sys/poll.h>
#include <sys/types.h>
#include <sys/time.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "process.h"
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index 685feaab65d2..ea9a23696f36 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -13,8 +13,8 @@
#include <sys/mman.h>
#include <sys/user.h>
#include <asm/page.h>
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "mem_user.h"
#include "irq_user.h"
#include "user.h"
@@ -25,12 +25,7 @@
#include "os.h"
#include "um_malloc.h"
-/* Set in set_stklim, which is called from main and __wrap_malloc.
- * __wrap_malloc only calls it if main hasn't started.
- */
-unsigned long stacksizelim;
-
-/* Set in main */
+/* Set in main, unchanged thereafter */
char *linux_prog;
#define PGD_BOUND (4 * 1024 * 1024)
@@ -52,7 +47,6 @@ static void set_stklim(void)
exit(1);
}
}
- stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1);
}
static __init void do_uml_initcalls(void)
@@ -126,7 +120,7 @@ extern int uml_exitcode;
extern void scan_elf_aux( char **envp);
-int main(int argc, char **argv, char **envp)
+int __init main(int argc, char **argv, char **envp)
{
char **new_argv;
int ret, i, err;
@@ -224,7 +218,7 @@ int main(int argc, char **argv, char **envp)
ret = 1;
}
printf("\n");
- return(uml_exitcode);
+ return uml_exitcode;
}
#define CAN_KMALLOC() \
@@ -237,7 +231,7 @@ void *__wrap_malloc(int size)
void *ret;
if(!CAN_KMALLOC())
- return(__real_malloc(size));
+ return __real_malloc(size);
else if(size <= PAGE_SIZE) /* finding contiguos pages can be hard*/
ret = um_kmalloc(size);
else ret = um_vmalloc(size);
@@ -248,16 +242,17 @@ void *__wrap_malloc(int size)
if(ret == NULL)
errno = ENOMEM;
- return(ret);
+ return ret;
}
void *__wrap_calloc(int n, int size)
{
void *ptr = __wrap_malloc(n * size);
- if(ptr == NULL) return(NULL);
+ if(ptr == NULL)
+ return NULL;
memset(ptr, 0, n * size);
- return(ptr);
+ return ptr;
}
extern void __real_free(void *);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index f1ea169db85e..c6378c6d10d2 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -11,7 +11,6 @@
#include <sys/statfs.h>
#include "kern_util.h"
#include "user.h"
-#include "user_util.h"
#include "mem_user.h"
#include "init.h"
#include "os.h"
@@ -165,7 +164,8 @@ found:
* (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
* So it isn't 'static' yet.
*/
-int make_tempfile(const char *template, char **out_tempname, int do_unlink)
+int __init make_tempfile(const char *template, char **out_tempname,
+ int do_unlink)
{
char *tempname;
int fd;
@@ -206,7 +206,7 @@ out:
* This proc is used in start_up.c
* So it isn't 'static'.
*/
-int create_tmp_file(unsigned long long len)
+int __init create_tmp_file(unsigned long long len)
{
int fd, err;
char zero;
@@ -232,17 +232,16 @@ int create_tmp_file(unsigned long long len)
zero = 0;
- err = os_write_file(fd, &zero, 1);
+ err = write(fd, &zero, 1);
if(err != 1){
- errno = -err;
- perror("os_write_file");
+ perror("write");
exit(1);
}
return fd;
}
-int create_mem_file(unsigned long long len)
+int __init create_mem_file(unsigned long long len)
{
int err, fd;
@@ -257,7 +256,7 @@ int create_mem_file(unsigned long long len)
}
-void check_tmpexec(void)
+void __init check_tmpexec(void)
{
void *addr;
int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 76bdd6712417..2d9d2ca39299 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -14,7 +14,6 @@
#include "ptrace_user.h"
#include "os.h"
#include "user.h"
-#include "user_util.h"
#include "process.h"
#include "irq_user.h"
#include "kern_util.h"
@@ -22,6 +21,7 @@
#include "skas_ptrace.h"
#include "kern_constants.h"
#include "uml-config.h"
+#include "init.h"
#define ARBITRARY_ADDR -1
#define FAILURE_PID -1
@@ -40,14 +40,14 @@ unsigned long os_process_pc(int pid)
if(fd < 0){
printk("os_process_pc - couldn't open '%s', err = %d\n",
proc_stat, -fd);
- return(ARBITRARY_ADDR);
+ return ARBITRARY_ADDR;
}
- err = os_read_file(fd, buf, sizeof(buf));
+ CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
if(err < 0){
printk("os_process_pc - couldn't read '%s', err = %d\n",
- proc_stat, -err);
+ proc_stat, errno);
os_close_file(fd);
- return(ARBITRARY_ADDR);
+ return ARBITRARY_ADDR;
}
os_close_file(fd);
pc = ARBITRARY_ADDR;
@@ -56,7 +56,7 @@ unsigned long os_process_pc(int pid)
"%*d %*d %*d %*d %*d %lu", &pc) != 1){
printk("os_process_pc - couldn't find pc in '%s'\n", buf);
}
- return(pc);
+ return pc;
}
int os_process_parent(int pid)
@@ -65,21 +65,22 @@ int os_process_parent(int pid)
char data[256];
int parent, n, fd;
- if(pid == -1) return(-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);
- return(FAILURE_PID);
+ return FAILURE_PID;
}
- n = os_read_file(fd, data, sizeof(data));
+ CATCH_EINTR(n = read(fd, data, sizeof(data)));
os_close_file(fd);
if(n < 0){
- printk("Couldn't read '%s', err = %d\n", stat, -n);
- return(FAILURE_PID);
+ printk("Couldn't read '%s', err = %d\n", stat, errno);
+ return FAILURE_PID;
}
parent = FAILURE_PID;
@@ -87,7 +88,7 @@ int os_process_parent(int pid)
if(n != 1)
printk("Failed to scan '%s'\n", data);
- return(parent);
+ return parent;
}
void os_stop_process(int pid)
@@ -145,7 +146,7 @@ void os_usr1_process(int pid)
int os_getpid(void)
{
- return(syscall(__NR_getpid));
+ return syscall(__NR_getpid);
}
int os_getpgrp(void)
@@ -165,8 +166,8 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
fd, off);
if(loc == MAP_FAILED)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
@@ -175,8 +176,8 @@ int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
(x ? PROT_EXEC : 0));
if(mprotect(addr, len, prot) < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
int os_unmap_memory(void *addr, int len)
@@ -185,15 +186,15 @@ int os_unmap_memory(void *addr, int len)
err = munmap(addr, len);
if(err < 0)
- return(-errno);
- return(0);
+ return -errno;
+ return 0;
}
#ifndef MADV_REMOVE
#define MADV_REMOVE KERNEL_MADV_REMOVE
#endif
-int os_drop_memory(void *addr, int length)
+int __init os_drop_memory(void *addr, int length)
{
int err;
@@ -203,7 +204,7 @@ int os_drop_memory(void *addr, int length)
return err;
}
-int can_drop_memory(void)
+int __init can_drop_memory(void)
{
void *addr;
int fd, ok = 0;
@@ -238,13 +239,14 @@ out:
return ok;
}
+#ifdef UML_CONFIG_MODE_TT
void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
{
int flags = 0, pages;
if(sig_stack != NULL){
pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
- set_sigstack(sig_stack, pages * page_size());
+ set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE);
flags = SA_ONSTACK;
}
if(usr1_handler){
@@ -259,6 +261,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
"errno = %d\n", errno);
}
}
+#endif
void init_new_thread_signals(void)
{
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index 3fc43b33db66..8d4e0c6b8c92 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -8,6 +8,7 @@
#include <termios.h>
#include <pty.h>
#include <signal.h>
+#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <sched.h>
@@ -16,10 +17,10 @@
#include "init.h"
#include "user.h"
#include "kern_util.h"
-#include "user_util.h"
#include "sigio.h"
#include "os.h"
#include "um_malloc.h"
+#include "init.h"
/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
* exitcall.
@@ -68,11 +69,12 @@ static int write_sigio_thread(void *unused)
p = &fds->poll[i];
if(p->revents == 0) continue;
if(p->fd == sigio_private[1]){
- n = os_read_file(sigio_private[1], &c, sizeof(c));
+ CATCH_EINTR(n = read(sigio_private[1], &c,
+ sizeof(c)));
if(n != sizeof(c))
printk("write_sigio_thread : "
"read on socket failed, "
- "err = %d\n", -n);
+ "err = %d\n", errno);
tmp = current_poll;
current_poll = next_poll;
next_poll = tmp;
@@ -85,10 +87,10 @@ static int write_sigio_thread(void *unused)
(fds->used - i) * sizeof(*fds->poll));
}
- n = os_write_file(respond_fd, &c, sizeof(c));
+ CATCH_EINTR(n = write(respond_fd, &c, sizeof(c)));
if(n != sizeof(c))
printk("write_sigio_thread : write on socket "
- "failed, err = %d\n", -n);
+ "failed, err = %d\n", errno);
}
}
@@ -126,15 +128,15 @@ static void update_thread(void)
char c;
flags = set_signals(0);
- n = os_write_file(sigio_private[0], &c, sizeof(c));
+ n = write(sigio_private[0], &c, sizeof(c));
if(n != sizeof(c)){
- printk("update_thread : write failed, err = %d\n", -n);
+ printk("update_thread : write failed, err = %d\n", errno);
goto fail;
}
- n = os_read_file(sigio_private[0], &c, sizeof(c));
+ CATCH_EINTR(n = read(sigio_private[0], &c, sizeof(c)));
if(n != sizeof(c)){
- printk("update_thread : read failed, err = %d\n", -n);
+ printk("update_thread : read failed, err = %d\n", errno);
goto fail;
}
@@ -320,6 +322,10 @@ out_close1:
close(l_write_sigio_fds[1]);
}
+/* Changed during early boot */
+static int pty_output_sigio = 0;
+static int pty_close_sigio = 0;
+
void maybe_sigio_broken(int fd, int read)
{
int err;
@@ -357,3 +363,143 @@ static void sigio_cleanup(void)
}
__uml_exitcall(sigio_cleanup);
+
+/* Used as a flag during SIGIO testing early in boot */
+static volatile int got_sigio = 0;
+
+static void __init handler(int sig)
+{
+ got_sigio = 1;
+}
+
+struct openpty_arg {
+ int master;
+ int slave;
+ int err;
+};
+
+static void openpty_cb(void *arg)
+{
+ struct openpty_arg *info = arg;
+
+ info->err = 0;
+ if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
+ info->err = -errno;
+}
+
+static int async_pty(int master, int slave)
+{
+ int flags;
+
+ flags = fcntl(master, F_GETFL);
+ if(flags < 0)
+ return -errno;
+
+ if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
+ (fcntl(master, F_SETOWN, os_getpid()) < 0))
+ return -errno;
+
+ if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
+ return -errno;
+
+ return(0);
+}
+
+static void __init check_one_sigio(void (*proc)(int, int))
+{
+ struct sigaction old, new;
+ struct openpty_arg pty = { .master = -1, .slave = -1 };
+ int master, slave, err;
+
+ initial_thread_cb(openpty_cb, &pty);
+ if(pty.err){
+ printk("openpty failed, errno = %d\n", -pty.err);
+ return;
+ }
+
+ master = pty.master;
+ slave = pty.slave;
+
+ if((master == -1) || (slave == -1)){
+ printk("openpty failed to allocate a pty\n");
+ return;
+ }
+
+ /* Not now, but complain so we now where we failed. */
+ err = raw(master);
+ if (err < 0)
+ panic("check_sigio : __raw failed, errno = %d\n", -err);
+
+ err = async_pty(master, slave);
+ if(err < 0)
+ panic("tty_fds : sigio_async failed, err = %d\n", -err);
+
+ if(sigaction(SIGIO, NULL, &old) < 0)
+ panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
+ new = old;
+ new.sa_handler = handler;
+ if(sigaction(SIGIO, &new, NULL) < 0)
+ panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
+
+ got_sigio = 0;
+ (*proc)(master, slave);
+
+ close(master);
+ close(slave);
+
+ if(sigaction(SIGIO, &old, NULL) < 0)
+ panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
+}
+
+static void tty_output(int master, int slave)
+{
+ int n;
+ char buf[512];
+
+ printk("Checking that host ptys support output SIGIO...");
+
+ memset(buf, 0, sizeof(buf));
+
+ while(write(master, buf, sizeof(buf)) > 0) ;
+ if(errno != EAGAIN)
+ panic("tty_output : write failed, errno = %d\n", errno);
+ while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
+
+ if(got_sigio){
+ printk("Yes\n");
+ pty_output_sigio = 1;
+ }
+ else if(n == -EAGAIN)
+ printk("No, enabling workaround\n");
+ else panic("tty_output : read failed, err = %d\n", n);
+}
+
+static void tty_close(int master, int slave)
+{
+ printk("Checking that host ptys support SIGIO on close...");
+
+ close(slave);
+ if(got_sigio){
+ printk("Yes\n");
+ pty_close_sigio = 1;
+ }
+ else printk("No, enabling workaround\n");
+}
+
+void __init check_sigio(void)
+{
+ if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
+ (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
+ printk("No pseudo-terminals available - skipping pty SIGIO "
+ "check\n");
+ return;
+ }
+ check_one_sigio(tty_output);
+ check_one_sigio(tty_close);
+}
+
+/* Here because it only does the SIGIO testing for now */
+void __init os_check_bugs(void)
+{
+ check_sigio();
+}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 266768629fee..18e5c8b67eb8 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -11,7 +11,6 @@
#include <stdarg.h>
#include <string.h>
#include <sys/mman.h>
-#include "user_util.h"
#include "user.h"
#include "signal_kern.h"
#include "sysdep/sigcontext.h"
@@ -62,15 +61,19 @@ void sig_handler(int sig, struct sigcontext *sc)
static void real_alarm_handler(int sig, struct sigcontext *sc)
{
+ union uml_pt_regs regs;
+
if(sig == SIGALRM)
switch_timers(0);
- CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
- sig, sc);
+ if(sc != NULL)
+ copy_sc(&regs, sc);
+ regs.skas.is_user = 0;
+ unblock_signals();
+ timer_handler(sig, &regs);
if(sig == SIGALRM)
switch_timers(1);
-
}
void alarm_handler(int sig, struct sigcontext *sc)
@@ -114,6 +117,46 @@ void remove_sigstack(void)
void (*handlers[_NSIG])(int sig, struct sigcontext *sc);
+void handle_signal(int sig, struct sigcontext *sc)
+{
+ unsigned long pending = 0;
+
+ do {
+ int nested, bail;
+
+ /*
+ * pending comes back with one bit set for each
+ * interrupt that arrived while setting up the stack,
+ * plus a bit for this interrupt, plus the zero bit is
+ * set if this is a nested interrupt.
+ * If bail is true, then we interrupted another
+ * handler setting up the stack. In this case, we
+ * have to return, and the upper handler will deal
+ * with this interrupt.
+ */
+ bail = to_irq_stack(sig, &pending);
+ if(bail)
+ return;
+
+ nested = pending & 1;
+ pending &= ~1;
+
+ while((sig = ffs(pending)) != 0){
+ sig--;
+ pending &= ~(1 << sig);
+ (*handlers[sig])(sig, sc);
+ }
+
+ /* 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)
+ pending = from_irq_stack(nested);
+ } while(pending);
+}
+
extern void hard_handler(int sig);
void set_handler(int sig, void (*handler)(int), int flags, ...)
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 9383e8751ae7..5c8946320799 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -6,6 +6,7 @@
#include <signal.h>
#include <errno.h>
#include <string.h>
+#include <unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <asm/page.h>
@@ -17,17 +18,17 @@
#include "os.h"
#include "proc_mm.h"
#include "ptrace_user.h"
-#include "user_util.h"
#include "kern_util.h"
#include "task.h"
#include "registers.h"
#include "uml-config.h"
#include "sysdep/ptrace.h"
#include "sysdep/stub.h"
+#include "init.h"
extern unsigned long batch_syscall_stub, __syscall_stub_start;
-extern void wait_stub_done(int pid, int sig, char * fname);
+extern void wait_stub_done(int pid);
static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
unsigned long *stack)
@@ -39,6 +40,19 @@ static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
return stack;
}
+static unsigned long syscall_regs[MAX_REG_NR];
+
+static int __init init_syscall_regs(void)
+{
+ get_safe_registers(syscall_regs, NULL);
+ syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ ((unsigned long) &batch_syscall_stub -
+ (unsigned long) &__syscall_stub_start);
+ return 0;
+}
+
+__initcall(init_syscall_regs);
+
extern int proc_mm;
int single_count = 0;
@@ -47,34 +61,33 @@ int multi_op_count = 0;
static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
{
- unsigned long regs[MAX_REG_NR];
int n, i;
long ret, offset;
unsigned long * data;
unsigned long * syscall;
- int pid = mm_idp->u.pid;
+ int err, pid = mm_idp->u.pid;
if(proc_mm)
-#warning Need to look up userspace_pid by cpu
+ /* FIXME: Need to look up userspace_pid by cpu */
pid = userspace_pid[0];
multi_count++;
- get_safe_registers(regs, NULL);
- regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
- ((unsigned long) &batch_syscall_stub -
- (unsigned long) &__syscall_stub_start);
-
- n = ptrace_setregs(pid, regs);
+ 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, regs[i]);
+ printk("\t%d\t0x%lx\n", i, syscall_regs[i]);
panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
-n);
}
- wait_stub_done(pid, 0, "do_syscall_stub");
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ 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
* beginning of the stack:
@@ -176,14 +189,10 @@ long syscall_stub_data(struct mm_id * mm_idp,
return 0;
}
-int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
- int r, int w, int x, int phys_fd, unsigned long long offset,
- int done, void **data)
+int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
+ int phys_fd, unsigned long long offset, int done, void **data)
{
- int prot, ret;
-
- prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
- (x ? PROT_EXEC : 0);
+ int ret;
if(proc_mm){
struct proc_mm_op map;
@@ -200,9 +209,11 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
.fd = phys_fd,
.offset= offset
} } } );
- ret = os_write_file(fd, &map, sizeof(map));
- if(ret != sizeof(map))
+ CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
+ if(ret != sizeof(map)){
+ ret = -errno;
printk("map : /proc/mm map failed, err = %d\n", -ret);
+ }
else ret = 0;
}
else {
@@ -217,8 +228,8 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len,
return ret;
}
-int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
- void **data)
+int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
+ int done, void **data)
{
int ret;
@@ -232,9 +243,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
{ .addr =
(unsigned long) addr,
.len = len } } } );
- ret = os_write_file(fd, &unmap, sizeof(unmap));
- if(ret != sizeof(unmap))
+ CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
+ if(ret != sizeof(unmap)){
+ ret = -errno;
printk("unmap - proc_mm write returned %d\n", ret);
+ }
else ret = 0;
}
else {
@@ -249,13 +262,11 @@ int unmap(struct mm_id * mm_idp, void *addr, unsigned long len, int done,
}
int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
- int r, int w, int x, int done, void **data)
+ unsigned int prot, int done, void **data)
{
struct proc_mm_op protect;
- int prot, ret;
+ int ret;
- prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
- (x ? PROT_EXEC : 0);
if(proc_mm){
int fd = mm_idp->u.mm_fd;
@@ -267,9 +278,11 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
.len = len,
.prot = prot } } } );
- ret = os_write_file(fd, &protect, sizeof(protect));
- if(ret != sizeof(protect))
+ CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
+ if(ret != sizeof(protect)){
+ ret = -errno;
printk("protect failed, err = %d", -ret);
+ }
else ret = 0;
}
else {
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 0564422c155f..f9d2f8545afe 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -18,7 +18,6 @@
#include <asm/types.h>
#include "user.h"
#include "sysdep/ptrace.h"
-#include "user_util.h"
#include "kern_util.h"
#include "skas.h"
#include "stub-data.h"
@@ -34,6 +33,8 @@
#include "uml-config.h"
#include "process.h"
#include "longjmp.h"
+#include "kern_constants.h"
+#include "as-layout.h"
int is_skas_winch(int pid, int fd, void *data)
{
@@ -44,45 +45,58 @@ int is_skas_winch(int pid, int fd, void *data)
return(1);
}
-void wait_stub_done(int pid, int sig, char * fname)
+static int ptrace_dump_regs(int pid)
{
- int n, status, err;
+ unsigned long regs[MAX_REG_NR];
+ int i;
+
+ 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]);
+ }
+
+ return 0;
+}
- do {
- if ( sig != -1 ) {
- err = ptrace(PTRACE_CONT, pid, 0, sig);
- if(err)
- panic("%s : continue failed, errno = %d\n",
- fname, errno);
- }
- sig = 0;
+/*
+ * Signals that are OK to receive in the stub - we'll just continue it.
+ * SIGWINCH will happen when UML is inside a detached screen.
+ */
+#define STUB_SIG_MASK ((1 << SIGVTALRM) | (1 << SIGWINCH))
+/* Signals that the stub will finish with - anything else is an error */
+#define STUB_DONE_MASK ((1 << SIGUSR1) | (1 << SIGTRAP))
+
+void wait_stub_done(int pid)
+{
+ int n, status, err;
+
+ while(1){
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
- } while((n >= 0) && WIFSTOPPED(status) &&
- ((WSTOPSIG(status) == SIGVTALRM) ||
- /* running UML inside a detached screen can cause
- * SIGWINCHes
- */
- (WSTOPSIG(status) == SIGWINCH)));
-
- if((n < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){
- unsigned long regs[MAX_REG_NR];
-
- if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
- printk("Failed to get registers from stub, "
- "errno = %d\n", errno);
- else {
- int i;
-
- printk("Stub registers -\n");
- for(i = 0; i < ARRAY_SIZE(regs); i++)
- printk("\t%d - %lx\n", i, regs[i]);
- }
- panic("%s : failed to wait for SIGUSR1/SIGTRAP, "
- "pid = %d, n = %d, errno = %d, status = 0x%x\n",
- fname, pid, n, errno, status);
+ if((n < 0) || !WIFSTOPPED(status))
+ goto bad_wait;
+
+ if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
+ break;
+
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ if(err)
+ panic("wait_stub_done : continue failed, errno = %d\n",
+ errno);
}
+
+ 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);
+ panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
+ "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
}
extern unsigned long current_stub_stack(void);
@@ -104,7 +118,11 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
sizeof(struct ptrace_faultinfo));
}
else {
- wait_stub_done(pid, SIGSEGV, "get_skas_faultinfo");
+ err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
+ 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
* the stub stack page. We just have to copy it.
@@ -142,9 +160,14 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
if((err < 0) || !WIFSTOPPED(status) ||
- (WSTOPSIG(status) != SIGTRAP + 0x80))
+ (WSTOPSIG(status) != SIGTRAP + 0x80)){
+ err = ptrace_dump_regs(pid);
+ if(err)
+ printk("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);
+ }
}
handle_syscall(regs);
@@ -172,7 +195,7 @@ static int userspace_tramp(void *stack)
int fd;
__u64 offset;
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
- addr = mmap64((void *) UML_CONFIG_STUB_CODE, page_size(),
+ 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",
@@ -182,8 +205,8 @@ static int userspace_tramp(void *stack)
if(stack != NULL){
fd = phys_mapping(to_phys(stack), &offset);
- addr = mmap((void *) UML_CONFIG_STUB_DATA, page_size(),
- PROT_READ | PROT_WRITE,
+ 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, "
@@ -199,7 +222,7 @@ static int userspace_tramp(void *stack)
(unsigned long) stub_segv_handler -
(unsigned long) &__syscall_stub_start;
- set_sigstack((void *) UML_CONFIG_STUB_DATA, page_size());
+ set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE);
sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGIO);
sigaddset(&sa.sa_mask, SIGWINCH);
@@ -265,7 +288,8 @@ int start_userspace(unsigned long stub_stack)
void userspace(union uml_pt_regs *regs)
{
int err, status, op, pid = userspace_pid[0];
- int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
+ /* To prevent races if using_sysemu changes under us.*/
+ int local_using_sysemu;
while(1){
restore_registers(pid, regs);
@@ -273,7 +297,8 @@ void userspace(union uml_pt_regs *regs)
/* Now we set local_using_sysemu to be used for one loop */
local_using_sysemu = get_using_sysemu();
- op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));
+ op = SELECT_PTRACE_OPERATION(local_using_sysemu,
+ singlestepping(NULL));
err = ptrace(op, pid, 0, 0);
if(err)
@@ -291,10 +316,13 @@ void userspace(union uml_pt_regs *regs)
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
if(WIFSTOPPED(status)){
- switch(WSTOPSIG(status)){
+ int sig = WSTOPSIG(status);
+ switch(sig){
case SIGSEGV:
- if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo)
- user_signal(SIGSEGV, regs, pid);
+ if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){
+ get_skas_faultinfo(pid, &regs->skas.faultinfo);
+ (*sig_info[SIGSEGV])(SIGSEGV, regs);
+ }
else handle_segv(pid, regs);
break;
case SIGTRAP + 0x80:
@@ -309,11 +337,13 @@ void userspace(union uml_pt_regs *regs)
case SIGBUS:
case SIGFPE:
case SIGWINCH:
- user_signal(WSTOPSIG(status), regs, pid);
+ block_signals();
+ (*sig_info[sig])(sig, regs);
+ unblock_signals();
break;
default:
printk("userspace - child stopped with signal "
- "%d\n", WSTOPSIG(status));
+ "%d\n", sig);
}
pid = userspace_pid[0];
interrupt_end();
@@ -325,11 +355,29 @@ void userspace(union uml_pt_regs *regs)
}
}
+static unsigned long thread_regs[MAX_REG_NR];
+static unsigned long thread_fp_regs[HOST_FP_SIZE];
+
+static int __init init_thread_regs(void)
+{
+ get_safe_registers(thread_regs, thread_fp_regs);
+ /* Set parent's instruction pointer to start of clone-stub */
+ thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
+ (unsigned long) stub_clone_handler -
+ (unsigned long) &__syscall_stub_start;
+ thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
+ sizeof(void *);
+#ifdef __SIGNAL_FRAMESIZE
+ thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
+#endif
+ return 0;
+}
+
+__initcall(init_thread_regs);
+
int copy_context_skas0(unsigned long new_stack, int pid)
{
int err;
- unsigned long regs[MAX_REG_NR];
- unsigned long fp_regs[HOST_FP_SIZE];
unsigned long current_stack = current_stub_stack();
struct stub_data *data = (struct stub_data *) current_stack;
struct stub_data *child_data = (struct stub_data *) new_stack;
@@ -344,23 +392,12 @@ int copy_context_skas0(unsigned long new_stack, int pid)
.timer = ((struct itimerval)
{ { 0, 1000000 / hz() },
{ 0, 1000000 / hz() }})});
- get_safe_registers(regs, fp_regs);
-
- /* Set parent's instruction pointer to start of clone-stub */
- regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE +
- (unsigned long) stub_clone_handler -
- (unsigned long) &__syscall_stub_start;
- regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + PAGE_SIZE -
- sizeof(void *);
-#ifdef __SIGNAL_FRAMESIZE
- regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
-#endif
- err = ptrace_setregs(pid, regs);
+ err = ptrace_setregs(pid, thread_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETREGS failed, "
"pid = %d, errno = %d\n", pid, -err);
- err = ptrace_setfpregs(pid, fp_regs);
+ err = ptrace_setfpregs(pid, thread_fp_regs);
if(err < 0)
panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
"pid = %d, errno = %d\n", pid, -err);
@@ -371,7 +408,11 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/* Wait, until parent has finished its work: read child's pid from
* parent's stack, and check, if bad result.
*/
- wait_stub_done(pid, 0, "copy_context_skas0");
+ err = ptrace(PTRACE_CONT, pid, 0, 0);
+ 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)
@@ -381,7 +422,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/* Wait, until child has finished too: read child's result from
* child's stack and check it.
*/
- wait_stub_done(pid, -1, "copy_context_skas0");
+ wait_stub_done(pid);
if (child_data->err != UML_CONFIG_STUB_DATA)
panic("copy_context_skas0 - stub-child reports error %ld\n",
child_data->err);
@@ -396,7 +437,7 @@ int copy_context_skas0(unsigned long new_stack, int pid)
/*
* This is used only, if stub pages are needed, while proc_mm is
- * availabl. Opening /proc/mm creates a new mm_context, which lacks
+ * available. Opening /proc/mm creates a new mm_context, which lacks
* the stub-pages. Thus, we map them using /proc/mm-fd
*/
void map_stub_pages(int fd, unsigned long code,
@@ -418,12 +459,13 @@ void map_stub_pages(int fd, unsigned long code,
.fd = code_fd,
.offset = code_offset
} } });
- n = os_write_file(fd, &mmop, sizeof(mmop));
+ CATCH_EINTR(n = write(fd, &mmop, 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);
panic("map_stub_pages : /proc/mm map for code failed, "
- "err = %d\n", -n);
+ "err = %d\n", n);
}
if ( stack ) {
@@ -440,18 +482,18 @@ void map_stub_pages(int fd, unsigned long code,
.fd = map_fd,
.offset = map_offset
} } });
- n = os_write_file(fd, &mmop, sizeof(mmop));
+ CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
if(n != sizeof(mmop))
panic("map_stub_pages : /proc/mm map for data failed, "
- "err = %d\n", -n);
+ "err = %d\n", errno);
}
}
void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
{
(*buf)[0].JB_IP = (unsigned long) handler;
- (*buf)[0].JB_SP = (unsigned long) stack +
- (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) - sizeof(void *);
+ (*buf)[0].JB_SP = (unsigned long) stack + UM_THREAD_SIZE -
+ sizeof(void *);
}
#define INIT_JMP_NEW_THREAD 0
@@ -480,17 +522,24 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM,
SIGVTALRM, -1);
- n = UML_SETJMP(&initial_jmpbuf);
+ /*
+ * Can't use UML_SETJMP or UML_LONGJMP here because they save
+ * and restore signals, with the possible side-effect of
+ * trying to handle any signals which came when they were
+ * blocked, which can't be done on this stack.
+ * Signals must be blocked when jumping back here and restored
+ * after returning to the jumper.
+ */
+ n = setjmp(initial_jmpbuf);
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 +
- (PAGE_SIZE << UML_CONFIG_KERNEL_STACK_ORDER) -
- sizeof(void *);
+ UM_THREAD_SIZE - sizeof(void *);
break;
case INIT_JMP_CALLBACK:
(*cb_proc)(cb_arg);
- UML_LONGJMP(cb_back, 1);
+ longjmp(*cb_back, 1);
break;
case INIT_JMP_HALT:
kmalloc_ok = 0;
@@ -501,7 +550,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
default:
panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
}
- UML_LONGJMP(switch_buf, 1);
+ longjmp(*switch_buf, 1);
}
void initial_thread_cb_skas(void (*proc)(void *), void *arg)
@@ -538,7 +587,7 @@ void switch_mm_skas(struct mm_id *mm_idp)
{
int err;
-#warning need cpu pid in switch_mm_skas
+ /* FIXME: need cpu pid in switch_mm_skas */
if(proc_mm){
err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
mm_idp->u.mm_fd);
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
index 9ad5fbec4593..3b600c2e63b8 100644
--- a/arch/um/os-Linux/skas/trap.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -5,8 +5,8 @@
#include <signal.h>
#include <errno.h>
-#include "user_util.h"
#include "kern_util.h"
+#include "as-layout.h"
#include "task.h"
#include "sigcontext.h"
#include "skas.h"
@@ -15,29 +15,39 @@
#include "sysdep/ptrace_user.h"
#include "os.h"
+static union uml_pt_regs ksig_regs[UM_NR_CPUS];
+
void sig_handler_common_skas(int sig, void *sc_ptr)
{
struct sigcontext *sc = sc_ptr;
- struct skas_regs *r;
+ union uml_pt_regs *r;
void (*handler)(int, union uml_pt_regs *);
- int save_errno = errno;
- int save_user;
+ int save_user, save_errno = errno;
/* 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
+ * 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
+ * registers are OK.
+ */
+ r = &ksig_regs[cpu()];
+ copy_sc(r, sc_ptr);
+ }
+ else r = TASK_REGS(get_current());
- r = &TASK_REGS(get_current())->skas;
- save_user = r->is_user;
- r->is_user = 0;
+ save_user = r->skas.is_user;
+ r->skas.is_user = 0;
if ( sig == SIGFPE || sig == SIGSEGV ||
sig == SIGBUS || sig == SIGILL ||
sig == SIGTRAP ) {
- GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
+ GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc);
}
change_sig(SIGUSR1, 1);
@@ -49,25 +59,8 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
sig != SIGVTALRM && sig != SIGALRM)
unblock_signals();
- handler(sig, (union uml_pt_regs *) r);
+ handler(sig, r);
errno = save_errno;
- r->is_user = save_user;
-}
-
-extern int ptrace_faultinfo;
-
-void user_signal(int sig, union uml_pt_regs *regs, int pid)
-{
- void (*handler)(int, union uml_pt_regs *);
- int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
- (sig == SIGILL) || (sig == SIGTRAP));
-
- if (segv)
- get_skas_faultinfo(pid, &regs->skas.faultinfo);
-
- handler = sig_info[sig];
- handler(sig, (union uml_pt_regs *) regs);
-
- unblock_signals();
+ r->skas.is_user = save_user;
}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 5178eba9afa5..79471f85eb89 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -17,10 +17,10 @@
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/mman.h>
+#include <sys/resource.h>
#include <asm/unistd.h>
#include <asm/page.h>
#include <sys/types.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "signal_kern.h"
@@ -329,8 +329,32 @@ static void __init check_ptrace(void)
extern void check_tmpexec(void);
-void os_early_checks(void)
+static void __init check_coredump_limit(void)
{
+ struct rlimit lim;
+ int err = getrlimit(RLIMIT_CORE, &lim);
+
+ if(err){
+ perror("Getting core dump limit");
+ return;
+ }
+
+ printf("Core dump limits :\n\tsoft - ");
+ if(lim.rlim_cur == RLIM_INFINITY)
+ printf("NONE\n");
+ else printf("%lu\n", lim.rlim_cur);
+
+ printf("\thard - ");
+ if(lim.rlim_max == RLIM_INFINITY)
+ printf("NONE\n");
+ else printf("%lu\n", lim.rlim_max);
+}
+
+void __init os_early_checks(void)
+{
+ /* Print out the core dump limits early */
+ check_coredump_limit();
+
check_ptrace();
/* Need to check this early because mmapping happens before the
@@ -528,148 +552,3 @@ int __init parse_iomem(char *str, int *add)
out:
return 1;
}
-
-
-/* Changed during early boot */
-int pty_output_sigio = 0;
-int pty_close_sigio = 0;
-
-/* Used as a flag during SIGIO testing early in boot */
-static volatile int got_sigio = 0;
-
-static void __init handler(int sig)
-{
- got_sigio = 1;
-}
-
-struct openpty_arg {
- int master;
- int slave;
- int err;
-};
-
-static void openpty_cb(void *arg)
-{
- struct openpty_arg *info = arg;
-
- info->err = 0;
- if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
- info->err = -errno;
-}
-
-static int async_pty(int master, int slave)
-{
- int flags;
-
- flags = fcntl(master, F_GETFL);
- if(flags < 0)
- return -errno;
-
- if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
- (fcntl(master, F_SETOWN, os_getpid()) < 0))
- return -errno;
-
- if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
- return -errno;
-
- return(0);
-}
-
-static void __init check_one_sigio(void (*proc)(int, int))
-{
- struct sigaction old, new;
- struct openpty_arg pty = { .master = -1, .slave = -1 };
- int master, slave, err;
-
- initial_thread_cb(openpty_cb, &pty);
- if(pty.err){
- printk("openpty failed, errno = %d\n", -pty.err);
- return;
- }
-
- master = pty.master;
- slave = pty.slave;
-
- if((master == -1) || (slave == -1)){
- printk("openpty failed to allocate a pty\n");
- return;
- }
-
- /* Not now, but complain so we now where we failed. */
- err = raw(master);
- if (err < 0)
- panic("check_sigio : __raw failed, errno = %d\n", -err);
-
- err = async_pty(master, slave);
- if(err < 0)
- panic("tty_fds : sigio_async failed, err = %d\n", -err);
-
- if(sigaction(SIGIO, NULL, &old) < 0)
- panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
- new = old;
- new.sa_handler = handler;
- if(sigaction(SIGIO, &new, NULL) < 0)
- panic("check_sigio : sigaction 2 failed, errno = %d\n", errno);
-
- got_sigio = 0;
- (*proc)(master, slave);
-
- close(master);
- close(slave);
-
- if(sigaction(SIGIO, &old, NULL) < 0)
- panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
-}
-
-static void tty_output(int master, int slave)
-{
- int n;
- char buf[512];
-
- printk("Checking that host ptys support output SIGIO...");
-
- memset(buf, 0, sizeof(buf));
-
- while(os_write_file(master, buf, sizeof(buf)) > 0) ;
- if(errno != EAGAIN)
- panic("check_sigio : write failed, errno = %d\n", errno);
- while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
-
- if(got_sigio){
- printk("Yes\n");
- pty_output_sigio = 1;
- }
- else if(n == -EAGAIN) printk("No, enabling workaround\n");
- else panic("check_sigio : read failed, err = %d\n", n);
-}
-
-static void tty_close(int master, int slave)
-{
- printk("Checking that host ptys support SIGIO on close...");
-
- close(slave);
- if(got_sigio){
- printk("Yes\n");
- pty_close_sigio = 1;
- }
- else printk("No, enabling workaround\n");
-}
-
-void __init check_sigio(void)
-{
- if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
- (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
- printk("No pseudo-terminals available - skipping pty SIGIO "
- "check\n");
- return;
- }
- check_one_sigio(tty_output);
- check_one_sigio(tty_close);
-}
-
-void os_check_bugs(void)
-{
- check_ptrace();
- check_sigio();
-}
-
diff --git a/arch/um/os-Linux/sys-i386/signal.c b/arch/um/os-Linux/sys-i386/signal.c
index 0d3eae518352..f311609f93da 100644
--- a/arch/um/os-Linux/sys-i386/signal.c
+++ b/arch/um/os-Linux/sys-i386/signal.c
@@ -1,15 +1,13 @@
/*
- * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <signal.h>
-extern void (*handlers[])(int sig, struct sigcontext *sc);
+extern void handle_signal(int sig, struct sigcontext *sc);
void hard_handler(int sig)
{
- struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
-
- (*handlers[sig])(sig, sc);
+ handle_signal(sig, (struct sigcontext *) (&sig + 1));
}
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 256532034c62..32ed41ec1a3d 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -5,7 +5,7 @@
#include <unistd.h>
#include "sysdep/tls.h"
-#include "user_util.h"
+#include "user.h"
/* Checks whether host supports TLS, and sets *tls_min according to the value
* valid on the host.
diff --git a/arch/um/os-Linux/sys-x86_64/signal.c b/arch/um/os-Linux/sys-x86_64/signal.c
index 3f369e5f976b..82a388822cd3 100644
--- a/arch/um/os-Linux/sys-x86_64/signal.c
+++ b/arch/um/os-Linux/sys-x86_64/signal.c
@@ -1,16 +1,16 @@
/*
- * Copyright (C) 2006 Jeff Dike (jdike@addtoit.com)
+ * Copyright (C) 2006 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
#include <signal.h>
-extern void (*handlers[])(int sig, struct sigcontext *sc);
+extern void handle_signal(int sig, struct sigcontext *sc);
void hard_handler(int sig)
{
struct ucontext *uc;
asm("movq %%rdx, %0" : "=r" (uc));
- (*handlers[sig])(sig, (struct sigcontext *) &uc->uc_mcontext);
+ handle_signal(sig, (struct sigcontext *) &uc->uc_mcontext);
}
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 2115b8beb541..5de169b168f6 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -10,7 +10,6 @@
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "process.h"
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index d221214d2ed5..295da657931a 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <signal.h>
#include "kern_util.h"
-#include "user_util.h"
#include "os.h"
#include "mode.h"
#include "longjmp.h"
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 3dc3a02d6263..bcf9359c4e9f 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -18,7 +18,6 @@
#include <asm/ptrace.h>
#include <asm/unistd.h>
#include <asm/page.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "signal_kern.h"
@@ -32,6 +31,7 @@
#include "choose-mode.h"
#include "mode.h"
#include "tempfile.h"
+#include "kern_constants.h"
int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
int must_succeed)
@@ -143,7 +143,7 @@ int outer_tramp(void *arg)
int sig = sigkill;
t = arg;
- t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2,
+ t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2,
t->flags, t->tramp_data);
if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
kill(os_getpid(), sig);
diff --git a/arch/um/os-Linux/tty_log.c b/arch/um/os-Linux/tty_log.c
index c6ba56c1560f..d11a55baa6bd 100644
--- a/arch/um/os-Linux/tty_log.c
+++ b/arch/um/os-Linux/tty_log.c
@@ -53,9 +53,9 @@ int open_tty_log(void *tty, void *current_tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
- os_write_file(tty_log_fd, &current_tty, data.len);
- return(tty_log_fd);
+ write(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &current_tty, data.len);
+ return tty_log_fd;
}
sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
@@ -67,7 +67,7 @@ int open_tty_log(void *tty, void *current_tty)
printk("open_tty_log : couldn't open '%s', errno = %d\n",
buf, -fd);
}
- return(fd);
+ return fd;
}
void close_tty_log(int fd, void *tty)
@@ -83,7 +83,7 @@ void close_tty_log(int fd, void *tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
return;
}
os_close_file(fd);
@@ -98,21 +98,21 @@ static int log_chunk(int fd, const char *buf, int len)
try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
missed = copy_from_user_proc(chunk, (char *) buf, try);
try -= missed;
- n = os_write_file(fd, chunk, try);
+ n = write(fd, chunk, try);
if(n != try) {
if(n < 0)
- return(n);
- return(-EIO);
+ return -errno;
+ return -EIO;
}
if(missed != 0)
- return(-EFAULT);
+ return -EFAULT;
len -= try;
total += try;
buf += try;
}
- return(total);
+ return total;
}
int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
@@ -130,10 +130,10 @@ int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
.direction = direction,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
}
- return(log_chunk(fd, buf, len));
+ return log_chunk(fd, buf, len);
}
void log_exec(char **argv, void *tty)
@@ -161,7 +161,7 @@ void log_exec(char **argv, void *tty)
.direction = 0,
.sec = tv.tv_sec,
.usec = tv.tv_usec } );
- os_write_file(tty_log_fd, &data, sizeof(data));
+ write(tty_log_fd, &data, sizeof(data));
for(ptr = argv; ; ptr++){
if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
@@ -179,7 +179,7 @@ extern void register_tty_logger(int (*opener)(void *, void *),
static int register_logger(void)
{
register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
- return(0);
+ return 0;
}
__uml_initcall(register_logger);
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 56b8a50e8bc2..7cbcf484e13d 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -21,7 +21,6 @@
#include <sched.h>
#include <termios.h>
#include <string.h>
-#include "user_util.h"
#include "kern_util.h"
#include "user.h"
#include "mem_user.h"
@@ -30,28 +29,12 @@
#include "uml-config.h"
#include "os.h"
#include "longjmp.h"
+#include "kern_constants.h"
void stack_protections(unsigned long address)
{
- int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-
- if(mprotect((void *) address, page_size(), prot) < 0)
- panic("protecting stack failed, errno = %d", errno);
-}
-
-void task_protections(unsigned long address)
-{
- unsigned long guard = address + page_size();
- unsigned long stack = guard + page_size();
- int prot = 0, pages;
-
-#ifdef notdef
- if(mprotect((void *) stack, page_size(), prot) < 0)
- panic("protecting guard page failed, errno = %d", errno);
-#endif
- pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
- prot = PROT_READ | PROT_WRITE | PROT_EXEC;
- if(mprotect((void *) stack, pages * page_size(), prot) < 0)
+ if(mprotect((void *) address, UM_THREAD_SIZE,
+ PROT_READ | PROT_WRITE | PROT_EXEC) < 0)
panic("protecting stack failed, errno = %d", errno);
}
@@ -72,7 +55,7 @@ int raw(int fd)
/* XXX tcsetattr could have applied only some changes
* (and cfmakeraw() is a set of changes) */
- return(0);
+ return 0;
}
void setup_machinename(char *machine_out)
@@ -96,15 +79,13 @@ void setup_machinename(char *machine_out)
strcpy(machine_out, host.machine);
}
-char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1];
-
-void setup_hostinfo(void)
+void setup_hostinfo(char *buf, int len)
{
struct utsname host;
uname(&host);
- sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename,
- host.release, host.version, host.machine);
+ snprintf(buf, len, "%s %s %s %s %s", host.sysname, host.nodename,
+ host.release, host.version, host.machine);
}
int setjmp_wrapper(void (*proc)(void *, void *), ...)
@@ -121,3 +102,9 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
va_end(args);
return n;
}
+
+void os_dump_core(void)
+{
+ signal(SIGSEGV, SIG_DFL);
+ abort();
+}
OpenPOWER on IntegriCloud