aboutsummaryrefslogtreecommitdiff
path: root/arch/um
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig41
-rw-r--r--arch/um/Kconfig.char5
-rw-r--r--arch/um/Kconfig.i38649
-rw-r--r--arch/um/Makefile21
-rw-r--r--arch/um/Makefile-i3864
-rw-r--r--arch/um/Makefile-x86_648
-rw-r--r--arch/um/drivers/cow_sys.h1
-rw-r--r--arch/um/drivers/daemon_user.c1
-rw-r--r--arch/um/drivers/fd.c1
-rw-r--r--arch/um/drivers/mcast_user.c1
-rw-r--r--arch/um/drivers/mconsole_kern.c23
-rw-r--r--arch/um/drivers/mconsole_user.c1
-rw-r--r--arch/um/drivers/mmapper_kern.c3
-rw-r--r--arch/um/drivers/net_user.c1
-rw-r--r--arch/um/drivers/pcap_user.c1
-rw-r--r--arch/um/drivers/port_user.c1
-rw-r--r--arch/um/drivers/pty.c1
-rw-r--r--arch/um/drivers/slip_user.c1
-rw-r--r--arch/um/drivers/tty.c1
-rw-r--r--arch/um/drivers/ubd_kern.c319
-rw-r--r--arch/um/drivers/xterm.c2
-rw-r--r--arch/um/include/common-offsets.h11
-rw-r--r--arch/um/include/kern_util.h1
-rw-r--r--arch/um/include/longjmp.h3
-rw-r--r--arch/um/include/mconsole.h1
-rw-r--r--arch/um/include/mconsole_kern.h1
-rw-r--r--arch/um/include/os.h1
-rw-r--r--arch/um/include/sysdep-i386/barrier.h9
-rw-r--r--arch/um/include/sysdep-i386/kernel-offsets.h5
-rw-r--r--arch/um/include/sysdep-x86_64/barrier.h7
-rw-r--r--arch/um/include/sysdep-x86_64/kernel-offsets.h5
-rw-r--r--arch/um/include/um_malloc.h17
-rw-r--r--arch/um/include/user.h6
-rw-r--r--arch/um/include/user_util.h1
-rw-r--r--arch/um/kernel/dyn.lds.S1
-rw-r--r--arch/um/kernel/irq.c1
-rw-r--r--arch/um/kernel/process.c1
-rw-r--r--arch/um/kernel/skas/mmu.c5
-rw-r--r--arch/um/kernel/tt/tracer.c1
-rw-r--r--arch/um/kernel/tt/uaccess_user.c6
-rw-r--r--arch/um/kernel/uml.lds.S1
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c1
-rw-r--r--arch/um/os-Linux/helper.c54
-rw-r--r--arch/um/os-Linux/irq.c1
-rw-r--r--arch/um/os-Linux/main.c1
-rw-r--r--arch/um/os-Linux/process.c1
-rw-r--r--arch/um/os-Linux/sigio.c1
-rw-r--r--arch/um/os-Linux/signal.c31
-rw-r--r--arch/um/os-Linux/skas/process.c2
-rw-r--r--arch/um/os-Linux/sys-i386/tls.c3
-rw-r--r--arch/um/os-Linux/time.c3
-rw-r--r--arch/um/os-Linux/tls.c1
-rw-r--r--arch/um/os-Linux/tt.c1
-rw-r--r--arch/um/os-Linux/util.c9
-rw-r--r--arch/um/sys-i386/unmap.c11
-rw-r--r--arch/um/sys-x86_64/ksyms.c3
-rw-r--r--arch/um/sys-x86_64/stub_segv.c1
-rw-r--r--arch/um/sys-x86_64/unmap.c11
58 files changed, 442 insertions, 263 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index d75307589d7..5ac1f2963ae 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -1,3 +1,8 @@
+config DEFCONFIG_LIST
+ string
+ option defconfig_list
+ default "arch/$ARCH/defconfig"
+
# UML uses the generic IRQ sugsystem
config GENERIC_HARDIRQS
bool
@@ -25,6 +30,19 @@ config PCI
config PCMCIA
bool
+# Yet to do!
+config TRACE_IRQFLAGS_SUPPORT
+ bool
+ default n
+
+config LOCKDEP_SUPPORT
+ bool
+ default y
+
+config STACKTRACE_SUPPORT
+ bool
+ default y
+
config GENERIC_CALIBRATE_DELAY
bool
default y
@@ -37,13 +55,16 @@ config IRQ_RELEASE_METHOD
menu "UML-specific options"
config MODE_TT
- bool "Tracing thread support"
+ bool "Tracing thread support (DEPRECATED)"
default n
+ depends on BROKEN
help
This option controls whether tracing thread support is compiled
- into UML. This option is largely obsolete, given that skas0 provides
+ into UML. This option is largely obsolete, given that skas0 provides
skas security and performance without needing to patch the host.
- It is safe to say 'N' here.
+ It is safe to say 'N' here; saying 'Y' may cause additional problems
+ with the resulting binary even if you run UML in SKAS mode, and running
+ in TT mode is strongly *NOT RECOMMENDED*.
config STATIC_LINK
bool "Force a static link"
@@ -56,6 +77,9 @@ config STATIC_LINK
for use in a chroot jail. So, if you intend to run UML inside a
chroot, and you disable CONFIG_MODE_TT, you probably want to say Y
here.
+ Additionally, this option enables using higher memory spaces (up to
+ 2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads
+ to best results for this.
config KERNEL_HALF_GIGS
int "Kernel address space size (in .5G units)"
@@ -72,10 +96,13 @@ config MODE_SKAS
default y
help
This option controls whether skas (separate kernel address space)
- support is compiled in. If you have applied the skas patch to the
- host, then you certainly want to say Y here (and consider saying N
- to CONFIG_MODE_TT). Otherwise, it is safe to say Y. Disabling this
- option will shrink the UML binary slightly.
+ support is compiled in.
+ Unless you have specific needs to use TT mode (which applies almost only
+ to developers), you should say Y here.
+ SKAS mode will make use of the SKAS3 patch if it is applied on the host
+ (and your UML will run in SKAS3 mode), but if no SKAS patch is applied
+ on the host it will run in SKAS0 mode, which is anyway faster than TT
+ mode.
source "arch/um/Kconfig.arch"
source "mm/Kconfig"
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index 62d87b71179..e03e40c7aac 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -190,6 +190,11 @@ config HOSTAUDIO
tristate
default UML_SOUND
+#It is selected elsewhere, so kconfig would warn without this.
+config HW_RANDOM
+ tristate
+ default n
+
config UML_RANDOM
tristate "Hardware random number generator"
help
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index f6eb72d117b..f191a550a07 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -16,23 +16,42 @@ config SEMAPHORE_SLEEPERS
bool
default y
-config HOST_2G_2G
- bool "2G/2G host address space split"
- default n
- help
- This is needed when the host on which you run has a 2G/2G memory
- split, instead of the customary 3G/1G.
-
- Note that to enable such a host
- configuration, which makes sense only in some cases, you need special
- host patches.
-
- So, if you do not know what to do here, say 'N'.
+choice
+ prompt "Host memory split"
+ default HOST_VMSPLIT_3G
+ ---help---
+ This is needed when the host kernel on which you run has a non-default
+ (like 2G/2G) memory split, instead of the customary 3G/1G. If you did
+ not recompile your own kernel but use the default distro's one, you can
+ safely accept the "Default split" option.
+
+ It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via
+ CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck
+ patchset by Con Kolivas, or other ones) - option names match closely the
+ host CONFIG_VM_SPLIT_* ones.
+
+ A lower setting (where 1G/3G is lowest and 3G/1G is higher) will
+ tolerate even more "normal" host kernels, but an higher setting will be
+ stricter.
+
+ So, if you do not know what to do here, say 'Default split'.
+
+ config HOST_VMSPLIT_3G
+ bool "Default split (3G/1G user/kernel host split)"
+ config HOST_VMSPLIT_3G_OPT
+ bool "3G/1G user/kernel host split (for full 1G low memory)"
+ config HOST_VMSPLIT_2G
+ bool "2G/2G user/kernel host split"
+ config HOST_VMSPLIT_1G
+ bool "1G/3G user/kernel host split"
+endchoice
config TOP_ADDR
- hex
- default 0xc0000000 if !HOST_2G_2G
- default 0x80000000 if HOST_2G_2G
+ hex
+ default 0xB0000000 if HOST_VMSPLIT_3G_OPT
+ default 0x78000000 if HOST_VMSPLIT_2G
+ default 0x40000000 if HOST_VMSPLIT_1G
+ default 0xC0000000
config 3_LEVEL_PGTABLES
bool "Three-level pagetables (EXPERIMENTAL)"
diff --git a/arch/um/Makefile b/arch/um/Makefile
index c8016a98483..5d5ed726faa 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -64,9 +64,14 @@ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
AFLAGS += $(ARCH_INCLUDE)
-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
- $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64
+USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
+ $(patsubst -I%,,$(CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
+ -D_FILE_OFFSET_BITS=64
+
+include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
+
+#This will adjust *FLAGS accordingly to the platform.
+include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
# -Derrno=kernel_errno - This turns all kernel references to errno into
# kernel_errno to separate them from the libc errno. This allows -fno-common
@@ -74,15 +79,11 @@ USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
# errnos.
# These apply to kernelspace only.
-CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
- -Dmktime=kernel_mktime
+KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \
+ -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES)
+CFLAGS += $(KERNEL_DEFINES)
CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
-include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
-
-#This will adjust *FLAGS accordingly to the platform.
-include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
-
# These are needed for clean and mrproper, since in that case .config is not
# included; the values here are meaningless
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index b65ca115ef7..c9f1c5b24c9 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -16,7 +16,6 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S
ifeq ("$(origin SUBARCH)", "command line")
ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
CFLAGS += $(call cc-option,-m32)
-USER_CFLAGS += $(call cc-option,-m32)
AFLAGS += $(call cc-option,-m32)
LINK-y += $(call cc-option,-m32)
UML_OBJCOPYFLAGS += -F $(ELF_FORMAT)
@@ -25,7 +24,7 @@ export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS
endif
endif
-CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
+ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH)
# First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
include $(srctree)/arch/i386/Makefile.cpu
@@ -38,4 +37,3 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
cflags-y += -ffreestanding
CFLAGS += $(cflags-y)
-USER_CFLAGS += $(cflags-y)
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 11154b6773e..69ecea63fda 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -1,15 +1,15 @@
# Copyright 2003 - 2004 Pathscale, Inc
# Released under the GPL
-core-y += arch/um/sys-x86_64/
+core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/
START := 0x60000000
-_extra_flags_ = -fno-builtin -m64 -mcmodel=kernel
+_extra_flags_ = -fno-builtin -m64
#We #undef __x86_64__ for kernelspace, not for userspace where
#it's needed for headers to work!
-CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_)
-USER_CFLAGS += $(_extra_flags_)
+ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__
+CFLAGS += $(_extra_flags_)
CHECKFLAGS += -m64
AFLAGS += -m64
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index 7a5b4afde69..c6a308464ac 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -5,6 +5,7 @@
#include "user_util.h"
#include "os.h"
#include "user.h"
+#include "um_malloc.h"
static inline void *cow_malloc(int size)
{
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 77954ea7704..310af0f1e49 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -17,6 +17,7 @@
#include "user_util.h"
#include "user.h"
#include "os.h"
+#include "um_malloc.h"
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 108b7dafbd0..218aa0e9b79 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -12,6 +12,7 @@
#include "user_util.h"
#include "chan_user.h"
#include "os.h"
+#include "um_malloc.h"
struct fd_chan {
int fd;
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 4d2bd39a85b..8138f5ea1bf 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -23,6 +23,7 @@
#include "user_util.h"
#include "user.h"
#include "os.h"
+#include "um_malloc.h"
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index d08bd036ccb..7b172160fe0 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -79,7 +79,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
/* long to avoid size mismatch warnings from gcc */
long fd;
struct mconsole_entry *new;
- struct mc_request req;
+ static struct mc_request req; /* that's OK */
fd = (long) dev_id;
while (mconsole_get_request(fd, &req)){
@@ -91,6 +91,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
mconsole_reply(&req, "Out of memory", 1, 0);
else {
new->request = req;
+ new->request.regs = get_irq_regs()->regs;
list_add(&new->list, &mc_requests);
}
}
@@ -314,9 +315,21 @@ void mconsole_stop(struct mc_request *req)
{
deactivate_fd(req->originating_fd, MCONSOLE_IRQ);
os_set_fd_block(req->originating_fd, 1);
- mconsole_reply(req, "", 0, 0);
- while(mconsole_get_request(req->originating_fd, req)){
- if(req->cmd->handler == mconsole_go) break;
+ mconsole_reply(req, "stopped", 0, 0);
+ while (mconsole_get_request(req->originating_fd, req)) {
+ if (req->cmd->handler == mconsole_go)
+ break;
+ if (req->cmd->handler == mconsole_stop) {
+ mconsole_reply(req, "Already stopped", 1, 0);
+ continue;
+ }
+ if (req->cmd->handler == mconsole_sysrq) {
+ struct pt_regs *old_regs;
+ old_regs = set_irq_regs((struct pt_regs *)&req->regs);
+ mconsole_sysrq(req);
+ set_irq_regs(old_regs);
+ continue;
+ }
(*req->cmd->handler)(req);
}
os_set_fd_block(req->originating_fd, 0);
@@ -673,9 +686,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
static void sysrq_proc(void *arg)
{
char *op = arg;
- struct pt_regs *old_regs = set_irq_regs(&current->thread.regs);
handle_sysrq(*op, NULL);
- set_irq_regs(old_regs);
}
void mconsole_sysrq(struct mc_request *req)
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index 17068eb746c..75aef6f7ef6 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -14,6 +14,7 @@
#include <sys/un.h>
#include <unistd.h>
#include "user.h"
+#include "sysdep/ptrace.h"
#include "mconsole.h"
#include "umid.h"
#include "user_util.h"
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 9a3b5daf625..df3516e47d4 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -95,7 +95,8 @@ static const struct file_operations mmapper_fops = {
.release = mmapper_release,
};
-static const struct miscdevice mmapper_dev = {
+/* No locking needed - only used (and modified) by below initcall and exitcall. */
+static struct miscdevice mmapper_dev = {
.minor = MISC_DYNAMIC_MINOR,
.name = "mmapper",
.fops = &mmapper_fops
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index f3a3f8a29c7..0ffd7ac295d 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -18,6 +18,7 @@
#include "kern_util.h"
#include "net_user.h"
#include "os.h"
+#include "um_malloc.h"
int tap_open_common(void *dev, char *gate_addr)
{
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 2ef641ded96..11921a7baa7 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -12,6 +12,7 @@
#include "net_user.h"
#include "pcap_user.h"
#include "user.h"
+#include "um_malloc.h"
#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index f2e8fc42ecc..bc6afaf74c1 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -19,6 +19,7 @@
#include "chan_user.h"
#include "port.h"
#include "os.h"
+#include "um_malloc.h"
struct port_chan {
int raw;
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index abec620e838..829a5eca8c0 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -13,6 +13,7 @@
#include "user_util.h"
#include "kern_util.h"
#include "os.h"
+#include "um_malloc.h"
struct pty_chan {
void (*announce)(char *dev_name, int dev);
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index 8460285c69a..7eddacc53b6 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -15,6 +15,7 @@
#include "slip.h"
#include "slip_common.h"
#include "os.h"
+#include "um_malloc.h"
void slip_user_init(void *data, void *dev)
{
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index 11de3ac1eb5..d95d64309ea 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -11,6 +11,7 @@
#include "user_util.h"
#include "user.h"
#include "os.h"
+#include "um_malloc.h"
struct tty_chan {
char *dev;
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index bc458f57921..49c047b75cc 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -106,10 +106,15 @@ static inline void ubd_set_bit(__u64 bit, unsigned char *data)
#define DRIVER_NAME "uml-blkdev"
+/* Can be taken in interrupt context, and is passed to the block layer to lock
+ * the request queue. Kernel side code knows that. */
static DEFINE_SPINLOCK(ubd_io_lock);
-static DEFINE_SPINLOCK(ubd_lock);
-static void (*do_ubd)(void);
+static DEFINE_MUTEX(ubd_lock);
+
+/* XXX - this made sense in 2.4 days, now it's only used as a boolean, and
+ * probably it doesn't make sense even for that. */
+static int do_ubd;
static int ubd_open(struct inode * inode, struct file * filp);
static int ubd_release(struct inode * inode, struct file * file);
@@ -117,7 +122,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
-#define MAX_DEV (8)
+#define MAX_DEV (16)
static struct block_device_operations ubd_blops = {
.owner = THIS_MODULE,
@@ -150,8 +155,9 @@ static struct gendisk *fake_gendisk[MAX_DEV];
static struct openflags global_openflags = OPEN_FLAGS;
struct cow {
- /* This is the backing file, actually */
+ /* backing file name */
char *file;
+ /* backing file fd */
int fd;
unsigned long *bitmap;
unsigned long bitmap_len;
@@ -160,14 +166,16 @@ struct cow {
};
struct ubd {
+ /* name (and fd, below) of the file opened for writing, either the
+ * backing or the cow file. */
char *file;
int count;
int fd;
__u64 size;
struct openflags boot_openflags;
struct openflags openflags;
- int shared;
- int no_cow;
+ unsigned shared:1;
+ unsigned no_cow:1;
struct cow cow;
struct platform_device pdev;
};
@@ -192,18 +200,7 @@ struct ubd {
.cow = DEFAULT_COW, \
}
-struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
-
-static int ubd0_init(void)
-{
- struct ubd *dev = &ubd_dev[0];
-
- if(dev->file == NULL)
- dev->file = "root_fs";
- return(0);
-}
-
-__initcall(ubd0_init);
+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;
@@ -277,7 +274,7 @@ static int parse_unit(char **ptr)
return(-1);
*ptr = end;
}
- else if (('a' <= *str) && (*str <= 'h')) {
+ else if (('a' <= *str) && (*str <= 'z')) {
n = *str - 'a';
str++;
*ptr = str;
@@ -285,9 +282,13 @@ static int parse_unit(char **ptr)
return(n);
}
+/* If *index_out == -1 at exit, the passed option was a general one;
+ * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it
+ * should not be freed on exit.
+ */
static int ubd_setup_common(char *str, int *index_out)
{
- struct ubd *dev;
+ struct ubd *ubd_dev;
struct openflags flags = global_openflags;
char *backing_file;
int n, err, i;
@@ -311,7 +312,7 @@ static int ubd_setup_common(char *str, int *index_out)
}
err = 1;
- spin_lock(&ubd_lock);
+ mutex_lock(&ubd_lock);
if(fake_major != MAJOR_NR){
printk(KERN_ERR "Can't assign a fake major twice\n");
goto out1;
@@ -323,7 +324,7 @@ static int ubd_setup_common(char *str, int *index_out)
major);
err = 0;
out1:
- spin_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
return(err);
}
@@ -340,10 +341,10 @@ static int ubd_setup_common(char *str, int *index_out)
}
err = 1;
- spin_lock(&ubd_lock);
+ mutex_lock(&ubd_lock);
- dev = &ubd_dev[n];
- if(dev->file != NULL){
+ ubd_dev = &ubd_devs[n];
+ if(ubd_dev->file != NULL){
printk(KERN_ERR "ubd_setup : device already configured\n");
goto out;
}
@@ -360,10 +361,10 @@ static int ubd_setup_common(char *str, int *index_out)
flags.s = 1;
break;
case 'd':
- dev->no_cow = 1;
+ ubd_dev->no_cow = 1;
break;
case 'c':
- dev->shared = 1;
+ ubd_dev->shared = 1;
break;
case '=':
str++;
@@ -390,7 +391,7 @@ break_loop:
}
if(backing_file){
- if(dev->no_cow)
+ if(ubd_dev->no_cow)
printk(KERN_ERR "Can't specify both 'd' and a "
"cow file\n");
else {
@@ -398,11 +399,11 @@ break_loop:
backing_file++;
}
}
- dev->file = str;
- dev->cow.file = backing_file;
- dev->boot_openflags = flags;
+ ubd_dev->file = str;
+ ubd_dev->cow.file = backing_file;
+ ubd_dev->boot_openflags = flags;
out:
- spin_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
return(err);
}
@@ -472,8 +473,9 @@ int thread_fd = -1;
/* Changed by ubd_handler, which is serialized because interrupts only
* happen on CPU 0.
+ * XXX: currently unused.
*/
-int intr_count = 0;
+static int intr_count = 0;
/* call ubd_finish if you need to serialize */
static void __ubd_finish(struct request *req, int error)
@@ -493,6 +495,8 @@ static void __ubd_finish(struct request *req, int error)
end_request(req, 1);
}
+/* Callable only from interrupt context - otherwise you need to do
+ * spin_lock_irq()/spin_lock_irqsave() */
static inline void ubd_finish(struct request *req, int error)
{
spin_lock(&ubd_io_lock);
@@ -500,14 +504,15 @@ static inline void ubd_finish(struct request *req, int error)
spin_unlock(&ubd_io_lock);
}
-/* Called without ubd_io_lock held */
+/* XXX - move this inside ubd_intr. */
+/* Called without ubd_io_lock held, and only in interrupt context. */
static void ubd_handler(void)
{
struct io_thread_req req;
struct request *rq = elv_next_request(ubd_queue);
int n;
- do_ubd = NULL;
+ do_ubd = 0;
intr_count++;
n = os_read_file(thread_fd, &req, sizeof(req));
if(n != sizeof(req)){
@@ -521,7 +526,9 @@ static void ubd_handler(void)
ubd_finish(rq, req.error);
reactivate_fd(thread_fd, UBD_IRQ);
+ spin_lock(&ubd_io_lock);
do_ubd_request(ubd_queue);
+ spin_unlock(&ubd_io_lock);
}
static irqreturn_t ubd_intr(int irq, void *dev)
@@ -541,87 +548,90 @@ void kill_io_thread(void)
__uml_exitcall(kill_io_thread);
-static int ubd_file_size(struct ubd *dev, __u64 *size_out)
+static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
{
char *file;
- file = dev->cow.file ? dev->cow.file : dev->file;
+ file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file;
return(os_file_size(file, size_out));
}
-static void ubd_close(struct ubd *dev)
+static void ubd_close_dev(struct ubd *ubd_dev)
{
- os_close_file(dev->fd);
- if(dev->cow.file == NULL)
+ os_close_file(ubd_dev->fd);
+ if(ubd_dev->cow.file == NULL)
return;
- os_close_file(dev->cow.fd);
- vfree(dev->cow.bitmap);
- dev->cow.bitmap = NULL;
+ os_close_file(ubd_dev->cow.fd);
+ vfree(ubd_dev->cow.bitmap);
+ ubd_dev->cow.bitmap = NULL;
}
-static int ubd_open_dev(struct ubd *dev)
+static int ubd_open_dev(struct ubd *ubd_dev)
{
struct openflags flags;
char **back_ptr;
int err, create_cow, *create_ptr;
+ int fd;
- dev->openflags = dev->boot_openflags;
+ ubd_dev->openflags = ubd_dev->boot_openflags;
create_cow = 0;
- create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
- back_ptr = dev->no_cow ? NULL : &dev->cow.file;
- dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared,
- back_ptr, &dev->cow.bitmap_offset,
- &dev->cow.bitmap_len, &dev->cow.data_offset,
+ create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL;
+ back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file;
+
+ fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared,
+ back_ptr, &ubd_dev->cow.bitmap_offset,
+ &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset,
create_ptr);
- if((dev->fd == -ENOENT) && create_cow){
- dev->fd = create_cow_file(dev->file, dev->cow.file,
- dev->openflags, 1 << 9, PAGE_SIZE,
- &dev->cow.bitmap_offset,
- &dev->cow.bitmap_len,
- &dev->cow.data_offset);
- if(dev->fd >= 0){
+ if((fd == -ENOENT) && create_cow){
+ fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file,
+ ubd_dev->openflags, 1 << 9, PAGE_SIZE,
+ &ubd_dev->cow.bitmap_offset,
+ &ubd_dev->cow.bitmap_len,
+ &ubd_dev->cow.data_offset);
+ if(fd >= 0){
printk(KERN_INFO "Creating \"%s\" as COW file for "
- "\"%s\"\n", dev->file, dev->cow.file);
+ "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file);
}
}
- if(dev->fd < 0){
- printk("Failed to open '%s', errno = %d\n", dev->file,
- -dev->fd);
- return(dev->fd);
+ if(fd < 0){
+ printk("Failed to open '%s', errno = %d\n", ubd_dev->file,
+ -fd);
+ return fd;
}
+ ubd_dev->fd = fd;
- if(dev->cow.file != NULL){
+ if(ubd_dev->cow.file != NULL){
err = -ENOMEM;
- dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
- if(dev->cow.bitmap == NULL){
+ ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len);
+ if(ubd_dev->cow.bitmap == NULL){
printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
goto error;
}
flush_tlb_kernel_vm();
- err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
- dev->cow.bitmap_offset,
- dev->cow.bitmap_len);
+ err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap,
+ ubd_dev->cow.bitmap_offset,
+ ubd_dev->cow.bitmap_len);
if(err < 0)
goto error;
- flags = dev->openflags;
+ flags = ubd_dev->openflags;
flags.w = 0;
- err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL,
+ err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL,
NULL, NULL, NULL, NULL);
if(err < 0) goto error;
- dev->cow.fd = err;
+ ubd_dev->cow.fd = err;
}
return(0);
error:
- os_close_file(dev->fd);
+ os_close_file(ubd_dev->fd);
return(err);
}
-static int ubd_new_disk(int major, u64 size, int unit,
+static int ubd_disk_register(int major, u64 size, int unit,
struct gendisk **disk_out)
{
@@ -642,13 +652,13 @@ static int ubd_new_disk(int major, u64 size, int unit,
/* sysfs register (not for ide fake devices) */
if (major == MAJOR_NR) {
- ubd_dev[unit].pdev.id = unit;
- ubd_dev[unit].pdev.name = DRIVER_NAME;
- platform_device_register(&ubd_dev[unit].pdev);
- disk->driverfs_dev = &ubd_dev[unit].pdev.dev;
+ ubd_devs[unit].pdev.id = unit;
+ ubd_devs[unit].pdev.name = DRIVER_NAME;
+ platform_device_register(&ubd_devs[unit].pdev);
+ disk->driverfs_dev = &ubd_devs[unit].pdev.dev;
}
- disk->private_data = &ubd_dev[unit];
+ disk->private_data = &ubd_devs[unit];
disk->queue = ubd_queue;
add_disk(disk);
@@ -660,25 +670,25 @@ static int ubd_new_disk(int major, u64 size, int unit,
static int ubd_add(int n)
{
- struct ubd *dev = &ubd_dev[n];
+ struct ubd *ubd_dev = &ubd_devs[n];
int err;
err = -ENODEV;
- if(dev->file == NULL)
+ if(ubd_dev->file == NULL)
goto out;
- err = ubd_file_size(dev, &dev->size);
+ err = ubd_file_size(ubd_dev, &ubd_dev->size);
if(err < 0)
goto out;
- dev->size = ROUND_BLOCK(dev->size);
+ ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
- err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
+ err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]);
if(err)
goto out;
if(fake_major != MAJOR_NR)
- ubd_new_disk(fake_major, dev->size, n,
+ ubd_disk_register(fake_major, ubd_dev->size, n,
&fake_gendisk[n]);
/* perhaps this should also be under the "if (fake_major)" above */
@@ -693,32 +703,41 @@ out:
static int ubd_config(char *str)
{
- int n, err;
+ int n, ret;
str = kstrdup(str, GFP_KERNEL);
- if(str == NULL){
+ if (str == NULL) {
printk(KERN_ERR "ubd_config failed to strdup string\n");
- return(1);
+ ret = 1;
+ goto out;
}
- err = ubd_setup_common(str, &n);
- if(err){
- kfree(str);
- return(-1);
+ ret = ubd_setup_common(str, &n);
+ if (ret) {
+ ret = -1;
+ goto err_free;
+ }
+ if (n == -1) {
+ ret = 0;
+ goto err_free;
}
- if(n == -1) return(0);
- spin_lock(&ubd_lock);
- err = ubd_add(n);
- if(err)
- ubd_dev[n].file = NULL;
- spin_unlock(&ubd_lock);
+ mutex_lock(&ubd_lock);
+ ret = ubd_add(n);
+ if (ret)
+ ubd_devs[n].file = NULL;
+ mutex_unlock(&ubd_lock);
- return(err);
+out:
+ return ret;
+
+err_free:
+ kfree(str);
+ goto out;
}
static int ubd_get_config(char *name, char *str, int size, char **error_out)
{
- struct ubd *dev;
+ struct ubd *ubd_dev;
int n, len = 0;
n = parse_unit(&name);
@@ -727,24 +746,24 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out)
return(-1);
}
- dev = &ubd_dev[n];
- spin_lock(&ubd_lock);
+ ubd_dev = &ubd_devs[n];
+ mutex_lock(&ubd_lock);
- if(dev->file == NULL){
+ if(ubd_dev->file == NULL){
CONFIG_CHUNK(str, size, len, "", 1);
goto out;
}
- CONFIG_CHUNK(str, size, len, dev->file, 0);
+ CONFIG_CHUNK(str, size, len, ubd_dev->file, 0);
- if(dev->cow.file != NULL){
+ if(ubd_dev->cow.file != NULL){
CONFIG_CHUNK(str, size, len, ",", 0);
- CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
+ CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1);
}
else CONFIG_CHUNK(str, size, len, "", 1);
out:
- spin_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
return(len);
}
@@ -760,22 +779,22 @@ static int ubd_id(char **str, int *start_out, int *end_out)
static int ubd_remove(int n)
{
- struct ubd *dev;
+ struct ubd *ubd_dev;
int err = -ENODEV;
- spin_lock(&ubd_lock);
+ mutex_lock(&ubd_lock);
if(ubd_gendisk[n] == NULL)
goto out;
- dev = &ubd_dev[n];
+ ubd_dev = &ubd_devs[n];
- if(dev->file == NULL)
+ if(ubd_dev->file == NULL)
goto out;
/* you cannot remove a open disk */
err = -EBUSY;
- if(dev->count > 0)
+ if(ubd_dev->count > 0)
goto out;
del_gendisk(ubd_gendisk[n]);
@@ -788,14 +807,15 @@ static int ubd_remove(int n)
fake_gendisk[n] = NULL;
}
- platform_device_unregister(&dev->pdev);
- *dev = ((struct ubd) DEFAULT_UBD);
+ platform_device_unregister(&ubd_dev->pdev);
+ *ubd_dev = ((struct ubd) DEFAULT_UBD);
err = 0;
out:
- spin_unlock(&ubd_lock);
+ mutex_unlock(&ubd_lock);
return err;
}
+/* All these are called by mconsole in process context and without ubd-specific locks. */
static struct mc_device ubd_mc = {
.name = "ubd",
.config = ubd_config,
@@ -804,7 +824,7 @@ static struct mc_device ubd_mc = {
.remove = ubd_remove,
};
-static int ubd_mc_init(void)
+static int __init ubd_mc_init(void)
{
mconsole_register_dev(&ubd_mc);
return 0;
@@ -812,13 +832,24 @@ static int ubd_mc_init(void)
__initcall(ubd_mc_init);
+static int __init ubd0_init(void)
+{
+ struct ubd *ubd_dev = &ubd_devs[0];
+
+ if(ubd_dev->file == NULL)
+ ubd_dev->file = "root_fs";
+ return(0);
+}
+
+__initcall(ubd0_init);
+
static struct platform_driver ubd_driver = {
.driver = {
.name = DRIVER_NAME,
},
};
-int ubd_init(void)
+static int __init ubd_init(void)
{
int i;
@@ -846,7 +877,7 @@ int ubd_init(void)
late_initcall(ubd_init);
-int ubd_driver_init(void){
+static int __init ubd_driver_init(void){
unsigned long stack;
int err;
@@ -867,7 +898,7 @@ int ubd_driver_init(void){
return(0);
}
err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr,
- IRQF_DISABLED, "ubd", ubd_dev);
+ IRQF_DISABLED, "ubd", ubd_devs);
if(err != 0)
printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
return 0;
@@ -878,24 +909,24 @@ device_initcall(ubd_driver_init);
static int ubd_open(struct inode *inode, struct file *filp)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
- struct ubd *dev = disk->private_data;
+ struct ubd *ubd_dev = disk->private_data;
int err = 0;
- if(dev->count == 0){
- err = ubd_open_dev(dev);
+ if(ubd_dev->count == 0){
+ err = ubd_open_dev(ubd_dev);
if(err){
printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
- disk->disk_name, dev->file, -err);
+ disk->disk_name, ubd_dev->file, -err);
goto out;
}
}
- dev->count++;
- set_disk_ro(disk, !dev->openflags.w);
+ ubd_dev->count++;
+ set_disk_ro(disk, !ubd_dev->openflags.w);
/* This should no more be needed. And it didn't work anyway to exclude
* read-write remounting of filesystems.*/
- /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){
- if(--dev->count == 0) ubd_close(dev);
+ /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){
+ if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev);
err = -EROFS;
}*/
out:
@@ -905,10 +936,10 @@ static int ubd_open(struct inode *inode, struct file *filp)
static int ubd_release(struct inode * inode, struct file * file)
{
struct gendisk *disk = inode->i_bdev->bd_disk;
- struct ubd *dev = disk->private_data;
+ struct ubd *ubd_dev = disk->private_data;
- if(--dev->count == 0)
- ubd_close(dev);
+ if(--ubd_dev->count == 0)
+ ubd_close_dev(ubd_dev);
return(0);
}
@@ -976,12 +1007,12 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap,
static int prepare_request(struct request *req, struct io_thread_req *io_req)
{
struct gendisk *disk = req->rq_disk;
- struct ubd *dev = disk->private_data;
+ struct ubd *ubd_dev = disk->private_data;
__u64 offset;
int len;
/* This should be impossible now */
- if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
+ if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){
printk("Write attempted on readonly ubd device %s\n",
disk->disk_name);
end_request(req, 0);
@@ -991,8 +1022,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
offset = ((__u64) req->sector) << 9;
len = req->current_nr_sectors << 9;
- io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
- io_req->fds[1] = dev->fd;
+ io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd;
+ io_req->fds[1] = ubd_dev->fd;
io_req->cow_offset = -1;
io_req->offset = offset;
io_req->length = len;
@@ -1001,13 +1032,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
io_req->offsets[0] = 0;
- io_req->offsets[1] = dev->cow.data_offset;
+ io_req->offsets[1] = ubd_dev->cow.data_offset;
io_req->buffer = req->buffer;
io_req->sectorsize = 1 << 9;
- if(dev->cow.file != NULL)
- cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
- dev->cow.bitmap_len);
+ if(ubd_dev->cow.file != NULL)
+ cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset,
+ ubd_dev->cow.bitmap_len);
return(0);
}
@@ -1033,7 +1064,7 @@ static void do_ubd_request(request_queue_t *q)
return;
err = prepare_request(req, &io_req);
if(!err){
- do_ubd = ubd_handler;
+ do_ubd = 1;
n = os_write_file(thread_fd, (char *) &io_req,
sizeof(io_req));
if(n != sizeof(io_req))
@@ -1045,18 +1076,18 @@ static void do_ubd_request(request_queue_t *q)
static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
- struct ubd *dev = bdev->bd_disk->private_data;
+ struct ubd *ubd_dev = bdev->bd_disk->private_data;
geo->heads = 128;
geo->sectors = 32;
- geo->cylinders = dev->size / (128 * 32 * 512);
+ geo->cylinders = ubd_dev->size / (128 * 32 * 512);
return 0;
}
static int ubd_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
- struct ubd *dev = inode->i_bdev->bd_disk->private_data;
+ struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data;
struct hd_driveid ubd_id = {
.cyls = 0,
.heads = 128,
@@ -1066,7 +1097,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
switch (cmd) {
struct cdrom_volctrl volume;
case HDIO_GET_IDENTITY:
- ubd_id.cyls = dev->size / (128 * 32 * 512);
+ ubd_id.cyls = ubd_dev->size / (128 * 32 * 512);
if(copy_to_user((char __user *) arg, (char *) &ubd_id,
sizeof(ubd_id)))
return(-EFAULT);
@@ -1353,8 +1384,8 @@ void do_io(struct io_thread_req *req)
*/
int kernel_fd = -1;
-/* Only changed by the io thread */
-int io_count = 0;
+/* Only changed by the io thread. XXX: currently unused. */
+static int io_count = 0;
int io_thread(void *arg)
{
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index 386f8b95298..850221d9b4c 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -136,8 +136,6 @@ int xterm_open(int input, int output, int primary, void *d,
return(pid);
}
- if(data->stack == 0) free_stack(stack, 0);
-
if (data->direct_rcv) {
new = os_rcv_fd(fd, &data->helper_pid);
} else {
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 356390d1f8b..461175f8b1d 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -1,9 +1,16 @@
/* for use by sys-$SUBARCH/kernel-offsets.c */
+DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
+#ifdef CONFIG_MODE_TT
+OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
+#endif
+
OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
OFFSET(HOST_TASK_PID, task_struct, pid);
+
DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
+
DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
@@ -12,6 +19,10 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
DEFINE_STR(UM_KERN_INFO, KERN_INFO);
DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
+
DEFINE(UM_ELF_CLASS, ELF_CLASS);
DEFINE(UM_ELFCLASS32, ELFCLASS32);
DEFINE(UM_ELFCLASS64, ELFCLASS64);
+
+/* For crypto assembler code. */
+DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 59cfa9e0cad..cec9fcc57bf 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -6,7 +6,6 @@
#ifndef __KERN_UTIL_H__
#define __KERN_UTIL_H__
-#include "linux/threads.h"
#include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h"
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h
index e93c6d3e893..e860bc5848e 100644
--- a/arch/um/include/longjmp.h
+++ b/arch/um/include/longjmp.h
@@ -12,7 +12,8 @@ extern void longjmp(jmp_buf, int);
} while(0)
#define UML_SETJMP(buf) ({ \
- int n, enable; \
+ int n; \
+ volatile int enable; \
enable = get_signals(); \
n = setjmp(*buf); \
if(n != 0) \
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index 58f67d39110..2666815b6af 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -61,6 +61,7 @@ struct mc_request
struct mconsole_request request;
struct mconsole_command *cmd;
+ union uml_pt_regs regs;
};
extern char mconsole_socket_name[];
diff --git a/arch/um/include/mconsole_kern.h b/arch/um/include/mconsole_kern.h
index d0b690197fd..1ea6d928e1c 100644
--- a/arch/um/include/mconsole_kern.h
+++ b/arch/um/include/mconsole_kern.h
@@ -14,6 +14,7 @@ struct mconsole_entry {
struct mc_request request;
};
+/* All these methods are called in process context. */
struct mc_device {
struct list_head list;
char *name;
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 120ca21a513..6516f6dca96 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -201,6 +201,7 @@ extern int os_getpgrp(void);
#ifdef UML_CONFIG_MODE_TT
extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
+extern void stop(void);
#endif
extern void init_new_thread_signals(void);
extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
diff --git a/arch/um/include/sysdep-i386/barrier.h b/arch/um/include/sysdep-i386/barrier.h
new file mode 100644
index 00000000000..b58d52c5b2f
--- /dev/null
+++ b/arch/um/include/sysdep-i386/barrier.h
@@ -0,0 +1,9 @@
+#ifndef __SYSDEP_I386_BARRIER_H
+#define __SYSDEP_I386_BARRIER_H
+
+/* Copied from include/asm-i386 for use by userspace. i386 has the option
+ * of using mfence, but I'm just using this, which works everywhere, for now.
+ */
+#define mb() asm volatile("lock; addl $0,0(%esp)")
+
+#endif
diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h
index 2c13de321f2..97ec9d894d7 100644
--- a/arch/um/include/sysdep-i386/kernel-offsets.h
+++ b/arch/um/include/sysdep-i386/kernel-offsets.h
@@ -1,6 +1,7 @@
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/elf.h>
+#include <linux/crypto.h>
#include <asm/mman.h>
#define DEFINE(sym, val) \
@@ -17,9 +18,5 @@
void foo(void)
{
OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
- DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
-#ifdef CONFIG_MODE_TT
- OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
-#endif
#include <common-offsets.h>
}
diff --git a/arch/um/include/sysdep-x86_64/barrier.h b/arch/um/include/sysdep-x86_64/barrier.h
new file mode 100644
index 00000000000..7b610befdc8
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/barrier.h
@@ -0,0 +1,7 @@
+#ifndef __SYSDEP_X86_64_BARRIER_H
+#define __SYSDEP_X86_64_BARRIER_H
+
+/* Copied from include/asm-x86_64 for use by userspace. */
+#define mb() asm volatile("mfence":::"memory")
+
+#endif
diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h
index 91d129fb393..a307237b796 100644
--- a/arch/um/include/sysdep-x86_64/kernel-offsets.h
+++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h
@@ -2,6 +2,7 @@
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/elf.h>
+#include <linux/crypto.h>
#include <asm/page.h>
#include <asm/mman.h>
@@ -18,9 +19,5 @@
void foo(void)
{
- DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
-#ifdef CONFIG_MODE_TT
- OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
-#endif
#include <common-offsets.h>
}
diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h
new file mode 100644
index 00000000000..0363a9b53f8
--- /dev/null
+++ b/arch/um/include/um_malloc.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_MALLOC_H__
+#define __UM_MALLOC_H__
+
+extern void *um_kmalloc(int size);
+extern void *um_kmalloc_atomic(int size);
+extern void kfree(const void *ptr);
+
+extern void *um_vmalloc(int size);
+extern void *um_vmalloc_atomic(int size);
+extern void vfree(void *ptr);
+
+#endif /* __UM_MALLOC_H__ */
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index 39f8c880107..acadce3f271 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -11,17 +11,11 @@ extern void panic(const char *fmt, ...)
extern int printk(const char *fmt, ...)
__attribute__ ((format (printf, 1, 2)));
extern void schedule(void);
-extern void *um_kmalloc(int size);
-extern void *um_kmalloc_atomic(int size);
-extern void kfree(void *ptr);
extern int in_aton(char *str);
extern int open_gdb_chan(void);
/* These use size_t, however unsigned long is correct on both i386 and x86_64. */
extern unsigned long strlcpy(char *, const char *, unsigned long);
extern unsigned long strlcat(char *, const char *, unsigned long);
-extern void *um_vmalloc(int size);
-extern void *um_vmalloc_atomic(int size);
-extern void vfree(void *ptr);
#endif
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h
index 802d7842514..06625fefef3 100644
--- a/arch/um/include/user_util.h
+++ b/arch/um/include/user_util.h
@@ -52,7 +52,6 @@ extern int linux_main(int argc, char **argv);
extern void set_cmdline(char *cmd);
extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
extern int get_pty(void);
-extern void *um_kmalloc(int size);
extern int switcheroo(int fd, int prot, void *from, void *to, int size);
extern void do_exec(int old_pid, int new_pid);
extern void tracer_panic(char *msg, ...)
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 68ed24df5c8..e36f92b463c 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -14,6 +14,7 @@ SECTIONS
* is remapped.*/
__binary_start = .;
. = ALIGN(4096); /* Init code and data */
+ _text = .;
_stext = .;
__init_begin = .;
.init.text : {
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index ef259569fd8..5c1e611f628 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -31,6 +31,7 @@
#include "irq_kern.h"
#include "os.h"
#include "sigio.h"
+#include "um_malloc.h"
#include "misc_constants.h"
/*
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index fe6c64abda5..348b272bb76 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -46,6 +46,7 @@
#include "mode.h"
#include "mode_kern.h"
#include "choose-mode.h"
+#include "um_malloc.h"
/* This is a per-cpu array. A processor only modifies its entry and it only
* cares about its entry, so it's OK if another processor is modifying its
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index c17eddcf89b..2c6d090a2e8 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -60,10 +60,7 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
#endif
*pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
- /* This is wrong for the code page, but it doesn't matter since the
- * stub is mapped by hand with the correct permissions.
- */
- *pte = pte_mkwrite(*pte);
+ *pte = pte_mkread(*pte);
return(0);
out_pmd:
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index 9882342206e..b9195355075 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -176,7 +176,6 @@ struct {
int signal_index[32];
int nsignals = 0;
int debug_trace = 0;
-extern int io_nsignals, io_count, intr_count;
extern void signal_usr1(int sig);
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
index 6c92bbccb49..ed1abcf4d05 100644
--- a/arch/um/kernel/tt/uaccess_user.c
+++ b/arch/um/kernel/tt/uaccess_user.c
@@ -4,13 +4,13 @@
* Licensed under the GPL
*/
-#include <setjmp.h>
#include <string.h>
#include "user_util.h"
#include "uml_uaccess.h"
#include "task.h"
#include "kern_util.h"
#include "os.h"
+#include "longjmp.h"
int __do_copy_from_user(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher)
@@ -80,10 +80,10 @@ int __do_strnlen_user(const char *str, unsigned long n,
struct tt_regs save = TASK_REGS(get_current())->tt;
int ret;
unsigned long *faddrp = (unsigned long *)fault_addr;
- sigjmp_buf jbuf;
+ jmp_buf jbuf;
*fault_catcher = &jbuf;
- if(sigsetjmp(jbuf, 1) == 0)
+ if(UML_SETJMP(&jbuf) == 0)
ret = strlen(str) + 1;
else ret = *faddrp - (unsigned long) str;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 8eca47a6ff0..f6301274cf3 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -25,6 +25,7 @@ SECTIONS
. = ALIGN(4096); /* Init code and data */
#endif
+ _text = .;
_stext = .;
__init_begin = .;
.init.text : {
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index f559bdf746e..863981ba146 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -20,6 +20,7 @@
#include "net_user.h"
#include "etap.h"
#include "os.h"
+#include "um_malloc.h"
#define MAX_PACKET ETH_MAX_PACKET
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index cd15b9df5b5..d13299cfa31 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -35,22 +35,23 @@ static int helper_child(void *arg)
char **argv = data->argv;
int errval;
- if(helper_pause){
+ if (helper_pause){
signal(SIGHUP, helper_hup);
pause();
}
- if(data->pre_exec != NULL)
+ if (data->pre_exec != NULL)
(*data->pre_exec)(data->pre_data);
execvp(argv[0], argv);
errval = -errno;
printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno);
os_write_file(data->fd, &errval, sizeof(errval));
kill(os_getpid(), SIGKILL);
- return(0);
+ return 0;
}
/* Returns either the pid of the child process we run or -E* on failure.
- * XXX The alloc_stack here breaks if this is called in the tracing thread */
+ * XXX The alloc_stack here breaks if this is called in the tracing thread, so
+ * we need to receive a preallocated stack (a local buffer is ok). */
int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
unsigned long *stack_out)
{
@@ -58,20 +59,21 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
unsigned long stack, sp;
int pid, fds[2], ret, n;
- if((stack_out != NULL) && (*stack_out != 0))
+ if ((stack_out != NULL) && (*stack_out != 0))
stack = *stack_out;
- else stack = alloc_stack(0, __cant_sleep());
- if(stack == 0)
+ else
+ stack = alloc_stack(0, __cant_sleep());
+ if (stack == 0)
return -ENOMEM;
ret = os_pipe(fds, 1, 0);
- if(ret < 0){
+ if (ret < 0) {
printk("run_helper : pipe failed, ret = %d\n", -ret);
goto out_free;
}
ret = os_set_exec_close(fds[1], 1);
- if(ret < 0){
+ if (ret < 0) {
printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
-ret);
goto out_close;
@@ -83,7 +85,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
data.argv = argv;
data.fd = fds[1];
pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
- if(pid < 0){
+ if (pid < 0) {
ret = -errno;
printk("run_helper : clone failed, errno = %d\n", errno);
goto out_close;
@@ -95,10 +97,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
/* 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));
- if(n == 0)
+ if (n == 0) {
ret = pid;
- else {
- if(n < 0){
+ } else {
+ if (n < 0) {
printk("run_helper : read on pipe failed, ret = %d\n",
-n);
ret = n;
@@ -112,10 +114,9 @@ out_close:
close(fds[1]);
close(fds[0]);
out_free:
- if(stack_out == NULL)
+ if ((stack_out == NULL) || (*stack_out == 0))
free_stack(stack, 0);
- else *stack_out = stack;
- return(ret);
+ return ret;
}
int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
@@ -125,31 +126,32 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
int pid, status, err;
stack = alloc_stack(stack_order, __cant_sleep());
- if(stack == 0) return(-ENOMEM);
+ if (stack == 0)
+ return -ENOMEM;
sp = stack + (page_size() << stack_order) - sizeof(void *);
pid = clone(proc, (void *) sp, flags | SIGCHLD, arg);
- if(pid < 0){
+ if (pid < 0) {
err = -errno;
printk("run_helper_thread : clone failed, errno = %d\n",
errno);
return err;
}
- if(stack_out == NULL){
+ if (stack_out == NULL) {
CATCH_EINTR(pid = waitpid(pid, &status, 0));
- if(pid < 0){
+ if (pid < 0) {
err = -errno;
printk("run_helper_thread - wait failed, errno = %d\n",
errno);
pid = err;
}
- if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
+ if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
printk("run_helper_thread - thread returned status "
"0x%x\n", status);
free_stack(stack, stack_order);
- }
- else *stack_out = stack;
- return(pid);
+ } else
+ *stack_out = stack;
+ return pid;
}
int helper_wait(int pid)
@@ -157,9 +159,9 @@ int helper_wait(int pid)
int ret;
CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG));
- if(ret < 0){
+ if (ret < 0) {
ret = -errno;
printk("helper_wait : waitpid failed, errno = %d\n", errno);
}
- return(ret);
+ return ret;
}
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index a97206df5b5..d46b818c131 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -18,6 +18,7 @@
#include "sigio.h"
#include "irq_user.h"
#include "os.h"
+#include "um_malloc.h"
static struct pollfd *pollfds = NULL;
static int pollfds_num = 0;
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index d1c5670787d..685feaab65d 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -23,6 +23,7 @@
#include "choose-mode.h"
#include "uml-config.h"
#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.
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index 51f0893640a..c692a192957 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -7,7 +7,6 @@
#include <stdio.h>
#include <errno.h>
#include <signal.h>
-#include <linux/unistd.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/mman.h>
diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c
index f6457765b17..925a65240cf 100644
--- a/arch/um/os-Linux/sigio.c
+++ b/arch/um/os-Linux/sigio.c
@@ -19,6 +19,7 @@
#include "user_util.h"
#include "sigio.h"
#include "os.h"
+#include "um_malloc.h"
/* Protected by sigio_lock(), also used by sigio_cleanup, which is an
* exitcall.
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 6b81739279d..b897e8592d7 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -15,6 +15,7 @@
#include "user.h"
#include "signal_kern.h"
#include "sysdep/sigcontext.h"
+#include "sysdep/barrier.h"
#include "sigcontext.h"
#include "mode.h"
#include "os.h"
@@ -34,8 +35,12 @@
#define SIGALRM_BIT 2
#define SIGALRM_MASK (1 << SIGALRM_BIT)
-static int signals_enabled = 1;
-static int pending = 0;
+/* These are used by both the signal handlers and
+ * block/unblock_signals. I don't want modifications cached in a
+ * register - they must go straight to memory.
+ */
+static volatile int signals_enabled = 1;
+static volatile int pending = 0;
void sig_handler(int sig, struct sigcontext *sc)
{
@@ -152,6 +157,12 @@ int change_sig(int signal, int on)
void block_signals(void)
{
signals_enabled = 0;
+ /* This must return with signals disabled, so this barrier
+ * ensures that writes are flushed out before the return.
+ * This might matter if gcc figures out how to inline this and
+ * decides to shuffle this code into the caller.
+ */
+ mb();
}
void unblock_signals(void)
@@ -171,9 +182,23 @@ void unblock_signals(void)
*/
signals_enabled = 1;
+ /* Setting signals_enabled and reading pending must
+ * happen in this order.
+ */
+ mb();
+
save_pending = pending;
- if(save_pending == 0)
+ if(save_pending == 0){
+ /* This must return with signals enabled, so
+ * this barrier ensures that writes are
+ * flushed out before the return. This might
+ * matter if gcc figures out how to inline
+ * this (unlikely, given its size) and decides
+ * to shuffle this code into the caller.
+ */
+ mb();
return;
+ }
pending = 0;
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index cb9ab54146c..9b34fe65949 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -14,7 +14,7 @@
#include <sys/mman.h>
#include <sys/user.h>
#include <sys/time.h>
-#include <asm/unistd.h>
+#include <sys/syscall.h>
#include <asm/types.h>
#include "user.h"
#include "sysdep/ptrace.h"
diff --git a/arch/um/os-Linux/sys-i386/tls.c b/arch/um/os-Linux/sys-i386/tls.c
index 6e945ab4584..256532034c6 100644
--- a/arch/um/os-Linux/sys-i386/tls.c
+++ b/arch/um/os-Linux/sys-i386/tls.c
@@ -1,6 +1,9 @@
#include <errno.h>
#include <linux/unistd.h>
+
#include <sys/syscall.h>
+#include <unistd.h>
+
#include "sysdep/tls.h"
#include "user_util.h"
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 38be096e750..2115b8beb54 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -16,6 +16,7 @@
#include "process.h"
#include "kern_constants.h"
#include "os.h"
+#include "uml-config.h"
int set_interval(int is_virtual)
{
@@ -30,7 +31,7 @@ int set_interval(int is_virtual)
return 0;
}
-#ifdef CONFIG_MODE_TT
+#ifdef UML_CONFIG_MODE_TT
void enable_timer(void)
{
set_interval(1);
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index a2de2580b8a..16215b99080 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -1,4 +1,5 @@
#include <errno.h>
+#include <unistd.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <asm/ldt.h>
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
index 5461a065bbb..3dc3a02d626 100644
--- a/arch/um/os-Linux/tt.c
+++ b/arch/um/os-Linux/tt.c
@@ -10,7 +10,6 @@
#include <errno.h>
#include <stdarg.h>
#include <stdlib.h>
-#include <setjmp.h>
#include <sys/time.h>
#include <sys/ptrace.h>
#include <linux/ptrace.h>
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 3f5b1514e8a..56b8a50e8bc 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -80,11 +80,18 @@ void setup_machinename(char *machine_out)
struct utsname host;
uname(&host);
-#if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT)
+#ifdef UML_CONFIG_UML_X86
+# ifndef UML_CONFIG_64BIT
if (!strcmp(host.machine, "x86_64")) {
strcpy(machine_out, "i686");
return;
}
+# else
+ if (!strcmp(host.machine, "i686")) {
+ strcpy(machine_out, "x86_64");
+ return;
+ }
+# endif
#endif
strcpy(machine_out, host.machine);
}
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
index 8e55cd5d3d0..1b0ad0e4adc 100644
--- a/arch/um/sys-i386/unmap.c
+++ b/arch/um/sys-i386/unmap.c
@@ -5,17 +5,20 @@
#include <linux/mman.h>
#include <asm/unistd.h>
-#include <sys/syscall.h>
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
int switcheroo(int fd, int prot, void *from, void *to, int size)
{
- if (syscall(__NR_munmap, to, size) < 0){
+ if(munmap(to, size) < 0){
return(-1);
}
- if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
+ if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
return(-1);
}
- if (syscall(__NR_munmap, from, size) < 0){
+ if(munmap(from, size) < 0){
return(-1);
}
return(0);
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c
index 85927380820..12c593607c5 100644
--- a/arch/um/sys-x86_64/ksyms.c
+++ b/arch/um/sys-x86_64/ksyms.c
@@ -14,6 +14,3 @@ EXPORT_SYMBOL(__up_wakeup);
/*XXX: we need them because they would be exported by x86_64 */
EXPORT_SYMBOL(__memcpy);
-
-/* Networking helper routines. */
-EXPORT_SYMBOL(ip_compute_csum);
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index 1c967026c95..652fa34c2cd 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -5,7 +5,6 @@
#include <stddef.h>
#include <signal.h>
-#include <linux/compiler.h>
#include <asm/unistd.h>
#include "uml-config.h"
#include "sysdep/sigcontext.h"
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
index 57c9286a701..f4a4bffd8a1 100644
--- a/arch/um/sys-x86_64/unmap.c
+++ b/arch/um/sys-x86_64/unmap.c
@@ -5,17 +5,20 @@
#include <linux/mman.h>
#include <asm/unistd.h>
-#include <sys/syscall.h>
+static int errno;
+
+static inline _syscall2(int,munmap,void *,start,size_t,len)
+static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
int switcheroo(int fd, int prot, void *from, void *to, int size)
{
- if (syscall(__NR_munmap, to, size) < 0){
+ if(munmap(to, size) < 0){
return(-1);
}
- if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
+ if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
return(-1);
}
- if (syscall(__NR_munmap, from, size) < 0){
+ if(munmap(from, size) < 0){
return(-1);
}
return(0);