summaryrefslogtreecommitdiff
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig2
-rw-r--r--arch/um/Kconfig.char6
-rw-r--r--arch/um/Kconfig.i3864
-rw-r--r--arch/um/Kconfig.x86_6411
-rw-r--r--arch/um/drivers/chan_kern.c15
-rw-r--r--arch/um/drivers/chan_user.c1
-rw-r--r--arch/um/drivers/cow_sys.h2
-rw-r--r--arch/um/drivers/daemon_user.c4
-rw-r--r--arch/um/drivers/fd.c2
-rw-r--r--arch/um/drivers/hostaudio_kern.c2
-rw-r--r--arch/um/drivers/line.c6
-rw-r--r--arch/um/drivers/mcast_kern.c2
-rw-r--r--arch/um/drivers/mcast_user.c3
-rw-r--r--arch/um/drivers/mconsole_user.c2
-rw-r--r--arch/um/drivers/net_kern.c12
-rw-r--r--arch/um/drivers/net_user.c2
-rw-r--r--arch/um/drivers/pcap_user.c2
-rw-r--r--arch/um/drivers/port_user.c4
-rw-r--r--arch/um/drivers/pty.c2
-rw-r--r--arch/um/drivers/random.c122
-rw-r--r--arch/um/drivers/slip_kern.c4
-rw-r--r--arch/um/drivers/slip_user.c2
-rw-r--r--arch/um/drivers/stdio_console.c4
-rw-r--r--arch/um/drivers/tty.c2
-rw-r--r--arch/um/drivers/ubd_kern.c390
-rw-r--r--arch/um/drivers/xterm.c2
-rw-r--r--arch/um/include/as-layout.h14
-rw-r--r--arch/um/include/chan_kern.h2
-rw-r--r--arch/um/include/line.h6
-rw-r--r--arch/um/include/os.h3
-rw-r--r--arch/um/include/process.h20
-rw-r--r--arch/um/include/skas_ptrace.h13
-rw-r--r--arch/um/include/sysdep-i386/ptrace_user.h30
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h2
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace_user.h17
-rw-r--r--arch/um/include/um_malloc.h9
-rw-r--r--arch/um/kernel/dyn.lds.S7
-rw-r--r--arch/um/kernel/exitcode.c2
-rw-r--r--arch/um/kernel/init_task.c1
-rw-r--r--arch/um/kernel/ksyms.c5
-rw-r--r--arch/um/kernel/mem.c5
-rw-r--r--arch/um/kernel/process.c2
-rw-r--r--arch/um/kernel/syscall.c17
-rw-r--r--arch/um/kernel/time.c7
-rw-r--r--arch/um/kernel/um_arch.c16
-rw-r--r--arch/um/kernel/uml.lds.S7
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c4
-rw-r--r--arch/um/os-Linux/helper.c6
-rw-r--r--arch/um/os-Linux/main.c2
-rw-r--r--arch/um/os-Linux/sigio.c39
-rw-r--r--arch/um/os-Linux/signal.c1
-rw-r--r--arch/um/os-Linux/skas/process.c4
-rw-r--r--arch/um/os-Linux/start_up.c120
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c6
-rw-r--r--arch/um/os-Linux/sys-i386/task_size.c39
-rw-r--r--arch/um/os-Linux/sys-x86_64/task_size.c2
-rw-r--r--arch/um/os-Linux/time.c61
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/ksyms.c12
-rw-r--r--arch/um/sys-i386/ptrace.c30
-rw-r--r--arch/um/sys-i386/user-offsets.c2
-rw-r--r--arch/um/sys-ppc/Makefile8
-rw-r--r--arch/um/sys-x86_64/Makefile2
-rw-r--r--arch/um/sys-x86_64/ksyms.c21
-rw-r--r--arch/um/sys-x86_64/user-offsets.c1
65 files changed, 588 insertions, 569 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index dba8e05..6976812 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -259,6 +259,8 @@ if BROKEN
source "drivers/mtd/Kconfig"
endif
+source "drivers/leds/Kconfig"
+
#This is just to shut up some Kconfig warnings, so no prompt.
config INPUT
bool
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index 3a4b396..1b238eb 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -145,14 +145,14 @@ config LEGACY_PTYS
systems, it is safe to say N.
config RAW_DRIVER
- tristate "RAW driver (/dev/raw/rawN) (OBSOLETE)"
+ tristate "RAW driver (/dev/raw/rawN)"
+ depends on BLOCK
help
The raw driver permits block devices to be bound to /dev/raw/rawN.
Once bound, I/O against /dev/raw/rawN uses efficient zero-copy I/O.
See the raw(8) manpage for more details.
- The raw driver is deprecated and will be removed soon.
- Applications should simply open the device (eg /dev/hda1)
+ Applications should preferably open the device (eg /dev/hda1)
with the O_DIRECT flag.
config MAX_RAW_DEVS
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index 3cd8a04..e09edfa 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -19,10 +19,6 @@ config 64BIT
bool
default n
-config SEMAPHORE_SLEEPERS
- bool
- default y
-
config 3_LEVEL_PGTABLES
bool "Three-level pagetables (EXPERIMENTAL)"
default n
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
index 6533b34..5696e7b 100644
--- a/arch/um/Kconfig.x86_64
+++ b/arch/um/Kconfig.x86_64
@@ -1,3 +1,10 @@
+
+menu "Host processor type and features"
+
+source "arch/x86/Kconfig.cpu"
+
+endmenu
+
config UML_X86
bool
default y
@@ -11,10 +18,6 @@ config RWSEM_GENERIC_SPINLOCK
bool
default y
-config SEMAPHORE_SLEEPERS
- bool
- default y
-
config 3_LEVEL_PGTABLES
bool
default y
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index db3082b..6e51424 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -125,7 +125,7 @@ static int open_one_chan(struct chan *chan)
return 0;
}
-int open_chan(struct list_head *chans)
+static int open_chan(struct list_head *chans)
{
struct list_head *ele;
struct chan *chan;
@@ -583,19 +583,6 @@ int parse_chan_pair(char *str, struct line *line, int device,
return 0;
}
-int chan_out_fd(struct list_head *chans)
-{
- struct list_head *ele;
- struct chan *chan;
-
- list_for_each(ele, chans) {
- chan = list_entry(ele, struct chan, list);
- if (chan->primary && chan->output)
- return chan->fd;
- }
- return -1;
-}
-
void chan_interrupt(struct list_head *chans, struct delayed_work *task,
struct tty_struct *tty, int irq)
{
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 0257640..cfeb3f4 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -11,6 +11,7 @@
#include <termios.h>
#include <sys/ioctl.h>
#include "chan_user.h"
+#include "kern_constants.h"
#include "os.h"
#include "um_malloc.h"
#include "user.h"
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index ca8c9e1..f5701fd 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -8,7 +8,7 @@
static inline void *cow_malloc(int size)
{
- return kmalloc(size, UM_GFP_KERNEL);
+ return uml_kmalloc(size, UM_GFP_KERNEL);
}
static inline void cow_free(void *ptr)
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index f23c109..f8e85e0 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -34,7 +34,7 @@ static struct sockaddr_un *new_addr(void *name, int len)
{
struct sockaddr_un *sun;
- sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+ sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
if (sun == NULL) {
printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
"failed\n");
@@ -83,7 +83,7 @@ static int connect_to_switch(struct daemon_data *pri)
goto out_close;
}
- sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
+ sun = uml_kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
if (sun == NULL) {
printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
"failed\n");
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 0a2bb5b..f5a981a 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -40,7 +40,7 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts)
return NULL;
}
- data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
if (data == NULL)
return NULL;
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index ff1b22b..368219c 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -154,7 +154,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
case SNDCTL_DSP_SUBDIVIDE:
case SNDCTL_DSP_SETFRAGMENT:
if (get_user(data, (int __user *) arg))
- return EFAULT;
+ return -EFAULT;
break;
default:
break;
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 2c898c4..5047490 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -191,9 +191,9 @@ void line_flush_chars(struct tty_struct *tty)
line_flush_buffer(tty);
}
-void line_put_char(struct tty_struct *tty, unsigned char ch)
+int line_put_char(struct tty_struct *tty, unsigned char ch)
{
- line_write(tty, &ch, sizeof(ch));
+ return line_write(tty, &ch, sizeof(ch));
}
int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
@@ -304,7 +304,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
break;
if (i == ARRAY_SIZE(tty_ioctls)) {
printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
- __FUNCTION__, tty->name, cmd);
+ __func__, tty->name, cmd);
}
ret = -ENOIOCTLCMD;
break;
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index 822092f..8c4378a 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -58,7 +58,7 @@ static const struct net_kern_info mcast_kern_info = {
.write = mcast_write,
};
-int mcast_setup(char *str, char **mac_out, void *data)
+static int mcast_setup(char *str, char **mac_out, void *data)
{
struct mcast_init *init = data;
char *port_str = NULL, *ttl_str = NULL, *remain;
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 5f647d7..ee19e91 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -15,6 +15,7 @@
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
+#include "kern_constants.h"
#include "mcast.h"
#include "net_user.h"
#include "um_malloc.h"
@@ -24,7 +25,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port)
{
struct sockaddr_in *sin;
- sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
+ sin = uml_kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
if (sin == NULL) {
printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
"failed\n");
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 13af2f0..f8cf4c8 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -39,7 +39,7 @@ static struct mconsole_command commands[] = {
/* Initialized in mconsole_init, which is an initcall */
char mconsole_socket_name[256];
-int mconsole_reply_v0(struct mc_request *req, char *reply)
+static int mconsole_reply_v0(struct mc_request *req, char *reply)
{
struct iovec iov;
struct msghdr msg;
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 1e8f41a..5b4ca8d 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -116,7 +116,7 @@ static void uml_dev_close(struct work_struct *work)
dev_close(lp->dev);
}
-irqreturn_t uml_net_interrupt(int irq, void *dev_id)
+static irqreturn_t uml_net_interrupt(int irq, void *dev_id)
{
struct net_device *dev = dev_id;
struct uml_net_private *lp = dev->priv;
@@ -256,11 +256,7 @@ static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
static void uml_net_set_multicast_list(struct net_device *dev)
{
- if (dev->flags & IFF_PROMISC)
- return;
- else if (dev->mc_count)
- dev->flags |= IFF_ALLMULTI;
- else dev->flags &= ~IFF_ALLMULTI;
+ return;
}
static void uml_net_tx_timeout(struct net_device *dev)
@@ -300,7 +296,7 @@ static struct ethtool_ops uml_net_ethtool_ops = {
.get_link = ethtool_op_get_link,
};
-void uml_net_user_timer_expire(unsigned long _conn)
+static void uml_net_user_timer_expire(unsigned long _conn)
{
#ifdef undef
struct connection *conn = (struct connection *)_conn;
@@ -790,7 +786,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
}
/* uml_net_init shouldn't be called twice on two CPUs at the same time */
-struct notifier_block uml_inetaddr_notifier = {
+static struct notifier_block uml_inetaddr_notifier = {
.notifier_call = uml_inetaddr_event,
};
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index abf2653..9415dd9 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -222,7 +222,7 @@ static void change(char *dev, char *what, unsigned char *addr,
netmask[2], netmask[3]);
output_len = UM_KERN_PAGE_SIZE;
- output = kmalloc(output_len, UM_GFP_KERNEL);
+ output = uml_kmalloc(output_len, UM_GFP_KERNEL);
if (output == NULL)
printk(UM_KERN_ERR "change : failed to allocate output "
"buffer\n");
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index e980935..5f90358 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -50,7 +50,7 @@ static int pcap_open(void *data)
return -EIO;
}
- pri->compiled = kmalloc(sizeof(struct bpf_program),
+ pri->compiled = uml_kmalloc(sizeof(struct bpf_program),
UM_GFP_KERNEL);
if (pri->compiled == NULL) {
printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index addd759..b49bf56 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -47,7 +47,7 @@ static void *port_init(char *str, int device, const struct chan_opts *opts)
if (kern_data == NULL)
return NULL;
- data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
if (data == NULL)
goto err;
@@ -153,7 +153,7 @@ struct port_pre_exec_data {
int pipe_fd;
};
-void port_pre_exec(void *arg)
+static void port_pre_exec(void *arg)
{
struct port_pre_exec_data *data = arg;
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 49c79dd..1113911 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -29,7 +29,7 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
{
struct pty_chan *data;
- data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
if (data == NULL)
return NULL;
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index 71f0959..4949044 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2005 Jeff Dike <jdike@addtoit.com> */
+/* Copyright (C) 2005 - 2008 Jeff Dike <jdike@{linux.intel,addtoit}.com> */
+
/* Much of this ripped from drivers/char/hw_random.c, see there for other
* copyright.
*
@@ -8,16 +9,18 @@
#include <linux/sched.h>
#include <linux/module.h>
#include <linux/fs.h>
+#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
+#include "irq_kern.h"
#include "os.h"
/*
* core module and version information
*/
#define RNG_VERSION "1.0.0"
-#define RNG_MODULE_NAME "random"
+#define RNG_MODULE_NAME "hw_random"
#define RNG_MISCDEV_MINOR 183 /* official */
@@ -26,47 +29,67 @@
* protects against a module being loaded twice at the same time.
*/
static int random_fd = -1;
+static DECLARE_WAIT_QUEUE_HEAD(host_read_wait);
static int rng_dev_open (struct inode *inode, struct file *filp)
{
/* enforce read-only access to this chrdev */
if ((filp->f_mode & FMODE_READ) == 0)
return -EINVAL;
- if (filp->f_mode & FMODE_WRITE)
+ if ((filp->f_mode & FMODE_WRITE) != 0)
return -EINVAL;
return 0;
}
+static atomic_t host_sleep_count = ATOMIC_INIT(0);
+
static ssize_t rng_dev_read (struct file *filp, char __user *buf, size_t size,
- loff_t * offp)
+ loff_t *offp)
{
- u32 data;
- int n, ret = 0, have_data;
-
- while(size){
- n = os_read_file(random_fd, &data, sizeof(data));
- if(n > 0){
- have_data = n;
- while (have_data && size) {
- if (put_user((u8)data, buf++)) {
- ret = ret ? : -EFAULT;
- break;
- }
- size--;
- ret++;
- have_data--;
- data>>=8;
- }
- }
- else if(n == -EAGAIN){
- if (filp->f_flags & O_NONBLOCK)
- return ret ? : -EAGAIN;
-
- if(need_resched())
- schedule_timeout_interruptible(1);
- }
- else return n;
+ u32 data;
+ int n, ret = 0, have_data;
+
+ while (size) {
+ n = os_read_file(random_fd, &data, sizeof(data));
+ if (n > 0) {
+ have_data = n;
+ while (have_data && size) {
+ if (put_user((u8) data, buf++)) {
+ ret = ret ? : -EFAULT;
+ break;
+ }
+ size--;
+ ret++;
+ have_data--;
+ data >>= 8;
+ }
+ }
+ else if (n == -EAGAIN) {
+ DECLARE_WAITQUEUE(wait, current);
+
+ if (filp->f_flags & O_NONBLOCK)
+ return ret ? : -EAGAIN;
+
+ atomic_inc(&host_sleep_count);
+ reactivate_fd(random_fd, RANDOM_IRQ);
+ add_sigio_fd(random_fd);
+
+ add_wait_queue(&host_read_wait, &wait);
+ set_task_state(current, TASK_INTERRUPTIBLE);
+
+ schedule();
+ set_task_state(current, TASK_RUNNING);
+ remove_wait_queue(&host_read_wait, &wait);
+
+ if (atomic_dec_and_test(&host_sleep_count)) {
+ ignore_sigio_fd(random_fd);
+ deactivate_fd(random_fd, RANDOM_IRQ);
+ }
+ }
+ else
+ return n;
+
if (signal_pending (current))
return ret ? : -ERESTARTSYS;
}
@@ -86,6 +109,13 @@ static struct miscdevice rng_miscdev = {
&rng_chrdev_ops,
};
+static irqreturn_t random_interrupt(int irq, void *data)
+{
+ wake_up(&host_read_wait);
+
+ return IRQ_HANDLED;
+}
+
/*
* rng_init - initialize RNG module
*/
@@ -93,28 +123,33 @@ static int __init rng_init (void)
{
int err;
- err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
- if(err < 0)
- goto out;
+ err = os_open_file("/dev/random", of_read(OPENFLAGS()), 0);
+ if (err < 0)
+ goto out;
- random_fd = err;
+ random_fd = err;
- err = os_set_fd_block(random_fd, 0);
- if(err)
+ err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
+ IRQF_DISABLED | IRQF_SAMPLE_RANDOM, "random",
+ NULL);
+ if (err)
goto err_out_cleanup_hw;
+ sigio_broken(random_fd, 1);
+
err = misc_register (&rng_miscdev);
if (err) {
- printk (KERN_ERR RNG_MODULE_NAME ": misc device register failed\n");
+ printk (KERN_ERR RNG_MODULE_NAME ": misc device register "
+ "failed\n");
goto err_out_cleanup_hw;
}
+out:
+ return err;
- out:
- return err;
-
- err_out_cleanup_hw:
- random_fd = -1;
- goto out;
+err_out_cleanup_hw:
+ os_close_file(random_fd);
+ random_fd = -1;
+ goto out;
}
/*
@@ -122,6 +157,7 @@ static int __init rng_init (void)
*/
static void __exit rng_cleanup (void)
{
+ os_close_file(random_fd);
misc_deregister (&rng_miscdev);
}
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 6b4a0f9..d19faec 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -13,7 +13,7 @@ struct slip_init {
char *gate_addr;
};
-void slip_init(struct net_device *dev, void *data)
+static void slip_init(struct net_device *dev, void *data)
{
struct uml_net_private *private;
struct slip_data *spri;
@@ -57,7 +57,7 @@ static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
(struct slip_data *) &lp->user);
}
-const struct net_kern_info slip_kern_info = {
+static const struct net_kern_info slip_kern_info = {
.init = slip_init,
.protocol = slip_protocol,
.read = slip_read,
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 8b80505..a1c2d2c 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -96,7 +96,7 @@ static int slip_tramp(char **argv, int fd)
pid = err;
output_len = UM_KERN_PAGE_SIZE;
- output = kmalloc(output_len, UM_GFP_KERNEL);
+ output = uml_kmalloc(output_len, UM_GFP_KERNEL);
if (output == NULL) {
printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
"buffer\n");
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index cec0c33..49266f6 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -34,7 +34,7 @@
static struct tty_driver *console_driver;
-void stdio_announce(char *dev_name, int dev)
+static void stdio_announce(char *dev_name, int dev)
{
printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev,
dev_name);
@@ -158,7 +158,7 @@ static struct console stdiocons = {
.index = -1,
};
-int stdio_init(void)
+static int stdio_init(void)
{
char *new_title;
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index c930fed..495858a 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -29,7 +29,7 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
}
str++;
- data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
if (data == NULL)
return NULL;
*data = ((struct tty_chan) { .dev = str,
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index be3a279..b58fb89 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -49,7 +49,6 @@
#include "irq_user.h"
#include "irq_kern.h"
#include "ubd_user.h"
-#include "kern_util.h"
#include "os.h"
#include "mem.h"
#include "mem_kern.h"
@@ -72,18 +71,6 @@ struct io_thread_req {
int error;
};
-extern int open_ubd_file(char *file, struct openflags *openflags, int shared,
- char **backing_file_out, int *bitmap_offset_out,
- unsigned long *bitmap_len_out, int *data_offset_out,
- int *create_cow_out);
-extern int create_cow_file(char *cow_file, char *backing_file,
- struct openflags flags, int sectorsize,
- int alignment, int *bitmap_offset_out,
- unsigned long *bitmap_len_out,
- int *data_offset_out);
-extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
-extern void do_io(struct io_thread_req *req);
-
static inline int ubd_test_bit(__u64 bit, unsigned char *data)
{
__u64 n;
@@ -200,7 +187,7 @@ struct ubd {
}
/* Protected by ubd_lock */
-struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
+static struct ubd ubd_devs[MAX_DEV] = { [0 ... MAX_DEV - 1] = DEFAULT_UBD };
/* Only changed by fake_ide_setup which is a setup */
static int fake_ide = 0;
@@ -463,7 +450,7 @@ __uml_help(udb_setup,
static void do_ubd_request(struct request_queue * q);
/* Only changed by ubd_init, which is an initcall. */
-int thread_fd = -1;
+static int thread_fd = -1;
static void ubd_end_request(struct request *req, int bytes, int error)
{
@@ -531,7 +518,7 @@ static irqreturn_t ubd_intr(int irq, void *dev)
/* Only changed by ubd_init, which is an initcall. */
static int io_pid = -1;
-void kill_io_thread(void)
+static void kill_io_thread(void)
{
if(io_pid != -1)
os_kill_process(io_pid, 1);
@@ -547,6 +534,192 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
return os_file_size(file, size_out);
}
+static int read_cow_bitmap(int fd, void *buf, int offset, int len)
+{
+ int err;
+
+ err = os_seek_file(fd, offset);
+ if (err < 0)
+ return err;
+
+ err = os_read_file(fd, buf, len);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
+{
+ unsigned long modtime;
+ unsigned long long actual;
+ int err;
+
+ err = os_file_modtime(file, &modtime);
+ if (err < 0) {
+ printk(KERN_ERR "Failed to get modification time of backing "
+ "file \"%s\", err = %d\n", file, -err);
+ return err;
+ }
+
+ err = os_file_size(file, &actual);
+ if (err < 0) {
+ printk(KERN_ERR "Failed to get size of backing file \"%s\", "
+ "err = %d\n", file, -err);
+ return err;
+ }
+
+ if (actual != size) {
+ /*__u64 can be a long on AMD64 and with %lu GCC complains; so
+ * the typecast.*/
+ printk(KERN_ERR "Size mismatch (%llu vs %llu) of COW header "
+ "vs backing file\n", (unsigned long long) size, actual);
+ return -EINVAL;
+ }
+ if (modtime != mtime) {
+ printk(KERN_ERR "mtime mismatch (%ld vs %ld) of COW header vs "
+ "backing file\n", mtime, modtime);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
+{
+ struct uml_stat buf1, buf2;
+ int err;
+
+ if (from_cmdline == NULL)
+ return 0;
+ if (!strcmp(from_cmdline, from_cow))
+ return 0;
+
+ err = os_stat_file(from_cmdline, &buf1);
+ if (err < 0) {
+ printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cmdline,
+ -err);
+ return 0;
+ }
+ err = os_stat_file(from_cow, &buf2);
+ if (err < 0) {
+ printk(KERN_ERR "Couldn't stat '%s', err = %d\n", from_cow,
+ -err);
+ return 1;
+ }
+ if ((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
+ return 0;
+
+ printk(KERN_ERR "Backing file mismatch - \"%s\" requested, "
+ "\"%s\" specified in COW header of \"%s\"\n",
+ from_cmdline, from_cow, cow);
+ return 1;
+}
+
+static int open_ubd_file(char *file, struct openflags *openflags, int shared,
+ char **backing_file_out, int *bitmap_offset_out,
+ unsigned long *bitmap_len_out, int *data_offset_out,
+ int *create_cow_out)
+{
+ time_t mtime;
+ unsigned long long size;
+ __u32 version, align;
+ char *backing_file;
+ int fd, err, sectorsize, asked_switch, mode = 0644;
+
+ fd = os_open_file(file, *openflags, mode);
+ if (fd < 0) {
+ if ((fd == -ENOENT) && (create_cow_out != NULL))
+ *create_cow_out = 1;
+ if (!openflags->w ||
+ ((fd != -EROFS) && (fd != -EACCES)))
+ return fd;
+ openflags->w = 0;
+ fd = os_open_file(file, *openflags, mode);
+ if (fd < 0)
+ return fd;
+ }
+
+ if (shared)
+ printk(KERN_INFO "Not locking \"%s\" on the host\n", file);
+ else {
+ err = os_lock_file(fd, openflags->w);
+ if (err < 0) {
+ printk(KERN_ERR "Failed to lock '%s', err = %d\n",
+ file, -err);
+ goto out_close;
+ }
+ }
+
+ /* Successful return case! */
+ if (backing_file_out == NULL)
+ return fd;
+
+ err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
+ &size, &sectorsize, &align, bitmap_offset_out);
+ if (err && (*backing_file_out != NULL)) {
+ printk(KERN_ERR "Failed to read COW header from COW file "
+ "\"%s\", errno = %d\n", file, -err);
+ goto out_close;
+ }
+ if (err)
+ return fd;
+
+ asked_switch = path_requires_switch(*backing_file_out, backing_file,
+ file);
+
+ /* Allow switching only if no mismatch. */
+ if (asked_switch && !backing_file_mismatch(*backing_file_out, size,
+ mtime)) {
+ printk(KERN_ERR "Switching backing file to '%s'\n",
+ *backing_file_out);
+ err = write_cow_header(file, fd, *backing_file_out,
+ sectorsize, align, &size);
+ if (err) {
+ printk(KERN_ERR "Switch failed, errno = %d\n", -err);
+ goto out_close;
+ }
+ } else {
+ *backing_file_out = backing_file;
+ err = backing_file_mismatch(*backing_file_out, size, mtime);
+ if (err)
+ goto out_close;
+ }
+
+ cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
+ bitmap_len_out, data_offset_out);
+
+ return fd;
+ out_close:
+ os_close_file(fd);
+ return err;
+}
+
+static int create_cow_file(char *cow_file, char *backing_file,
+ struct openflags flags,
+ int sectorsize, int alignment, int *bitmap_offset_out,
+ unsigned long *bitmap_len_out, int *data_offset_out)
+{
+ int err, fd;
+
+ flags.c = 1;
+ fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
+ if (fd < 0) {
+ err = fd;
+ printk(KERN_ERR "Open of COW file '%s' failed, errno = %d\n",
+ cow_file, -err);
+ goto out;
+ }
+
+ err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
+ bitmap_offset_out, bitmap_len_out,
+ data_offset_out);
+ if (!err)
+ return fd;
+ os_close_file(fd);
+ out:
+ return err;
+}
+
static void ubd_close_dev(struct ubd *ubd_dev)
{
os_close_file(ubd_dev->fd);
@@ -1004,8 +1177,8 @@ static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask,
* by one word. Thanks to Lynn Kerby for the fix and James McMechan
* for the original diagnosis.
*/
- if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) /
- sizeof(unsigned long) - 1))
+ if (*cow_offset == (DIV_ROUND_UP(bitmap_len,
+ sizeof(unsigned long)) - 1))
(*cow_offset)--;
bitmap_words[0] = bitmap[*cow_offset];
@@ -1166,185 +1339,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
return -EINVAL;
}
-static int path_requires_switch(char *from_cmdline, char *from_cow, char *cow)
-{
- struct uml_stat buf1, buf2;
- int err;
-
- if(from_cmdline == NULL)
- return 0;
- if(!strcmp(from_cmdline, from_cow))
- return 0;
-
- err = os_stat_file(from_cmdline, &buf1);
- if(err < 0){
- printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
- return 0;
- }
- err = os_stat_file(from_cow, &buf2);
- if(err < 0){
- printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
- return 1;
- }
- if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
- return 0;
-
- printk("Backing file mismatch - \"%s\" requested,\n"
- "\"%s\" specified in COW header of \"%s\"\n",
- from_cmdline, from_cow, cow);
- return 1;
-}
-
-static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
-{
- unsigned long modtime;
- unsigned long long actual;
- int err;
-
- err = os_file_modtime(file, &modtime);
- if(err < 0){
- printk("Failed to get modification time of backing file "
- "\"%s\", err = %d\n", file, -err);
- return err;
- }
-
- err = os_file_size(file, &actual);
- if(err < 0){
- printk("Failed to get size of backing file \"%s\", "
- "err = %d\n", file, -err);
- return err;
- }
-
- if(actual != size){
- /*__u64 can be a long on AMD64 and with %lu GCC complains; so
- * the typecast.*/
- printk("Size mismatch (%llu vs %llu) of COW header vs backing "
- "file\n", (unsigned long long) size, actual);
- return -EINVAL;
- }
- if(modtime != mtime){
- printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
- "file\n", mtime, modtime);
- return -EINVAL;
- }
- return 0;
-}
-
-int read_cow_bitmap(int fd, void *buf, int offset, int len)
-{
- int err;
-
- err = os_seek_file(fd, offset);
- if(err < 0)
- return err;
-
- err = os_read_file(fd, buf, len);
- if(err < 0)
- return err;
-
- return 0;
-}
-
-int open_ubd_file(char *file, struct openflags *openflags, int shared,
- char **backing_file_out, int *bitmap_offset_out,
- unsigned long *bitmap_len_out, int *data_offset_out,
- int *create_cow_out)
-{
- time_t mtime;
- unsigned long long size;
- __u32 version, align;
- char *backing_file;
- int fd, err, sectorsize, asked_switch, mode = 0644;
-
- fd = os_open_file(file, *openflags, mode);
- if (fd < 0) {
- if ((fd == -ENOENT) && (create_cow_out != NULL))
- *create_cow_out = 1;
- if (!openflags->w ||
- ((fd != -EROFS) && (fd != -EACCES)))
- return fd;
- openflags->w = 0;
- fd = os_open_file(file, *openflags, mode);
- if (fd < 0)
- return fd;
- }
-
- if(shared)
- printk("Not locking \"%s\" on the host\n", file);
- else {
- err = os_lock_file(fd, openflags->w);
- if(err < 0){
- printk("Failed to lock '%s', err = %d\n", file, -err);
- goto out_close;
- }
- }
-
- /* Successful return case! */
- if(backing_file_out == NULL)
- return fd;
-
- err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
- &size, &sectorsize, &align, bitmap_offset_out);
- if(err && (*backing_file_out != NULL)){
- printk("Failed to read COW header from COW file \"%s\", "
- "errno = %d\n", file, -err);
- goto out_close;
- }
- if(err)
- return fd;
-
- asked_switch = path_requires_switch(*backing_file_out, backing_file, file);
-
- /* Allow switching only if no mismatch. */
- if (asked_switch && !backing_file_mismatch(*backing_file_out, size, mtime)) {
- printk("Switching backing file to '%s'\n", *backing_file_out);
- err = write_cow_header(file, fd, *backing_file_out,
- sectorsize, align, &size);
- if (err) {
- printk("Switch failed, errno = %d\n", -err);
- goto out_close;
- }
- } else {
- *backing_file_out = backing_file;
- err = backing_file_mismatch(*backing_file_out, size, mtime);
- if (err)
- goto out_close;
- }
-
- cow_sizes(version, size, sectorsize, align, *bitmap_offset_out,
- bitmap_len_out, data_offset_out);
-
- return fd;
- out_close:
- os_close_file(fd);
- return err;
-}
-
-int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
- int sectorsize, int alignment, int *bitmap_offset_out,
- unsigned long *bitmap_len_out, int *data_offset_out)
-{
- int err, fd;
-
- flags.c = 1;
- fd = open_ubd_file(cow_file, &flags, 0, NULL, NULL, NULL, NULL, NULL);
- if(fd < 0){
- err = fd;
- printk("Open of COW file '%s' failed, errno = %d\n", cow_file,
- -err);
- goto out;
- }
-
- err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
- bitmap_offset_out, bitmap_len_out,
- data_offset_out);
- if(!err)
- return fd;
- os_close_file(fd);
- out:
- return err;
-}
-
static int update_bitmap(struct io_thread_req *req)
{
int n;
@@ -1369,7 +1363,7 @@ static int update_bitmap(struct io_thread_req *req)
return 0;
}
-void do_io(struct io_thread_req *req)
+static void do_io(struct io_thread_req *req)
{
char *buf;
unsigned long len;
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 8a1c18a..da2caa5 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -30,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts)
{
struct xterm_chan *data;
- data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
+ data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
if (data == NULL)
return NULL;
*data = ((struct xterm_chan) { .pid = -1,
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
index cac542d..58e852d 100644
--- a/arch/um/include/as-layout.h
+++ b/arch/um/include/as-layout.h
@@ -23,16 +23,16 @@
*/
#ifdef __ASSEMBLY__
-#define _AC(X, Y) (Y)
+#define _UML_AC(X, Y) (Y)
#else
-#define __AC(X, Y) (X (Y))
-#define _AC(X, Y) __AC(X, Y)
+#define __UML_AC(X, Y) (X(Y))
+#define _UML_AC(X, Y) __UML_AC(X, Y)
#endif
-#define STUB_START _AC(, 0x100000)
-#define STUB_CODE _AC((unsigned long), STUB_START)
-#define STUB_DATA _AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
-#define STUB_END _AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
+#define STUB_START _UML_AC(, 0x100000)
+#define STUB_CODE _UML_AC((unsigned long), STUB_START)
+#define STUB_DATA _UML_AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
+#define STUB_END _UML_AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
#ifndef __ASSEMBLY__
diff --git a/arch/um/include/chan_kern.h b/arch/um/include/chan_kern.h
index 624b510..1e65145 100644
--- a/arch/um/include/chan_kern.h
+++ b/arch/um/include/chan_kern.h
@@ -31,7 +31,6 @@ extern void chan_interrupt(struct list_head *chans, struct delayed_work *task,
struct tty_struct *tty, int irq);
extern int parse_chan_pair(char *str, struct line *line, int device,
const struct chan_opts *opts, char **error_out);
-extern int open_chan(struct list_head *chans);
extern int write_chan(struct list_head *chans, const char *buf, int len,
int write_irq);
extern int console_write_chan(struct list_head *chans, const char *buf,
@@ -45,7 +44,6 @@ extern void close_chan(struct list_head *chans, int delay_free_irq);
extern int chan_window_size(struct list_head *chans,
unsigned short *rows_out,
unsigned short *cols_out);
-extern int chan_out_fd(struct list_head *chans);
extern int chan_config_string(struct list_head *chans, char *str, int size,
char **error_out);
diff --git a/arch/um/include/line.h b/arch/um/include/line.h
index 1223f2c..311a0d3 100644
--- a/arch/um/include/line.h
+++ b/arch/um/include/line.h
@@ -58,11 +58,11 @@ struct line {
};
#define LINE_INIT(str, d) \
- { .count_lock = SPIN_LOCK_UNLOCKED, \
+ { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \
.init_str = str, \
.init_pri = INIT_STATIC, \
.valid = 1, \
- .lock = SPIN_LOCK_UNLOCKED, \
+ .lock = __SPIN_LOCK_UNLOCKED((str).lock), \
.driver = d }
extern void line_close(struct tty_struct *tty, struct file * filp);
@@ -71,7 +71,7 @@ extern int line_setup(struct line *lines, unsigned int sizeof_lines,
char *init, char **error_out);
extern int line_write(struct tty_struct *tty, const unsigned char *buf,
int len);
-extern void line_put_char(struct tty_struct *tty, unsigned char ch);
+extern int line_put_char(struct tty_struct *tty, unsigned char ch);
extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
extern int line_chars_in_buffer(struct tty_struct *tty);
extern void line_flush_buffer(struct tty_struct *tty);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 32c799e..db5be46 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -290,6 +290,7 @@ extern void os_set_ioignore(void);
extern int add_sigio_fd(int fd);
extern int ignore_sigio_fd(int fd);
extern void maybe_sigio_broken(int fd, int read);
+extern void sigio_broken(int fd, int read);
/* sys-x86_64/prctl.c */
extern int os_arch_prctl(int pid, int code, unsigned long *addr);
@@ -298,6 +299,6 @@ extern int os_arch_prctl(int pid, int code, unsigned long *addr);
extern int get_pty(void);
/* sys-$ARCH/task_size.c */
-extern unsigned long os_get_task_size(void);
+extern unsigned long os_get_top_address(void);
#endif
diff --git a/arch/um/include/process.h b/arch/um/include/process.h
index 5af9157..bb873a5 100644
--- a/arch/um/include/process.h
+++ b/arch/um/include/process.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -8,18 +8,10 @@
#include <signal.h>
-extern void sig_handler(int sig, struct sigcontext sc);
-extern void alarm_handler(int sig, struct sigcontext sc);
+/* Copied from linux/compiler-gcc.h since we can't include it directly */
+#define barrier() __asm__ __volatile__("": : :"memory")
-#endif
+extern void sig_handler(int sig, struct sigcontext *sc);
+extern void alarm_handler(int sig, struct sigcontext *sc);
-/*
- * 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:
- */
+#endif
diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
index cd2327d..3d31bba 100644
--- a/arch/um/include/skas_ptrace.h
+++ b/arch/um/include/skas_ptrace.h
@@ -1,5 +1,5 @@
/*
- * 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
*/
@@ -12,14 +12,3 @@
#include "sysdep/skas_ptrace.h"
#endif
-
-/*
- * 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/include/sysdep-i386/ptrace_user.h b/arch/um/include/sysdep-i386/ptrace_user.h
index 7565072..ef56247 100644
--- a/arch/um/include/sysdep-i386/ptrace_user.h
+++ b/arch/um/include/sysdep-i386/ptrace_user.h
@@ -41,38 +41,10 @@
#define PT_SP_OFFSET PT_OFFSET(UESP)
#define PT_SP(regs) ((regs)[UESP])
-#define FP_SIZE ((HOST_XFP_SIZE > HOST_FP_SIZE) ? HOST_XFP_SIZE : HOST_FP_SIZE)
+#define FP_SIZE ((HOST_FPX_SIZE > HOST_FP_SIZE) ? HOST_FPX_SIZE : HOST_FP_SIZE)
#ifndef FRAME_SIZE
#define FRAME_SIZE (17)
#endif
-#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long))
-
-#define FP_FRAME_SIZE (27)
-#define FPX_FRAME_SIZE (128)
-
-#ifdef PTRACE_GETREGS
-#define UM_HAVE_GETREGS
-#endif
-
-#ifdef PTRACE_SETREGS
-#define UM_HAVE_SETREGS
-#endif
-
-#ifdef PTRACE_GETFPREGS
-#define UM_HAVE_GETFPREGS
-#endif
-
-#ifdef PTRACE_SETFPREGS
-#define UM_HAVE_SETFPREGS
-#endif
-
-#ifdef PTRACE_GETFPXREGS
-#define UM_HAVE_GETFPXREGS
-#endif
-
-#ifdef PTRACE_SETFPXREGS
-#define UM_HAVE_SETFPXREGS
-#endif
#endif
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index 67e7712..f583c87 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -10,7 +10,7 @@
#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
-#define GET_FAULTINFO_FROM_SC(fi,sc) \
+#define GET_FAULTINFO_FROM_SC(fi, sc) \
{ \
(fi).cr2 = SC_CR2(sc); \
(fi).error_code = SC_ERR(sc); \
diff --git a/arch/um/include/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
index 45c0bd8..4dbccdb 100644
--- a/arch/um/include/sysdep-x86_64/ptrace_user.h
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -48,7 +48,8 @@
#define PT_ORIG_RAX_OFFSET (ORIG_RAX)
#define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)])
-/* x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
+/*
+ * x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
* it's defined in the kernel's include/linux/ptrace.h. Additionally, use the
* 2.4 name and value for 2.4 host compatibility.
*/
@@ -56,7 +57,8 @@
#define PTRACE_OLDSETOPTIONS 21
#endif
-/* These are before the system call, so the system call number is RAX
+/*
+ * These are before the system call, so the system call number is RAX
* rather than ORIG_RAX, and arg4 is R10 rather than RCX
*/
#define REGS_SYSCALL_NR PT_INDEX(RAX)
@@ -73,14 +75,3 @@
#define FP_SIZE (HOST_FP_SIZE)
#endif
-
-/*
- * 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/include/um_malloc.h b/arch/um/include/um_malloc.h
index 0ad17cb..c554d70 100644
--- a/arch/um/include/um_malloc.h
+++ b/arch/um/include/um_malloc.h
@@ -8,15 +8,12 @@
#include "kern_constants.h"
-extern void *__kmalloc(int size, int flags);
-static inline void *kmalloc(int size, int flags)
-{
- return __kmalloc(size, flags);
-}
-
+extern void *uml_kmalloc(int size, int flags);
extern void kfree(const void *ptr);
extern void *vmalloc(unsigned long size);
extern void vfree(void *ptr);
#endif /* __UM_MALLOC_H__ */
+
+
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 26090b7..9975e1a 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -1,4 +1,5 @@
#include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
OUTPUT_FORMAT(ELF_FORMAT)
OUTPUT_ARCH(ELF_ARCH)
@@ -21,7 +22,7 @@ SECTIONS
_einittext = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
/* Read-only sections, merged into text segment: */
.hash : { *(.hash) }
@@ -68,9 +69,9 @@ SECTIONS
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
} =0x90909090
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.syscall_stub : {
__syscall_stub_start = .;
*(.__syscall_stub*)
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index 984f80e..6540d2c 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -59,7 +59,7 @@ static int make_proc_exitcode(void)
{
struct proc_dir_entry *ent;
- ent = create_proc_entry("exitcode", 0600, &proc_root);
+ ent = create_proc_entry("exitcode", 0600, NULL);
if (ent == NULL) {
printk(KERN_WARNING "make_proc_exitcode : Failed to register "
"/proc/exitcode\n");
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index dcfceca..910eda8 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -12,7 +12,6 @@
static struct fs_struct init_fs = INIT_FS;
struct mm_struct init_mm = INIT_MM(init_mm);
-static struct files_struct init_files = INIT_FILES;
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
EXPORT_SYMBOL(init_mm);
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 66e2a30..ccc02a6 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -60,6 +60,11 @@ EXPORT_SYMBOL(os_rcv_fd);
EXPORT_SYMBOL(run_helper);
EXPORT_SYMBOL(start_thread);
+EXPORT_SYMBOL(add_sigio_fd);
+EXPORT_SYMBOL(ignore_sigio_fd);
+EXPORT_SYMBOL(deactivate_fd);
+EXPORT_SYMBOL(sigio_broken);
+
#ifdef CONFIG_SMP
/* required for SMP */
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 2eea1ff..b0ee646 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -375,3 +375,8 @@ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
return pmd;
}
#endif
+
+void *uml_kmalloc(int size, int flags)
+{
+ return kmalloc(size, flags);
+}
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index e8cb9ff..83603cf 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -364,7 +364,7 @@ int __init make_proc_sysemu(void)
if (!sysemu_supported)
return 0;
- ent = create_proc_entry("sysemu", 0600, &proc_root);
+ ent = create_proc_entry("sysemu", 0600, NULL);
if (ent == NULL)
{
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 9cffc62..128ee85 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -73,23 +73,6 @@ long old_mmap(unsigned long addr, unsigned long len,
out:
return err;
}
-/*
- * sys_pipe() is the normal C calling standard for creating
- * a pipe. It's not the way unix traditionally does this, though.
- */
-long sys_pipe(unsigned long __user * fildes)
-{
- int fd[2];
- long error;
-
- error = do_pipe(fd);
- if (!error) {
- if (copy_to_user(fildes, fd, sizeof(fd)))
- error = -EFAULT;
- }
- return error;
-}
-
long sys_uname(struct old_utsname __user * name)
{
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index e066e84..c3e2f36 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -4,6 +4,7 @@
*/
#include <linux/clockchips.h>
+#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/jiffies.h>
#include <linux/threads.h>
@@ -74,7 +75,7 @@ static irqreturn_t um_timer(int irq, void *dev)
static cycle_t itimer_read(void)
{
- return os_nsecs();
+ return os_nsecs() / 1000;
}
static struct clocksource itimer_clocksource = {
@@ -82,7 +83,7 @@ static struct clocksource itimer_clocksource = {
.rating = 300,
.read = itimer_read,
.mask = CLOCKSOURCE_MASK(64),
- .mult = 1,
+ .mult = 1000,
.shift = 0,
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
@@ -109,8 +110,6 @@ static void __init setup_itimer(void)
clockevents_register_device(&itimer_clockevent);
}
-extern void (*late_time_init)(void);
-
void __init time_init(void)
{
long long nsecs;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index a6c1dd1..8d84250 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -115,7 +115,7 @@ static int have_root __initdata = 0;
/* Set in uml_mem_setup and modified in linux_main */
long long physmem_size = 32 * 1024 * 1024;
-static char *usage_string =
+static const char *usage_string =
"User Mode Linux v%s\n"
" available at http://user-mode-linux.sourceforge.net/\n\n";
@@ -150,7 +150,7 @@ __uml_setup("root=", uml_root_setup,
static int __init no_skas_debug_setup(char *line, int *add)
{
printf("'debug' is not necessary to gdb UML in skas mode - run \n");
- printf("'gdb linux'");
+ printf("'gdb linux'\n");
return 0;
}
@@ -202,7 +202,7 @@ static void __init uml_checksetup(char *line, int *add)
p = &__uml_setup_start;
while (p < &__uml_setup_end) {
- int n;
+ size_t n;
n = strlen(p->str);
if (!strncmp(line, p->str, n) && p->setup_func(line + n, add))
@@ -258,7 +258,9 @@ int __init linux_main(int argc, char **argv)
{
unsigned long avail, diff;
unsigned long virtmem_size, max_physmem;
- unsigned int i, add;
+ unsigned long stack;
+ unsigned int i;
+ int add;
char * mode;
for (i = 1; i < argc; i++) {
@@ -272,7 +274,7 @@ int __init linux_main(int argc, char **argv)
if (have_root == 0)
add_arg(DEFAULT_COMMAND_LINE);
- host_task_size = os_get_task_size();
+ host_task_size = os_get_top_address();
/*
* TASK_SIZE needs to be PGDIR_SIZE aligned or else exit_mmap craps
* out
@@ -347,7 +349,9 @@ int __init linux_main(int argc, char **argv)
}
virtmem_size = physmem_size;
- avail = TASK_SIZE - start_vm;
+ stack = (unsigned long) argv;
+ stack &= ~(1024 * 1024 - 1);
+ avail = stack - start_vm;
if (physmem_size > avail)
virtmem_size = avail;
end_vm = start_vm + virtmem_size;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 5828c1d..11b8352 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -1,4 +1,5 @@
#include <asm-generic/vmlinux.lds.h>
+#include <asm/page.h>
OUTPUT_FORMAT(ELF_FORMAT)
OUTPUT_ARCH(ELF_ARCH)
@@ -26,7 +27,7 @@ SECTIONS
INIT_TEXT
_einittext = .;
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.text :
{
@@ -39,7 +40,7 @@ SECTIONS
*(.gnu.linkonce.t*)
}
- . = ALIGN(4096);
+ . = ALIGN(PAGE_SIZE);
.syscall_stub : {
__syscall_stub_start = .;
*(.__syscall_stub*)
@@ -79,7 +80,7 @@ SECTIONS
.sdata : { *(.sdata) }
_edata = .;
PROVIDE (edata = .);
- . = ALIGN(0x1000);
+ . = ALIGN(PAGE_SIZE);
.sbss :
{
__bss_start = .;
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 6fb0b17..cc72cb2 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -52,7 +52,7 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
return;
}
- output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
+ output = uml_kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
if (output == NULL)
printk(UM_KERN_ERR "etap_change : Failed to allocate output "
"buffer\n");
@@ -165,7 +165,7 @@ static int etap_open(void *data)
err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
control_fds[1], data_fds[0], data_fds[1]);
output_len = UM_KERN_PAGE_SIZE;
- output = kmalloc(output_len, UM_GFP_KERNEL);
+ output = uml_kmalloc(output_len, UM_GFP_KERNEL);
read_output(control_fds[0], output, output_len);
if (output == NULL)
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index f4bd349..30860b8 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -7,6 +7,7 @@
#include <unistd.h>
#include <errno.h>
#include <sched.h>
+#include <linux/limits.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include "kern_constants.h"
@@ -14,6 +15,7 @@
#include "os.h"
#include "um_malloc.h"
#include "user.h"
+#include <linux/limits.h>
struct helper_data {
void (*pre_exec)(void*);
@@ -70,8 +72,8 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
data.pre_data = pre_data;
data.argv = argv;
data.fd = fds[1];
- data.buf = __cant_sleep() ? kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
- kmalloc(PATH_MAX, UM_GFP_KERNEL);
+ data.buf = __cant_sleep() ? uml_kmalloc(PATH_MAX, UM_GFP_ATOMIC) :
+ uml_kmalloc(PATH_MAX, UM_GFP_KERNEL);
pid = clone(helper_child, (void *) sp, CLONE_VM, &data);
if (pid < 0) {
ret = -errno;
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index abb9b0f..eee69b9 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -199,7 +199,7 @@ void *__wrap_malloc(int size)
return __real_malloc(size);
else if (size <= UM_KERN_PAGE_SIZE)
/* finding contiguous pages can be hard*/
- ret = kmalloc(size, UM_GFP_KERNEL);
+ ret = uml_kmalloc(size, UM_GFP_KERNEL);
else ret = vmalloc(size);
/*
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index abf47a7c..eb8f2e4 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
* Licensed under the GPL
*/
@@ -15,6 +15,7 @@
#include "kern_util.h"
#include "init.h"
#include "os.h"
+#include "process.h"
#include "sigio.h"
#include "um_malloc.h"
#include "user.h"
@@ -109,7 +110,7 @@ static int need_poll(struct pollfds *polls, int n)
if (n <= polls->size)
return 0;
- new = kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
+ new = uml_kmalloc(n * sizeof(struct pollfd), UM_GFP_ATOMIC);
if (new == NULL) {
printk(UM_KERN_ERR "need_poll : failed to allocate new "
"pollfds\n");
@@ -243,7 +244,7 @@ static struct pollfd *setup_initial_poll(int fd)
{
struct pollfd *p;
- p = kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
+ p = uml_kmalloc(sizeof(struct pollfd), UM_GFP_KERNEL);
if (p == NULL) {
printk(UM_KERN_ERR "setup_initial_poll : failed to allocate "
"poll\n");
@@ -338,20 +339,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)
+void sigio_broken(int fd, int read)
{
int err;
- if (!isatty(fd))
- return;
-
- if ((read || pty_output_sigio) && (!read || pty_close_sigio))
- return;
-
write_sigio_workaround();
sigio_lock();
@@ -370,6 +361,21 @@ out:
sigio_unlock();
}
+/* Changed during early boot */
+static int pty_output_sigio;
+static int pty_close_sigio;
+
+void maybe_sigio_broken(int fd, int read)
+{
+ if (!isatty(fd))
+ return;
+
+ if ((read || pty_output_sigio) && (!read || pty_close_sigio))
+ return;
+
+ sigio_broken(fd, read);
+}
+
static void sigio_cleanup(void)
{
if (write_sigio_pid == -1)
@@ -383,7 +389,7 @@ 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 int got_sigio;
static void __init handler(int sig)
{
@@ -498,7 +504,8 @@ static void tty_output(int master, int slave)
if (errno != EAGAIN)
printk(UM_KERN_ERR "tty_output : write failed, errno = %d\n",
errno);
- while (((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio)
+ while (((n = read(slave, buf, sizeof(buf))) > 0) &&
+ !({ barrier(); got_sigio; }))
;
if (got_sigio) {
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 3f1694b..5aade60 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -12,6 +12,7 @@
#include "as-layout.h"
#include "kern_util.h"
#include "os.h"
+#include "process.h"
#include "sysdep/barrier.h"
#include "sysdep/sigcontext.h"
#include "user.h"
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index 1e8cba6..172ad8f 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -55,7 +55,7 @@ static int ptrace_dump_regs(int pid)
* 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)
+#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 << SIGTRAP)
@@ -442,7 +442,7 @@ void userspace(struct uml_pt_regs *regs)
unblock_signals();
break;
default:
- printk(UM_KERN_ERR "userspace - child stopped "
+ printk(UM_KERN_ERR "userspace - child stopped "
"with signal %d\n", sig);
fatal_sigsegv();
}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index b616e15..183db26 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -23,17 +23,18 @@
#include "mem_user.h"
#include "ptrace_user.h"
#include "registers.h"
+#include "skas.h"
#include "skas_ptrace.h"
-static int ptrace_child(void)
+static void ptrace_child(void)
{
int ret;
/* Calling os_getpid because some libcs cached getpid incorrectly */
int pid = os_getpid(), ppid = getppid();
int sc_result;
- change_sig(SIGWINCH, 0);
- if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
+ if (change_sig(SIGWINCH, 0) < 0 ||
+ ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
perror("ptrace");
kill(pid, SIGKILL);
}
@@ -75,9 +76,8 @@ static void fatal(char *fmt, ...)
va_list list;
va_start(list, fmt);
- vprintf(fmt, list);
+ vfprintf(stderr, fmt, list);
va_end(list);
- fflush(stdout);
exit(1);
}
@@ -87,9 +87,8 @@ static void non_fatal(char *fmt, ...)
va_list list;
va_start(list, fmt);
- vprintf(fmt, list);
+ vfprintf(stderr, fmt, list);
va_end(list);
- fflush(stdout);
}
static int start_ptraced_child(void)
@@ -122,8 +121,10 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
{
int status, n, ret = 0;
- if (ptrace(PTRACE_CONT, pid, 0, 0) < 0)
- fatal_perror("stop_ptraced_child : ptrace failed");
+ if (ptrace(PTRACE_CONT, pid, 0, 0) < 0) {
+ perror("stop_ptraced_child : ptrace failed");
+ return -1;
+ }
CATCH_EINTR(n = waitpid(pid, &status, 0));
if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
int exit_with = WEXITSTATUS(status);
@@ -142,14 +143,27 @@ static int stop_ptraced_child(int pid, int exitcode, int mustexit)
}
/* Changed only during early boot */
-int ptrace_faultinfo = 1;
-int ptrace_ldt = 1;
-int proc_mm = 1;
-int skas_needs_stub = 0;
+int ptrace_faultinfo;
+static int disable_ptrace_faultinfo;
+
+int ptrace_ldt;
+static int disable_ptrace_ldt;
+
+int proc_mm;
+static int disable_proc_mm;
+
+int have_switch_mm;
+static int disable_switch_mm;
+
+int skas_needs_stub;
static int __init skas0_cmd_param(char *str, int* add)
{
- ptrace_faultinfo = proc_mm = 0;
+ disable_ptrace_faultinfo = 1;
+ disable_ptrace_ldt = 1;
+ disable_proc_mm = 1;
+ disable_switch_mm = 1;
+
return 0;
}
@@ -159,15 +173,12 @@ static int __init mode_skas0_cmd_param(char *str, int* add)
__attribute__((alias("skas0_cmd_param")));
__uml_setup("skas0", skas0_cmd_param,
- "skas0\n"
- " Disables SKAS3 usage, so that SKAS0 is used, unless \n"
- " you specify mode=tt.\n\n");
+"skas0\n"
+" Disables SKAS3 and SKAS4 usage, so that SKAS0 is used\n\n");
__uml_setup("mode=skas0", mode_skas0_cmd_param,
- "mode=skas0\n"
- " Disables SKAS3 usage, so that SKAS0 is used, unless you \n"
- " specify mode=tt. Note that this was recently added - on \n"
- " older kernels you must use simply \"skas0\".\n\n");
+"mode=skas0\n"
+" Disables SKAS3 and SKAS4 usage, so that SKAS0 is used.\n\n");
/* Changed only during early boot */
static int force_sysemu_disabled = 0;
@@ -203,7 +214,7 @@ static void __init check_sysemu(void)
if (n < 0)
fatal_perror("check_sysemu : wait failed");
if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
- fatal("check_sysemu : expected SIGTRAP, got status = %d",
+ fatal("check_sysemu : expected SIGTRAP, got status = %d\n",
status);
if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
@@ -245,9 +256,11 @@ static void __init check_sysemu(void)
if (WIFSTOPPED(status) &&
(WSTOPSIG(status) == (SIGTRAP|0x80))) {
- if (!count)
- fatal("check_ptrace : SYSEMU_SINGLESTEP "
- "doesn't singlestep");
+ if (!count) {
+ non_fatal("check_ptrace : SYSEMU_SINGLESTEP "
+ "doesn't singlestep");
+ goto fail;
+ }
n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
os_getpid());
if (n < 0)
@@ -257,9 +270,12 @@ static void __init check_sysemu(void)
}
else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
count++;
- else
- fatal("check_ptrace : expected SIGTRAP or "
- "(SIGTRAP | 0x80), got status = %d", status);
+ else {
+ non_fatal("check_ptrace : expected SIGTRAP or "
+ "(SIGTRAP | 0x80), got status = %d\n",
+ status);
+ goto fail;
+ }
}
if (stop_ptraced_child(pid, 0, 0) < 0)
goto fail_stopped;
@@ -362,7 +378,7 @@ void __init os_early_checks(void)
static int __init noprocmm_cmd_param(char *str, int* add)
{
- proc_mm = 0;
+ disable_proc_mm = 1;
return 0;
}
@@ -374,7 +390,7 @@ __uml_setup("noprocmm", noprocmm_cmd_param,
static int __init noptracefaultinfo_cmd_param(char *str, int* add)
{
- ptrace_faultinfo = 0;
+ disable_ptrace_faultinfo = 1;
return 0;
}
@@ -386,7 +402,7 @@ __uml_setup("noptracefaultinfo", noptracefaultinfo_cmd_param,
static int __init noptraceldt_cmd_param(char *str, int* add)
{
- ptrace_ldt = 0;
+ disable_ptrace_ldt = 1;
return 0;
}
@@ -406,17 +422,15 @@ static inline void check_skas3_ptrace_faultinfo(void)
n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
if (n < 0) {
- ptrace_faultinfo = 0;
if (errno == EIO)
non_fatal("not found\n");
else
perror("not found");
- }
+ } else if (disable_ptrace_faultinfo)
+ non_fatal("found but disabled on command line\n");
else {
- if (!ptrace_faultinfo)
- non_fatal("found but disabled on command line\n");
- else
- non_fatal("found\n");
+ ptrace_faultinfo = 1;
+ non_fatal("found\n");
}
stop_ptraced_child(pid, 1, 1);
@@ -439,38 +453,30 @@ static inline void check_skas3_ptrace_ldt(void)
if (n < 0) {
if (errno == EIO)
non_fatal("not found\n");
- else {
+ else
perror("not found");
- }
- ptrace_ldt = 0;
- }
+ } else if (disable_ptrace_ldt)
+ non_fatal("found, but use is disabled\n");
else {
- if (ptrace_ldt)
- non_fatal("found\n");
- else
- non_fatal("found, but use is disabled\n");
+ ptrace_ldt = 1;
+ non_fatal("found\n");
}
stop_ptraced_child(pid, 1, 1);
-#else
- /* PTRACE_LDT might be disabled via cmdline option.
- * We want to override this, else we might use the stub
- * without real need
- */
- ptrace_ldt = 1;
#endif
}
static inline void check_skas3_proc_mm(void)
{
non_fatal(" - /proc/mm...");
- if (access("/proc/mm", W_OK) < 0) {
- proc_mm = 0;
+ if (access("/proc/mm", W_OK) < 0)
perror("not found");
- }
- else if (!proc_mm)
+ else if (disable_proc_mm)
non_fatal("found but disabled on command line\n");
- else non_fatal("found\n");
+ else {
+ proc_mm = 1;
+ non_fatal("found\n");
+ }
}
void can_do_skas(void)
@@ -495,7 +501,7 @@ int __init parse_iomem(char *str, int *add)
driver = str;
file = strchr(str,',');
if (file == NULL) {
- printf("parse_iomem : failed to parse iomem\n");
+ fprintf(stderr, "parse_iomem : failed to parse iomem\n");
goto out;
}
*file = '\0';
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index b613473..229f7a5 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -5,6 +5,8 @@
*/
#include <errno.h>
+#include <sys/ptrace.h>
+#include <sys/user.h>
#include "kern_constants.h"
#include "longjmp.h"
#include "user.h"
@@ -74,10 +76,10 @@ int put_fp_registers(int pid, unsigned long *regs)
void arch_init_registers(int pid)
{
- unsigned long fpx_regs[HOST_XFP_SIZE];
+ struct user_fpxregs_struct fpx_regs;
int err;
- err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs);
+ err = ptrace(PTRACE_GETFPXREGS, pid, 0, &fpx_regs);
if (!err)
return;
diff --git a/arch/um/os-Linux/sys-i386/task_size.c b/arch/um/os-Linux/sys-i386/task_size.c
index 48d211b..be04c1e 100644
--- a/arch/um/os-Linux/sys-i386/task_size.c
+++ b/arch/um/os-Linux/sys-i386/task_size.c
@@ -63,7 +63,7 @@ static int page_ok(unsigned long page)
return ok;
}
-unsigned long os_get_task_size(void)
+unsigned long os_get_top_address(void)
{
struct sigaction sa, old;
unsigned long bottom = 0;
@@ -76,9 +76,9 @@ unsigned long os_get_task_size(void)
* hosts, but shouldn't hurt otherwise.
*/
unsigned long top = 0xffffd000 >> UM_KERN_PAGE_SHIFT;
- unsigned long test;
+ unsigned long test, original;
- printf("Locating the top of the address space ... ");
+ printf("Locating the bottom of the address space ... ");
fflush(stdout);
/*
@@ -88,14 +88,32 @@ unsigned long os_get_task_size(void)
sa.sa_handler = segfault;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_NODEFER;
- sigaction(SIGSEGV, &sa, &old);
+ if (sigaction(SIGSEGV, &sa, &old)) {
+ perror("os_get_top_address");
+ exit(1);
+ }
- if (!page_ok(bottom)) {
- fprintf(stderr, "Address 0x%x no good?\n",
- bottom << UM_KERN_PAGE_SHIFT);
+ /* Manually scan the address space, bottom-up, until we find
+ * the first valid page (or run out of them).
+ */
+ for (bottom = 0; bottom < top; bottom++) {
+ if (page_ok(bottom))
+ break;
+ }
+
+ /* If we've got this far, we ran out of pages. */
+ if (bottom == top) {
+ fprintf(stderr, "Unable to determine bottom of address "
+ "space.\n");
exit(1);
}
+ printf("0x%x\n", bottom << UM_KERN_PAGE_SHIFT);
+ printf("Locating the top of the address space ... ");
+ fflush(stdout);
+
+ original = bottom;
+
/* This could happen with a 4G/4G split */
if (page_ok(top))
goto out;
@@ -110,11 +128,12 @@ unsigned long os_get_task_size(void)
out:
/* Restore the old SIGSEGV handling */
- sigaction(SIGSEGV, &old, NULL);
-
+ if (sigaction(SIGSEGV, &old, NULL)) {
+ perror("os_get_top_address");
+ exit(1);
+ }
top <<= UM_KERN_PAGE_SHIFT;
printf("0x%x\n", top);
- fflush(stdout);
return top;
}
diff --git a/arch/um/os-Linux/sys-x86_64/task_size.c b/arch/um/os-Linux/sys-x86_64/task_size.c
index fad6f57..26a0dd1 100644
--- a/arch/um/os-Linux/sys-x86_64/task_size.c
+++ b/arch/um/os-Linux/sys-x86_64/task_size.c
@@ -1,4 +1,4 @@
-unsigned long os_get_task_size(unsigned long shift)
+unsigned long os_get_top_address(unsigned long shift)
{
/* The old value of CONFIG_TOP_ADDR */
return 0x7fc0000000;
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index e492805..dec5678 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -9,7 +9,9 @@
#include <time.h>
#include <sys/time.h>
#include "kern_constants.h"
+#include "kern_util.h"
#include "os.h"
+#include "process.h"
#include "user.h"
int set_interval(void)
@@ -58,12 +60,17 @@ static inline long long timeval_to_ns(const struct timeval *tv)
long long disable_timer(void)
{
struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
+ int remain, max = UM_NSEC_PER_SEC / UM_HZ;
if (setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
printk(UM_KERN_ERR "disable_timer - setitimer failed, "
"errno = %d\n", errno);
- return timeval_to_ns(&time.it_value);
+ remain = timeval_to_ns(&time.it_value);
+ if (remain > max)
+ remain = max;
+
+ return remain;
}
long long os_nsecs(void)
@@ -79,7 +86,48 @@ static int after_sleep_interval(struct timespec *ts)
{
return 0;
}
+
+static void deliver_alarm(void)
+{
+ alarm_handler(SIGVTALRM, NULL);
+}
+
+static unsigned long long sleep_time(unsigned long long nsecs)
+{
+ return nsecs;
+}
+
#else
+unsigned long long last_tick;
+unsigned long long skew;
+
+static void deliver_alarm(void)
+{
+ unsigned long long this_tick = os_nsecs();
+ int one_tick = UM_NSEC_PER_SEC / UM_HZ;
+
+ /* Protection against the host's time going backwards */
+ if ((last_tick != 0) && (this_tick < last_tick))
+ this_tick = last_tick;
+
+ if (last_tick == 0)
+ last_tick = this_tick - one_tick;
+
+ skew += this_tick - last_tick;
+
+ while (skew >= one_tick) {
+ alarm_handler(SIGVTALRM, NULL);
+ skew -= one_tick;
+ }
+
+ last_tick = this_tick;
+}
+
+static unsigned long long sleep_time(unsigned long long nsecs)
+{
+ return nsecs > skew ? nsecs - skew : 0;
+}
+
static inline long long timespec_to_us(const struct timespec *ts)
{
return ((long long) ts->tv_sec * UM_USEC_PER_SEC) +
@@ -102,6 +150,11 @@ static int after_sleep_interval(struct timespec *ts)
*/
if (start_usecs > usec)
start_usecs = usec;
+
+ start_usecs -= skew / UM_NSEC_PER_USEC;
+ if (start_usecs < 0)
+ start_usecs = 0;
+
tv = ((struct timeval) { .tv_sec = start_usecs / UM_USEC_PER_SEC,
.tv_usec = start_usecs % UM_USEC_PER_SEC });
interval = ((struct itimerval) { { 0, usec }, tv });
@@ -113,8 +166,6 @@ static int after_sleep_interval(struct timespec *ts)
}
#endif
-extern void alarm_handler(int sig, struct sigcontext *sc);
-
void idle_sleep(unsigned long long nsecs)
{
struct timespec ts;
@@ -126,10 +177,12 @@ void idle_sleep(unsigned long long nsecs)
*/
if (nsecs == 0)
nsecs = UM_NSEC_PER_SEC / UM_HZ;
+
+ nsecs = sleep_time(nsecs);
ts = ((struct timespec) { .tv_sec = nsecs / UM_NSEC_PER_SEC,
.tv_nsec = nsecs % UM_NSEC_PER_SEC });
if (nanosleep(&ts, &ts) == 0)
- alarm_handler(SIGVTALRM, NULL);
+ deliver_alarm();
after_sleep_interval(&ts);
}
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 964dc1a0..598b5c1 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -6,7 +6,7 @@ obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
sys_call_table.o tls.o
-subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o
+subarch-obj-y = lib/semaphore_32.o lib/string_32.o
subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c
index 2a1eac1..bfbefd3 100644
--- a/arch/um/sys-i386/ksyms.c
+++ b/arch/um/sys-i386/ksyms.c
@@ -1,17 +1,5 @@
#include "linux/module.h"
-#include "linux/in6.h"
-#include "linux/rwsem.h"
-#include "asm/byteorder.h"
-#include "asm/delay.h"
-#include "asm/semaphore.h"
-#include "asm/uaccess.h"
#include "asm/checksum.h"
-#include "asm/errno.h"
-
-EXPORT_SYMBOL(__down_failed);
-EXPORT_SYMBOL(__down_failed_interruptible);
-EXPORT_SYMBOL(__down_failed_trylock);
-EXPORT_SYMBOL(__up_wakeup);
/* Networking helper routines. */
EXPORT_SYMBOL(csum_partial);
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 6b44999..c9b1765 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -148,14 +148,13 @@ int peek_user(struct task_struct *child, long addr, long data)
int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
- long fpregs[HOST_FP_SIZE];
+ struct user_i387_struct fpregs;
- BUG_ON(sizeof(*buf) != sizeof(fpregs));
- err = save_fp_registers(userspace_pid[cpu], fpregs);
+ err = save_fp_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
if (err)
return err;
- n = copy_to_user(buf, fpregs, sizeof(fpregs));
+ n = copy_to_user(buf, &fpregs, sizeof(fpregs));
if(n > 0)
return -EFAULT;
@@ -165,27 +164,26 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
{
int n, cpu = ((struct thread_info *) child->stack)->cpu;
- long fpregs[HOST_FP_SIZE];
+ struct user_i387_struct fpregs;
- BUG_ON(sizeof(*buf) != sizeof(fpregs));
- n = copy_from_user(fpregs, buf, sizeof(fpregs));
+ n = copy_from_user(&fpregs, buf, sizeof(fpregs));
if (n > 0)
return -EFAULT;
- return restore_fp_registers(userspace_pid[cpu], fpregs);
+ return restore_fp_registers(userspace_pid[cpu],
+ (unsigned long *) &fpregs);
}
int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
{
int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
- long fpregs[HOST_XFP_SIZE];
+ struct user_fxsr_struct fpregs;
- BUG_ON(sizeof(*buf) != sizeof(fpregs));
- err = save_fpx_registers(userspace_pid[cpu], fpregs);
+ err = save_fpx_registers(userspace_pid[cpu], (unsigned long *) &fpregs);
if (err)
return err;
- n = copy_to_user(buf, fpregs, sizeof(fpregs));
+ n = copy_to_user(buf, &fpregs, sizeof(fpregs));
if(n > 0)
return -EFAULT;
@@ -195,14 +193,14 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
{
int n, cpu = ((struct thread_info *) child->stack)->cpu;
- long fpregs[HOST_XFP_SIZE];
+ struct user_fxsr_struct fpregs;
- BUG_ON(sizeof(*buf) != sizeof(fpregs));
- n = copy_from_user(fpregs, buf, sizeof(fpregs));
+ n = copy_from_user(&fpregs, buf, sizeof(fpregs));
if (n > 0)
return -EFAULT;
- return restore_fpx_registers(userspace_pid[cpu], fpregs);
+ return restore_fpx_registers(userspace_pid[cpu],
+ (unsigned long *) &fpregs);
}
long subarch_ptrace(struct task_struct *child, long request, long addr,
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 39bd32b..5f883bf 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -22,7 +22,7 @@ void foo(void)
OFFSET(HOST_SC_CR2, sigcontext, cr2);
DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct));
- DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct));
+ DEFINE_LONGS(HOST_FPX_SIZE, sizeof(struct user_fpxregs_struct));
DEFINE(HOST_IP, EIP);
DEFINE(HOST_SP, UESP);
diff --git a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile
index 0890152..b8bc844 100644
--- a/arch/um/sys-ppc/Makefile
+++ b/arch/um/sys-ppc/Makefile
@@ -3,7 +3,7 @@ OBJ = built-in.o
.S.o:
$(CC) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
-OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \
+OBJS = ptrace.o sigcontext.o checksum.o miscthings.o misc.o \
ptrace_user.o sysrq.o
EXTRA_AFLAGS := -DCONFIG_PPC32 -I. -I$(srctree)/arch/ppc/kernel
@@ -20,10 +20,6 @@ ptrace_user.o: ptrace_user.c
sigcontext.o: sigcontext.c
$(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
-semaphore.c:
- rm -f $@
- ln -s $(srctree)/arch/ppc/kernel/$@ $@
-
checksum.S:
rm -f $@
ln -s $(srctree)/arch/ppc/lib/$@ $@
@@ -66,4 +62,4 @@ misc.o: misc.S ppc_defs.h
$(CC) $(EXTRA_AFLAGS) $(KBUILD_AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
rm -f asm
-clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c
+clean-files := $(OBJS) ppc_defs.h checksum.S mk_defs.c
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index 3c22de5..c8b4cce 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -10,7 +10,7 @@ obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
obj-$(CONFIG_MODULES) += um_module.o
-subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
+subarch-obj-y = lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o
ldt-y = ../sys-i386/ldt.o
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c
index 12c5936..1db2fce 100644
--- a/arch/um/sys-x86_64/ksyms.c
+++ b/arch/um/sys-x86_64/ksyms.c
@@ -1,16 +1,11 @@
-#include "linux/module.h"
-#include "linux/in6.h"
-#include "linux/rwsem.h"
-#include "asm/byteorder.h"
-#include "asm/semaphore.h"
-#include "asm/uaccess.h"
-#include "asm/checksum.h"
-#include "asm/errno.h"
-
-EXPORT_SYMBOL(__down_failed);
-EXPORT_SYMBOL(__down_failed_interruptible);
-EXPORT_SYMBOL(__down_failed_trylock);
-EXPORT_SYMBOL(__up_wakeup);
+#include <linux/module.h>
+#include <asm/string.h>
+#include <asm/checksum.h>
/*XXX: we need them because they would be exported by x86_64 */
+#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4
+EXPORT_SYMBOL(memcpy);
+#else
EXPORT_SYMBOL(__memcpy);
+#endif
+EXPORT_SYMBOL(csum_partial);
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 2f3443c..9735854 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -24,7 +24,6 @@ void foo(void)
OFFSET(HOST_SC_TRAPNO, sigcontext, trapno);
DEFINE(HOST_FP_SIZE, sizeof(struct _fpstate) / sizeof(unsigned long));
- DEFINE(HOST_XFP_SIZE, 0);
DEFINE_LONGS(HOST_RBX, RBX);
DEFINE_LONGS(HOST_RCX, RCX);
DEFINE_LONGS(HOST_RDI, RDI);