diff options
Diffstat (limited to 'arch/um')
51 files changed, 570 insertions, 294 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index 78fb619bdb7..5ac1f2963ae 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig | |||
@@ -1,3 +1,8 @@ | |||
1 | config DEFCONFIG_LIST | ||
2 | string | ||
3 | option defconfig_list | ||
4 | default "arch/$ARCH/defconfig" | ||
5 | |||
1 | # UML uses the generic IRQ sugsystem | 6 | # UML uses the generic IRQ sugsystem |
2 | config GENERIC_HARDIRQS | 7 | config GENERIC_HARDIRQS |
3 | bool | 8 | bool |
@@ -52,6 +57,7 @@ menu "UML-specific options" | |||
52 | config MODE_TT | 57 | config MODE_TT |
53 | bool "Tracing thread support (DEPRECATED)" | 58 | bool "Tracing thread support (DEPRECATED)" |
54 | default n | 59 | default n |
60 | depends on BROKEN | ||
55 | help | 61 | help |
56 | This option controls whether tracing thread support is compiled | 62 | This option controls whether tracing thread support is compiled |
57 | into UML. This option is largely obsolete, given that skas0 provides | 63 | into UML. This option is largely obsolete, given that skas0 provides |
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 | |||
190 | tristate | 190 | tristate |
191 | default UML_SOUND | 191 | default UML_SOUND |
192 | 192 | ||
193 | #It is selected elsewhere, so kconfig would warn without this. | ||
194 | config HW_RANDOM | ||
195 | tristate | ||
196 | default n | ||
197 | |||
193 | config UML_RANDOM | 198 | config UML_RANDOM |
194 | tristate "Hardware random number generator" | 199 | tristate "Hardware random number generator" |
195 | help | 200 | help |
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)\" \ | |||
64 | 64 | ||
65 | AFLAGS += $(ARCH_INCLUDE) | 65 | AFLAGS += $(ARCH_INCLUDE) |
66 | 66 | ||
67 | USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) | 67 | USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\ |
68 | USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ | 68 | $(patsubst -I%,,$(CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \ |
69 | $(MODE_INCLUDE) -D_FILE_OFFSET_BITS=64 | 69 | -D_FILE_OFFSET_BITS=64 |
70 | |||
71 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) | ||
72 | |||
73 | #This will adjust *FLAGS accordingly to the platform. | ||
74 | include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) | ||
70 | 75 | ||
71 | # -Derrno=kernel_errno - This turns all kernel references to errno into | 76 | # -Derrno=kernel_errno - This turns all kernel references to errno into |
72 | # kernel_errno to separate them from the libc errno. This allows -fno-common | 77 | # 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) \ | |||
74 | # errnos. | 79 | # errnos. |
75 | # These apply to kernelspace only. | 80 | # These apply to kernelspace only. |
76 | 81 | ||
77 | CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ | 82 | KERNEL_DEFINES = -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask \ |
78 | -Dmktime=kernel_mktime | 83 | -Dmktime=kernel_mktime $(ARCH_KERNEL_DEFINES) |
84 | CFLAGS += $(KERNEL_DEFINES) | ||
79 | CFLAGS += $(call cc-option,-fno-unit-at-a-time,) | 85 | CFLAGS += $(call cc-option,-fno-unit-at-a-time,) |
80 | 86 | ||
81 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) | ||
82 | |||
83 | #This will adjust *FLAGS accordingly to the platform. | ||
84 | include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS) | ||
85 | |||
86 | # These are needed for clean and mrproper, since in that case .config is not | 87 | # These are needed for clean and mrproper, since in that case .config is not |
87 | # included; the values here are meaningless | 88 | # included; the values here are meaningless |
88 | 89 | ||
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 | |||
16 | ifeq ("$(origin SUBARCH)", "command line") | 16 | ifeq ("$(origin SUBARCH)", "command line") |
17 | ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") | 17 | ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)") |
18 | CFLAGS += $(call cc-option,-m32) | 18 | CFLAGS += $(call cc-option,-m32) |
19 | USER_CFLAGS += $(call cc-option,-m32) | ||
20 | AFLAGS += $(call cc-option,-m32) | 19 | AFLAGS += $(call cc-option,-m32) |
21 | LINK-y += $(call cc-option,-m32) | 20 | LINK-y += $(call cc-option,-m32) |
22 | UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) | 21 | UML_OBJCOPYFLAGS += -F $(ELF_FORMAT) |
@@ -25,7 +24,7 @@ export LDFLAGS HOSTCFLAGS HOSTLDFLAGS UML_OBJCOPYFLAGS | |||
25 | endif | 24 | endif |
26 | endif | 25 | endif |
27 | 26 | ||
28 | CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH) | 27 | ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH) |
29 | 28 | ||
30 | # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. | 29 | # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y. |
31 | include $(srctree)/arch/i386/Makefile.cpu | 30 | include $(srctree)/arch/i386/Makefile.cpu |
@@ -38,4 +37,3 @@ cflags-y += $(call cc-option,-mpreferred-stack-boundary=2) | |||
38 | cflags-y += -ffreestanding | 37 | cflags-y += -ffreestanding |
39 | 38 | ||
40 | CFLAGS += $(cflags-y) | 39 | CFLAGS += $(cflags-y) |
41 | USER_CFLAGS += $(cflags-y) | ||
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index d278682dd79..69ecea63fda 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 | |||
@@ -8,8 +8,8 @@ _extra_flags_ = -fno-builtin -m64 | |||
8 | 8 | ||
9 | #We #undef __x86_64__ for kernelspace, not for userspace where | 9 | #We #undef __x86_64__ for kernelspace, not for userspace where |
10 | #it's needed for headers to work! | 10 | #it's needed for headers to work! |
11 | CFLAGS += -U__$(SUBARCH)__ $(_extra_flags_) | 11 | ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__ |
12 | USER_CFLAGS += $(_extra_flags_) | 12 | CFLAGS += $(_extra_flags_) |
13 | 13 | ||
14 | CHECKFLAGS += -m64 | 14 | CHECKFLAGS += -m64 |
15 | AFLAGS += -m64 | 15 | AFLAGS += -m64 |
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c index 2f880cb167a..0cad3546cb8 100644 --- a/arch/um/drivers/chan_user.c +++ b/arch/um/drivers/chan_user.c | |||
@@ -120,7 +120,7 @@ static int winch_thread(void *arg) | |||
120 | /* These are synchronization calls between various UML threads on the | 120 | /* These are synchronization calls between various UML threads on the |
121 | * host - since they are not different kernel threads, we cannot use | 121 | * host - since they are not different kernel threads, we cannot use |
122 | * kernel semaphores. We don't use SysV semaphores because they are | 122 | * kernel semaphores. We don't use SysV semaphores because they are |
123 | * persistant. */ | 123 | * persistent. */ |
124 | count = os_read_file(pipe_fd, &c, sizeof(c)); | 124 | count = os_read_file(pipe_fd, &c, sizeof(c)); |
125 | if(count != sizeof(c)) | 125 | if(count != sizeof(c)) |
126 | printk("winch_thread : failed to read synchronization byte, " | 126 | printk("winch_thread : failed to read synchronization byte, " |
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 @@ | |||
5 | #include "user_util.h" | 5 | #include "user_util.h" |
6 | #include "os.h" | 6 | #include "os.h" |
7 | #include "user.h" | 7 | #include "user.h" |
8 | #include "um_malloc.h" | ||
8 | 9 | ||
9 | static inline void *cow_malloc(int size) | 10 | static inline void *cow_malloc(int size) |
10 | { | 11 | { |
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 @@ | |||
17 | #include "user_util.h" | 17 | #include "user_util.h" |
18 | #include "user.h" | 18 | #include "user.h" |
19 | #include "os.h" | 19 | #include "os.h" |
20 | #include "um_malloc.h" | ||
20 | 21 | ||
21 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | 22 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) |
22 | 23 | ||
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 @@ | |||
12 | #include "user_util.h" | 12 | #include "user_util.h" |
13 | #include "chan_user.h" | 13 | #include "chan_user.h" |
14 | #include "os.h" | 14 | #include "os.h" |
15 | #include "um_malloc.h" | ||
15 | 16 | ||
16 | struct fd_chan { | 17 | struct fd_chan { |
17 | int fd; | 18 | 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 @@ | |||
23 | #include "user_util.h" | 23 | #include "user_util.h" |
24 | #include "user.h" | 24 | #include "user.h" |
25 | #include "os.h" | 25 | #include "os.h" |
26 | #include "um_malloc.h" | ||
26 | 27 | ||
27 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | 28 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) |
28 | 29 | ||
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) | |||
79 | /* long to avoid size mismatch warnings from gcc */ | 79 | /* long to avoid size mismatch warnings from gcc */ |
80 | long fd; | 80 | long fd; |
81 | struct mconsole_entry *new; | 81 | struct mconsole_entry *new; |
82 | struct mc_request req; | 82 | static struct mc_request req; /* that's OK */ |
83 | 83 | ||
84 | fd = (long) dev_id; | 84 | fd = (long) dev_id; |
85 | while (mconsole_get_request(fd, &req)){ | 85 | while (mconsole_get_request(fd, &req)){ |
@@ -91,6 +91,7 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id) | |||
91 | mconsole_reply(&req, "Out of memory", 1, 0); | 91 | mconsole_reply(&req, "Out of memory", 1, 0); |
92 | else { | 92 | else { |
93 | new->request = req; | 93 | new->request = req; |
94 | new->request.regs = get_irq_regs()->regs; | ||
94 | list_add(&new->list, &mc_requests); | 95 | list_add(&new->list, &mc_requests); |
95 | } | 96 | } |
96 | } | 97 | } |
@@ -314,9 +315,21 @@ void mconsole_stop(struct mc_request *req) | |||
314 | { | 315 | { |
315 | deactivate_fd(req->originating_fd, MCONSOLE_IRQ); | 316 | deactivate_fd(req->originating_fd, MCONSOLE_IRQ); |
316 | os_set_fd_block(req->originating_fd, 1); | 317 | os_set_fd_block(req->originating_fd, 1); |
317 | mconsole_reply(req, "", 0, 0); | 318 | mconsole_reply(req, "stopped", 0, 0); |
318 | while(mconsole_get_request(req->originating_fd, req)){ | 319 | while (mconsole_get_request(req->originating_fd, req)) { |
319 | if(req->cmd->handler == mconsole_go) break; | 320 | if (req->cmd->handler == mconsole_go) |
321 | break; | ||
322 | if (req->cmd->handler == mconsole_stop) { | ||
323 | mconsole_reply(req, "Already stopped", 1, 0); | ||
324 | continue; | ||
325 | } | ||
326 | if (req->cmd->handler == mconsole_sysrq) { | ||
327 | struct pt_regs *old_regs; | ||
328 | old_regs = set_irq_regs((struct pt_regs *)&req->regs); | ||
329 | mconsole_sysrq(req); | ||
330 | set_irq_regs(old_regs); | ||
331 | continue; | ||
332 | } | ||
320 | (*req->cmd->handler)(req); | 333 | (*req->cmd->handler)(req); |
321 | } | 334 | } |
322 | os_set_fd_block(req->originating_fd, 0); | 335 | os_set_fd_block(req->originating_fd, 0); |
@@ -673,9 +686,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *), | |||
673 | static void sysrq_proc(void *arg) | 686 | static void sysrq_proc(void *arg) |
674 | { | 687 | { |
675 | char *op = arg; | 688 | char *op = arg; |
676 | struct pt_regs *old_regs = set_irq_regs(¤t->thread.regs); | ||
677 | handle_sysrq(*op, NULL); | 689 | handle_sysrq(*op, NULL); |
678 | set_irq_regs(old_regs); | ||
679 | } | 690 | } |
680 | 691 | ||
681 | void mconsole_sysrq(struct mc_request *req) | 692 | 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 @@ | |||
14 | #include <sys/un.h> | 14 | #include <sys/un.h> |
15 | #include <unistd.h> | 15 | #include <unistd.h> |
16 | #include "user.h" | 16 | #include "user.h" |
17 | #include "sysdep/ptrace.h" | ||
17 | #include "mconsole.h" | 18 | #include "mconsole.h" |
18 | #include "umid.h" | 19 | #include "umid.h" |
19 | #include "user_util.h" | 20 | #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 = { | |||
95 | .release = mmapper_release, | 95 | .release = mmapper_release, |
96 | }; | 96 | }; |
97 | 97 | ||
98 | static const struct miscdevice mmapper_dev = { | 98 | /* No locking needed - only used (and modified) by below initcall and exitcall. */ |
99 | static struct miscdevice mmapper_dev = { | ||
99 | .minor = MISC_DYNAMIC_MINOR, | 100 | .minor = MISC_DYNAMIC_MINOR, |
100 | .name = "mmapper", | 101 | .name = "mmapper", |
101 | .fops = &mmapper_fops | 102 | .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 @@ | |||
18 | #include "kern_util.h" | 18 | #include "kern_util.h" |
19 | #include "net_user.h" | 19 | #include "net_user.h" |
20 | #include "os.h" | 20 | #include "os.h" |
21 | #include "um_malloc.h" | ||
21 | 22 | ||
22 | int tap_open_common(void *dev, char *gate_addr) | 23 | int tap_open_common(void *dev, char *gate_addr) |
23 | { | 24 | { |
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 @@ | |||
12 | #include "net_user.h" | 12 | #include "net_user.h" |
13 | #include "pcap_user.h" | 13 | #include "pcap_user.h" |
14 | #include "user.h" | 14 | #include "user.h" |
15 | #include "um_malloc.h" | ||
15 | 16 | ||
16 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) | 17 | #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) |
17 | 18 | ||
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 @@ | |||
19 | #include "chan_user.h" | 19 | #include "chan_user.h" |
20 | #include "port.h" | 20 | #include "port.h" |
21 | #include "os.h" | 21 | #include "os.h" |
22 | #include "um_malloc.h" | ||
22 | 23 | ||
23 | struct port_chan { | 24 | struct port_chan { |
24 | int raw; | 25 | 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 @@ | |||
13 | #include "user_util.h" | 13 | #include "user_util.h" |
14 | #include "kern_util.h" | 14 | #include "kern_util.h" |
15 | #include "os.h" | 15 | #include "os.h" |
16 | #include "um_malloc.h" | ||
16 | 17 | ||
17 | struct pty_chan { | 18 | struct pty_chan { |
18 | void (*announce)(char *dev_name, int dev); | 19 | 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 @@ | |||
15 | #include "slip.h" | 15 | #include "slip.h" |
16 | #include "slip_common.h" | 16 | #include "slip_common.h" |
17 | #include "os.h" | 17 | #include "os.h" |
18 | #include "um_malloc.h" | ||
18 | 19 | ||
19 | void slip_user_init(void *data, void *dev) | 20 | void slip_user_init(void *data, void *dev) |
20 | { | 21 | { |
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 @@ | |||
11 | #include "user_util.h" | 11 | #include "user_util.h" |
12 | #include "user.h" | 12 | #include "user.h" |
13 | #include "os.h" | 13 | #include "os.h" |
14 | #include "um_malloc.h" | ||
14 | 15 | ||
15 | struct tty_chan { | 16 | struct tty_chan { |
16 | char *dev; | 17 | 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) | |||
106 | 106 | ||
107 | #define DRIVER_NAME "uml-blkdev" | 107 | #define DRIVER_NAME "uml-blkdev" |
108 | 108 | ||
109 | /* Can be taken in interrupt context, and is passed to the block layer to lock | ||
110 | * the request queue. Kernel side code knows that. */ | ||
109 | static DEFINE_SPINLOCK(ubd_io_lock); | 111 | static DEFINE_SPINLOCK(ubd_io_lock); |
110 | static DEFINE_SPINLOCK(ubd_lock); | ||
111 | 112 | ||
112 | static void (*do_ubd)(void); | 113 | static DEFINE_MUTEX(ubd_lock); |
114 | |||
115 | /* XXX - this made sense in 2.4 days, now it's only used as a boolean, and | ||
116 | * probably it doesn't make sense even for that. */ | ||
117 | static int do_ubd; | ||
113 | 118 | ||
114 | static int ubd_open(struct inode * inode, struct file * filp); | 119 | static int ubd_open(struct inode * inode, struct file * filp); |
115 | static int ubd_release(struct inode * inode, struct file * file); | 120 | static int ubd_release(struct inode * inode, struct file * file); |
@@ -117,7 +122,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, | |||
117 | unsigned int cmd, unsigned long arg); | 122 | unsigned int cmd, unsigned long arg); |
118 | static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo); | 123 | static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo); |
119 | 124 | ||
120 | #define MAX_DEV (8) | 125 | #define MAX_DEV (16) |
121 | 126 | ||
122 | static struct block_device_operations ubd_blops = { | 127 | static struct block_device_operations ubd_blops = { |
123 | .owner = THIS_MODULE, | 128 | .owner = THIS_MODULE, |
@@ -150,8 +155,9 @@ static struct gendisk *fake_gendisk[MAX_DEV]; | |||
150 | static struct openflags global_openflags = OPEN_FLAGS; | 155 | static struct openflags global_openflags = OPEN_FLAGS; |
151 | 156 | ||
152 | struct cow { | 157 | struct cow { |
153 | /* This is the backing file, actually */ | 158 | /* backing file name */ |
154 | char *file; | 159 | char *file; |
160 | /* backing file fd */ | ||
155 | int fd; | 161 | int fd; |
156 | unsigned long *bitmap; | 162 | unsigned long *bitmap; |
157 | unsigned long bitmap_len; | 163 | unsigned long bitmap_len; |
@@ -160,14 +166,16 @@ struct cow { | |||
160 | }; | 166 | }; |
161 | 167 | ||
162 | struct ubd { | 168 | struct ubd { |
169 | /* name (and fd, below) of the file opened for writing, either the | ||
170 | * backing or the cow file. */ | ||
163 | char *file; | 171 | char *file; |
164 | int count; | 172 | int count; |
165 | int fd; | 173 | int fd; |
166 | __u64 size; | 174 | __u64 size; |
167 | struct openflags boot_openflags; | 175 | struct openflags boot_openflags; |
168 | struct openflags openflags; | 176 | struct openflags openflags; |
169 | int shared; | 177 | unsigned shared:1; |
170 | int no_cow; | 178 | unsigned no_cow:1; |
171 | struct cow cow; | 179 | struct cow cow; |
172 | struct platform_device pdev; | 180 | struct platform_device pdev; |
173 | }; | 181 | }; |
@@ -192,18 +200,7 @@ struct ubd { | |||
192 | .cow = DEFAULT_COW, \ | 200 | .cow = DEFAULT_COW, \ |
193 | } | 201 | } |
194 | 202 | ||
195 | struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; | 203 | struct ubd ubd_devs[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; |
196 | |||
197 | static int ubd0_init(void) | ||
198 | { | ||
199 | struct ubd *dev = &ubd_dev[0]; | ||
200 | |||
201 | if(dev->file == NULL) | ||
202 | dev->file = "root_fs"; | ||
203 | return(0); | ||
204 | } | ||
205 | |||
206 | __initcall(ubd0_init); | ||
207 | 204 | ||
208 | /* Only changed by fake_ide_setup which is a setup */ | 205 | /* Only changed by fake_ide_setup which is a setup */ |
209 | static int fake_ide = 0; | 206 | static int fake_ide = 0; |
@@ -277,7 +274,7 @@ static int parse_unit(char **ptr) | |||
277 | return(-1); | 274 | return(-1); |
278 | *ptr = end; | 275 | *ptr = end; |
279 | } | 276 | } |
280 | else if (('a' <= *str) && (*str <= 'h')) { | 277 | else if (('a' <= *str) && (*str <= 'z')) { |
281 | n = *str - 'a'; | 278 | n = *str - 'a'; |
282 | str++; | 279 | str++; |
283 | *ptr = str; | 280 | *ptr = str; |
@@ -285,9 +282,13 @@ static int parse_unit(char **ptr) | |||
285 | return(n); | 282 | return(n); |
286 | } | 283 | } |
287 | 284 | ||
285 | /* If *index_out == -1 at exit, the passed option was a general one; | ||
286 | * otherwise, the str pointer is used (and owned) inside ubd_devs array, so it | ||
287 | * should not be freed on exit. | ||
288 | */ | ||
288 | static int ubd_setup_common(char *str, int *index_out) | 289 | static int ubd_setup_common(char *str, int *index_out) |
289 | { | 290 | { |
290 | struct ubd *dev; | 291 | struct ubd *ubd_dev; |
291 | struct openflags flags = global_openflags; | 292 | struct openflags flags = global_openflags; |
292 | char *backing_file; | 293 | char *backing_file; |
293 | int n, err, i; | 294 | int n, err, i; |
@@ -311,7 +312,7 @@ static int ubd_setup_common(char *str, int *index_out) | |||
311 | } | 312 | } |
312 | 313 | ||
313 | err = 1; | 314 | err = 1; |
314 | spin_lock(&ubd_lock); | 315 | mutex_lock(&ubd_lock); |
315 | if(fake_major != MAJOR_NR){ | 316 | if(fake_major != MAJOR_NR){ |
316 | printk(KERN_ERR "Can't assign a fake major twice\n"); | 317 | printk(KERN_ERR "Can't assign a fake major twice\n"); |
317 | goto out1; | 318 | goto out1; |
@@ -323,7 +324,7 @@ static int ubd_setup_common(char *str, int *index_out) | |||
323 | major); | 324 | major); |
324 | err = 0; | 325 | err = 0; |
325 | out1: | 326 | out1: |
326 | spin_unlock(&ubd_lock); | 327 | mutex_unlock(&ubd_lock); |
327 | return(err); | 328 | return(err); |
328 | } | 329 | } |
329 | 330 | ||
@@ -340,10 +341,10 @@ static int ubd_setup_common(char *str, int *index_out) | |||
340 | } | 341 | } |
341 | 342 | ||
342 | err = 1; | 343 | err = 1; |
343 | spin_lock(&ubd_lock); | 344 | mutex_lock(&ubd_lock); |
344 | 345 | ||
345 | dev = &ubd_dev[n]; | 346 | ubd_dev = &ubd_devs[n]; |
346 | if(dev->file != NULL){ | 347 | if(ubd_dev->file != NULL){ |
347 | printk(KERN_ERR "ubd_setup : device already configured\n"); | 348 | printk(KERN_ERR "ubd_setup : device already configured\n"); |
348 | goto out; | 349 | goto out; |
349 | } | 350 | } |
@@ -360,10 +361,10 @@ static int ubd_setup_common(char *str, int *index_out) | |||
360 | flags.s = 1; | 361 | flags.s = 1; |
361 | break; | 362 | break; |
362 | case 'd': | 363 | case 'd': |
363 | dev->no_cow = 1; | 364 | ubd_dev->no_cow = 1; |
364 | break; | 365 | break; |
365 | case 'c': | 366 | case 'c': |
366 | dev->shared = 1; | 367 | ubd_dev->shared = 1; |
367 | break; | 368 | break; |
368 | case '=': | 369 | case '=': |
369 | str++; | 370 | str++; |
@@ -390,7 +391,7 @@ break_loop: | |||
390 | } | 391 | } |
391 | 392 | ||
392 | if(backing_file){ | 393 | if(backing_file){ |
393 | if(dev->no_cow) | 394 | if(ubd_dev->no_cow) |
394 | printk(KERN_ERR "Can't specify both 'd' and a " | 395 | printk(KERN_ERR "Can't specify both 'd' and a " |
395 | "cow file\n"); | 396 | "cow file\n"); |
396 | else { | 397 | else { |
@@ -398,11 +399,11 @@ break_loop: | |||
398 | backing_file++; | 399 | backing_file++; |
399 | } | 400 | } |
400 | } | 401 | } |
401 | dev->file = str; | 402 | ubd_dev->file = str; |
402 | dev->cow.file = backing_file; | 403 | ubd_dev->cow.file = backing_file; |
403 | dev->boot_openflags = flags; | 404 | ubd_dev->boot_openflags = flags; |
404 | out: | 405 | out: |
405 | spin_unlock(&ubd_lock); | 406 | mutex_unlock(&ubd_lock); |
406 | return(err); | 407 | return(err); |
407 | } | 408 | } |
408 | 409 | ||
@@ -472,8 +473,9 @@ int thread_fd = -1; | |||
472 | 473 | ||
473 | /* Changed by ubd_handler, which is serialized because interrupts only | 474 | /* Changed by ubd_handler, which is serialized because interrupts only |
474 | * happen on CPU 0. | 475 | * happen on CPU 0. |
476 | * XXX: currently unused. | ||
475 | */ | 477 | */ |
476 | int intr_count = 0; | 478 | static int intr_count = 0; |
477 | 479 | ||
478 | /* call ubd_finish if you need to serialize */ | 480 | /* call ubd_finish if you need to serialize */ |
479 | static void __ubd_finish(struct request *req, int error) | 481 | static void __ubd_finish(struct request *req, int error) |
@@ -493,6 +495,8 @@ static void __ubd_finish(struct request *req, int error) | |||
493 | end_request(req, 1); | 495 | end_request(req, 1); |
494 | } | 496 | } |
495 | 497 | ||
498 | /* Callable only from interrupt context - otherwise you need to do | ||
499 | * spin_lock_irq()/spin_lock_irqsave() */ | ||
496 | static inline void ubd_finish(struct request *req, int error) | 500 | static inline void ubd_finish(struct request *req, int error) |
497 | { | 501 | { |
498 | spin_lock(&ubd_io_lock); | 502 | spin_lock(&ubd_io_lock); |
@@ -500,14 +504,15 @@ static inline void ubd_finish(struct request *req, int error) | |||
500 | spin_unlock(&ubd_io_lock); | 504 | spin_unlock(&ubd_io_lock); |
501 | } | 505 | } |
502 | 506 | ||
503 | /* Called without ubd_io_lock held */ | 507 | /* XXX - move this inside ubd_intr. */ |
508 | /* Called without ubd_io_lock held, and only in interrupt context. */ | ||
504 | static void ubd_handler(void) | 509 | static void ubd_handler(void) |
505 | { | 510 | { |
506 | struct io_thread_req req; | 511 | struct io_thread_req req; |
507 | struct request *rq = elv_next_request(ubd_queue); | 512 | struct request *rq = elv_next_request(ubd_queue); |
508 | int n; | 513 | int n; |
509 | 514 | ||
510 | do_ubd = NULL; | 515 | do_ubd = 0; |
511 | intr_count++; | 516 | intr_count++; |
512 | n = os_read_file(thread_fd, &req, sizeof(req)); | 517 | n = os_read_file(thread_fd, &req, sizeof(req)); |
513 | if(n != sizeof(req)){ | 518 | if(n != sizeof(req)){ |
@@ -521,7 +526,9 @@ static void ubd_handler(void) | |||
521 | 526 | ||
522 | ubd_finish(rq, req.error); | 527 | ubd_finish(rq, req.error); |
523 | reactivate_fd(thread_fd, UBD_IRQ); | 528 | reactivate_fd(thread_fd, UBD_IRQ); |
529 | spin_lock(&ubd_io_lock); | ||
524 | do_ubd_request(ubd_queue); | 530 | do_ubd_request(ubd_queue); |
531 | spin_unlock(&ubd_io_lock); | ||
525 | } | 532 | } |
526 | 533 | ||
527 | static irqreturn_t ubd_intr(int irq, void *dev) | 534 | static irqreturn_t ubd_intr(int irq, void *dev) |
@@ -541,87 +548,90 @@ void kill_io_thread(void) | |||
541 | 548 | ||
542 | __uml_exitcall(kill_io_thread); | 549 | __uml_exitcall(kill_io_thread); |
543 | 550 | ||
544 | static int ubd_file_size(struct ubd *dev, __u64 *size_out) | 551 | static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out) |
545 | { | 552 | { |
546 | char *file; | 553 | char *file; |
547 | 554 | ||
548 | file = dev->cow.file ? dev->cow.file : dev->file; | 555 | file = ubd_dev->cow.file ? ubd_dev->cow.file : ubd_dev->file; |
549 | return(os_file_size(file, size_out)); | 556 | return(os_file_size(file, size_out)); |
550 | } | 557 | } |
551 | 558 | ||
552 | static void ubd_close(struct ubd *dev) | 559 | static void ubd_close_dev(struct ubd *ubd_dev) |
553 | { | 560 | { |
554 | os_close_file(dev->fd); | 561 | os_close_file(ubd_dev->fd); |
555 | if(dev->cow.file == NULL) | 562 | if(ubd_dev->cow.file == NULL) |
556 | return; | 563 | return; |
557 | 564 | ||
558 | os_close_file(dev->cow.fd); | 565 | os_close_file(ubd_dev->cow.fd); |
559 | vfree(dev->cow.bitmap); | 566 | vfree(ubd_dev->cow.bitmap); |
560 | dev->cow.bitmap = NULL; | 567 | ubd_dev->cow.bitmap = NULL; |
561 | } | 568 | } |
562 | 569 | ||
563 | static int ubd_open_dev(struct ubd *dev) | 570 | static int ubd_open_dev(struct ubd *ubd_dev) |
564 | { | 571 | { |
565 | struct openflags flags; | 572 | struct openflags flags; |
566 | char **back_ptr; | 573 | char **back_ptr; |
567 | int err, create_cow, *create_ptr; | 574 | int err, create_cow, *create_ptr; |
575 | int fd; | ||
568 | 576 | ||
569 | dev->openflags = dev->boot_openflags; | 577 | ubd_dev->openflags = ubd_dev->boot_openflags; |
570 | create_cow = 0; | 578 | create_cow = 0; |
571 | create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; | 579 | create_ptr = (ubd_dev->cow.file != NULL) ? &create_cow : NULL; |
572 | back_ptr = dev->no_cow ? NULL : &dev->cow.file; | 580 | back_ptr = ubd_dev->no_cow ? NULL : &ubd_dev->cow.file; |
573 | dev->fd = open_ubd_file(dev->file, &dev->openflags, dev->shared, | 581 | |
574 | back_ptr, &dev->cow.bitmap_offset, | 582 | fd = open_ubd_file(ubd_dev->file, &ubd_dev->openflags, ubd_dev->shared, |
575 | &dev->cow.bitmap_len, &dev->cow.data_offset, | 583 | back_ptr, &ubd_dev->cow.bitmap_offset, |
584 | &ubd_dev->cow.bitmap_len, &ubd_dev->cow.data_offset, | ||
576 | create_ptr); | 585 | create_ptr); |
577 | 586 | ||
578 | if((dev->fd == -ENOENT) && create_cow){ | 587 | if((fd == -ENOENT) && create_cow){ |
579 | dev->fd = create_cow_file(dev->file, dev->cow.file, | 588 | fd = create_cow_file(ubd_dev->file, ubd_dev->cow.file, |
580 | dev->openflags, 1 << 9, PAGE_SIZE, | 589 | ubd_dev->openflags, 1 << 9, PAGE_SIZE, |
581 | &dev->cow.bitmap_offset, | 590 | &ubd_dev->cow.bitmap_offset, |
582 | &dev->cow.bitmap_len, | 591 | &ubd_dev->cow.bitmap_len, |
583 | &dev->cow.data_offset); | 592 | &ubd_dev->cow.data_offset); |
584 | if(dev->fd >= 0){ | 593 | if(fd >= 0){ |
585 | printk(KERN_INFO "Creating \"%s\" as COW file for " | 594 | printk(KERN_INFO "Creating \"%s\" as COW file for " |
586 | "\"%s\"\n", dev->file, dev->cow.file); | 595 | "\"%s\"\n", ubd_dev->file, ubd_dev->cow.file); |
587 | } | 596 | } |
588 | } | 597 | } |
589 | 598 | ||
590 | if(dev->fd < 0){ | 599 | if(fd < 0){ |
591 | printk("Failed to open '%s', errno = %d\n", dev->file, | 600 | printk("Failed to open '%s', errno = %d\n", ubd_dev->file, |
592 | -dev->fd); | 601 | -fd); |
593 | return(dev->fd); | 602 | return fd; |
594 | } | 603 | } |
604 | ubd_dev->fd = fd; | ||
595 | 605 | ||
596 | if(dev->cow.file != NULL){ | 606 | if(ubd_dev->cow.file != NULL){ |
597 | err = -ENOMEM; | 607 | err = -ENOMEM; |
598 | dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len); | 608 | ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); |
599 | if(dev->cow.bitmap == NULL){ | 609 | if(ubd_dev->cow.bitmap == NULL){ |
600 | printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); | 610 | printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); |
601 | goto error; | 611 | goto error; |
602 | } | 612 | } |
603 | flush_tlb_kernel_vm(); | 613 | flush_tlb_kernel_vm(); |
604 | 614 | ||
605 | err = read_cow_bitmap(dev->fd, dev->cow.bitmap, | 615 | err = read_cow_bitmap(ubd_dev->fd, ubd_dev->cow.bitmap, |
606 | dev->cow.bitmap_offset, | 616 | ubd_dev->cow.bitmap_offset, |
607 | dev->cow.bitmap_len); | 617 | ubd_dev->cow.bitmap_len); |
608 | if(err < 0) | 618 | if(err < 0) |
609 | goto error; | 619 | goto error; |
610 | 620 | ||
611 | flags = dev->openflags; | 621 | flags = ubd_dev->openflags; |
612 | flags.w = 0; | 622 | flags.w = 0; |
613 | err = open_ubd_file(dev->cow.file, &flags, dev->shared, NULL, | 623 | err = open_ubd_file(ubd_dev->cow.file, &flags, ubd_dev->shared, NULL, |
614 | NULL, NULL, NULL, NULL); | 624 | NULL, NULL, NULL, NULL); |
615 | if(err < 0) goto error; | 625 | if(err < 0) goto error; |
616 | dev->cow.fd = err; | 626 | ubd_dev->cow.fd = err; |
617 | } | 627 | } |
618 | return(0); | 628 | return(0); |
619 | error: | 629 | error: |
620 | os_close_file(dev->fd); | 630 | os_close_file(ubd_dev->fd); |
621 | return(err); | 631 | return(err); |
622 | } | 632 | } |
623 | 633 | ||
624 | static int ubd_new_disk(int major, u64 size, int unit, | 634 | static int ubd_disk_register(int major, u64 size, int unit, |
625 | struct gendisk **disk_out) | 635 | struct gendisk **disk_out) |
626 | 636 | ||
627 | { | 637 | { |
@@ -642,13 +652,13 @@ static int ubd_new_disk(int major, u64 size, int unit, | |||
642 | 652 | ||
643 | /* sysfs register (not for ide fake devices) */ | 653 | /* sysfs register (not for ide fake devices) */ |
644 | if (major == MAJOR_NR) { | 654 | if (major == MAJOR_NR) { |
645 | ubd_dev[unit].pdev.id = unit; | 655 | ubd_devs[unit].pdev.id = unit; |
646 | ubd_dev[unit].pdev.name = DRIVER_NAME; | 656 | ubd_devs[unit].pdev.name = DRIVER_NAME; |
647 | platform_device_register(&ubd_dev[unit].pdev); | 657 | platform_device_register(&ubd_devs[unit].pdev); |
648 | disk->driverfs_dev = &ubd_dev[unit].pdev.dev; | 658 | disk->driverfs_dev = &ubd_devs[unit].pdev.dev; |
649 | } | 659 | } |
650 | 660 | ||
651 | disk->private_data = &ubd_dev[unit]; | 661 | disk->private_data = &ubd_devs[unit]; |
652 | disk->queue = ubd_queue; | 662 | disk->queue = ubd_queue; |
653 | add_disk(disk); | 663 | add_disk(disk); |
654 | 664 | ||
@@ -660,25 +670,25 @@ static int ubd_new_disk(int major, u64 size, int unit, | |||
660 | 670 | ||
661 | static int ubd_add(int n) | 671 | static int ubd_add(int n) |
662 | { | 672 | { |
663 | struct ubd *dev = &ubd_dev[n]; | 673 | struct ubd *ubd_dev = &ubd_devs[n]; |
664 | int err; | 674 | int err; |
665 | 675 | ||
666 | err = -ENODEV; | 676 | err = -ENODEV; |
667 | if(dev->file == NULL) | 677 | if(ubd_dev->file == NULL) |
668 | goto out; | 678 | goto out; |
669 | 679 | ||
670 | err = ubd_file_size(dev, &dev->size); | 680 | err = ubd_file_size(ubd_dev, &ubd_dev->size); |
671 | if(err < 0) | 681 | if(err < 0) |
672 | goto out; | 682 | goto out; |
673 | 683 | ||
674 | dev->size = ROUND_BLOCK(dev->size); | 684 | ubd_dev->size = ROUND_BLOCK(ubd_dev->size); |
675 | 685 | ||
676 | err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]); | 686 | err = ubd_disk_register(MAJOR_NR, ubd_dev->size, n, &ubd_gendisk[n]); |
677 | if(err) | 687 | if(err) |
678 | goto out; | 688 | goto out; |
679 | 689 | ||
680 | if(fake_major != MAJOR_NR) | 690 | if(fake_major != MAJOR_NR) |
681 | ubd_new_disk(fake_major, dev->size, n, | 691 | ubd_disk_register(fake_major, ubd_dev->size, n, |
682 | &fake_gendisk[n]); | 692 | &fake_gendisk[n]); |
683 | 693 | ||
684 | /* perhaps this should also be under the "if (fake_major)" above */ | 694 | /* perhaps this should also be under the "if (fake_major)" above */ |
@@ -693,32 +703,41 @@ out: | |||
693 | 703 | ||
694 | static int ubd_config(char *str) | 704 | static int ubd_config(char *str) |
695 | { | 705 | { |
696 | int n, err; | 706 | int n, ret; |
697 | 707 | ||
698 | str = kstrdup(str, GFP_KERNEL); | 708 | str = kstrdup(str, GFP_KERNEL); |
699 | if(str == NULL){ | 709 | if (str == NULL) { |
700 | printk(KERN_ERR "ubd_config failed to strdup string\n"); | 710 | printk(KERN_ERR "ubd_config failed to strdup string\n"); |
701 | return(1); | 711 | ret = 1; |
712 | goto out; | ||
702 | } | 713 | } |
703 | err = ubd_setup_common(str, &n); | 714 | ret = ubd_setup_common(str, &n); |
704 | if(err){ | 715 | if (ret) { |
705 | kfree(str); | 716 | ret = -1; |
706 | return(-1); | 717 | goto err_free; |
718 | } | ||
719 | if (n == -1) { | ||
720 | ret = 0; | ||
721 | goto err_free; | ||
707 | } | 722 | } |
708 | if(n == -1) return(0); | ||
709 | 723 | ||
710 | spin_lock(&ubd_lock); | 724 | mutex_lock(&ubd_lock); |
711 | err = ubd_add(n); | 725 | ret = ubd_add(n); |
712 | if(err) | 726 | if (ret) |
713 | ubd_dev[n].file = NULL; | 727 | ubd_devs[n].file = NULL; |
714 | spin_unlock(&ubd_lock); | 728 | mutex_unlock(&ubd_lock); |
715 | 729 | ||
716 | return(err); | 730 | out: |
731 | return ret; | ||
732 | |||
733 | err_free: | ||
734 | kfree(str); | ||
735 | goto out; | ||
717 | } | 736 | } |
718 | 737 | ||
719 | static int ubd_get_config(char *name, char *str, int size, char **error_out) | 738 | static int ubd_get_config(char *name, char *str, int size, char **error_out) |
720 | { | 739 | { |
721 | struct ubd *dev; | 740 | struct ubd *ubd_dev; |
722 | int n, len = 0; | 741 | int n, len = 0; |
723 | 742 | ||
724 | n = parse_unit(&name); | 743 | n = parse_unit(&name); |
@@ -727,24 +746,24 @@ static int ubd_get_config(char *name, char *str, int size, char **error_out) | |||
727 | return(-1); | 746 | return(-1); |
728 | } | 747 | } |
729 | 748 | ||
730 | dev = &ubd_dev[n]; | 749 | ubd_dev = &ubd_devs[n]; |
731 | spin_lock(&ubd_lock); | 750 | mutex_lock(&ubd_lock); |
732 | 751 | ||
733 | if(dev->file == NULL){ | 752 | if(ubd_dev->file == NULL){ |
734 | CONFIG_CHUNK(str, size, len, "", 1); | 753 | CONFIG_CHUNK(str, size, len, "", 1); |
735 | goto out; | 754 | goto out; |
736 | } | 755 | } |
737 | 756 | ||
738 | CONFIG_CHUNK(str, size, len, dev->file, 0); | 757 | CONFIG_CHUNK(str, size, len, ubd_dev->file, 0); |
739 | 758 | ||
740 | if(dev->cow.file != NULL){ | 759 | if(ubd_dev->cow.file != NULL){ |
741 | CONFIG_CHUNK(str, size, len, ",", 0); | 760 | CONFIG_CHUNK(str, size, len, ",", 0); |
742 | CONFIG_CHUNK(str, size, len, dev->cow.file, 1); | 761 | CONFIG_CHUNK(str, size, len, ubd_dev->cow.file, 1); |
743 | } | 762 | } |
744 | else CONFIG_CHUNK(str, size, len, "", 1); | 763 | else CONFIG_CHUNK(str, size, len, "", 1); |
745 | 764 | ||
746 | out: | 765 | out: |
747 | spin_unlock(&ubd_lock); | 766 | mutex_unlock(&ubd_lock); |
748 | return(len); | 767 | return(len); |
749 | } | 768 | } |
750 | 769 | ||
@@ -760,22 +779,22 @@ static int ubd_id(char **str, int *start_out, int *end_out) | |||
760 | 779 | ||
761 | static int ubd_remove(int n) | 780 | static int ubd_remove(int n) |
762 | { | 781 | { |
763 | struct ubd *dev; | 782 | struct ubd *ubd_dev; |
764 | int err = -ENODEV; | 783 | int err = -ENODEV; |
765 | 784 | ||
766 | spin_lock(&ubd_lock); | 785 | mutex_lock(&ubd_lock); |
767 | 786 | ||
768 | if(ubd_gendisk[n] == NULL) | 787 | if(ubd_gendisk[n] == NULL) |
769 | goto out; | 788 | goto out; |
770 | 789 | ||
771 | dev = &ubd_dev[n]; | 790 | ubd_dev = &ubd_devs[n]; |
772 | 791 | ||
773 | if(dev->file == NULL) | 792 | if(ubd_dev->file == NULL) |
774 | goto out; | 793 | goto out; |
775 | 794 | ||
776 | /* you cannot remove a open disk */ | 795 | /* you cannot remove a open disk */ |
777 | err = -EBUSY; | 796 | err = -EBUSY; |
778 | if(dev->count > 0) | 797 | if(ubd_dev->count > 0) |
779 | goto out; | 798 | goto out; |
780 | 799 | ||
781 | del_gendisk(ubd_gendisk[n]); | 800 | del_gendisk(ubd_gendisk[n]); |
@@ -788,14 +807,15 @@ static int ubd_remove(int n) | |||
788 | fake_gendisk[n] = NULL; | 807 | fake_gendisk[n] = NULL; |
789 | } | 808 | } |
790 | 809 | ||
791 | platform_device_unregister(&dev->pdev); | 810 | platform_device_unregister(&ubd_dev->pdev); |
792 | *dev = ((struct ubd) DEFAULT_UBD); | 811 | *ubd_dev = ((struct ubd) DEFAULT_UBD); |
793 | err = 0; | 812 | err = 0; |
794 | out: | 813 | out: |
795 | spin_unlock(&ubd_lock); | 814 | mutex_unlock(&ubd_lock); |
796 | return err; | 815 | return err; |
797 | } | 816 | } |
798 | 817 | ||
818 | /* All these are called by mconsole in process context and without ubd-specific locks. */ | ||
799 | static struct mc_device ubd_mc = { | 819 | static struct mc_device ubd_mc = { |
800 | .name = "ubd", | 820 | .name = "ubd", |
801 | .config = ubd_config, | 821 | .config = ubd_config, |
@@ -804,7 +824,7 @@ static struct mc_device ubd_mc = { | |||
804 | .remove = ubd_remove, | 824 | .remove = ubd_remove, |
805 | }; | 825 | }; |
806 | 826 | ||
807 | static int ubd_mc_init(void) | 827 | static int __init ubd_mc_init(void) |
808 | { | 828 | { |
809 | mconsole_register_dev(&ubd_mc); | 829 | mconsole_register_dev(&ubd_mc); |
810 | return 0; | 830 | return 0; |
@@ -812,13 +832,24 @@ static int ubd_mc_init(void) | |||
812 | 832 | ||
813 | __initcall(ubd_mc_init); | 833 | __initcall(ubd_mc_init); |
814 | 834 | ||
835 | static int __init ubd0_init(void) | ||
836 | { | ||
837 | struct ubd *ubd_dev = &ubd_devs[0]; | ||
838 | |||
839 | if(ubd_dev->file == NULL) | ||
840 | ubd_dev->file = "root_fs"; | ||
841 | return(0); | ||
842 | } | ||
843 | |||
844 | __initcall(ubd0_init); | ||
845 | |||
815 | static struct platform_driver ubd_driver = { | 846 | static struct platform_driver ubd_driver = { |
816 | .driver = { | 847 | .driver = { |
817 | .name = DRIVER_NAME, | 848 | .name = DRIVER_NAME, |
818 | }, | 849 | }, |
819 | }; | 850 | }; |
820 | 851 | ||
821 | int ubd_init(void) | 852 | static int __init ubd_init(void) |
822 | { | 853 | { |
823 | int i; | 854 | int i; |
824 | 855 | ||
@@ -846,7 +877,7 @@ int ubd_init(void) | |||
846 | 877 | ||
847 | late_initcall(ubd_init); | 878 | late_initcall(ubd_init); |
848 | 879 | ||
849 | int ubd_driver_init(void){ | 880 | static int __init ubd_driver_init(void){ |
850 | unsigned long stack; | 881 | unsigned long stack; |
851 | int err; | 882 | int err; |
852 | 883 | ||
@@ -867,7 +898,7 @@ int ubd_driver_init(void){ | |||
867 | return(0); | 898 | return(0); |
868 | } | 899 | } |
869 | err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, | 900 | err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, |
870 | IRQF_DISABLED, "ubd", ubd_dev); | 901 | IRQF_DISABLED, "ubd", ubd_devs); |
871 | if(err != 0) | 902 | if(err != 0) |
872 | printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); | 903 | printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err); |
873 | return 0; | 904 | return 0; |
@@ -878,24 +909,24 @@ device_initcall(ubd_driver_init); | |||
878 | static int ubd_open(struct inode *inode, struct file *filp) | 909 | static int ubd_open(struct inode *inode, struct file *filp) |
879 | { | 910 | { |
880 | struct gendisk *disk = inode->i_bdev->bd_disk; | 911 | struct gendisk *disk = inode->i_bdev->bd_disk; |
881 | struct ubd *dev = disk->private_data; | 912 | struct ubd *ubd_dev = disk->private_data; |
882 | int err = 0; | 913 | int err = 0; |
883 | 914 | ||
884 | if(dev->count == 0){ | 915 | if(ubd_dev->count == 0){ |
885 | err = ubd_open_dev(dev); | 916 | err = ubd_open_dev(ubd_dev); |
886 | if(err){ | 917 | if(err){ |
887 | printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n", | 918 | printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n", |
888 | disk->disk_name, dev->file, -err); | 919 | disk->disk_name, ubd_dev->file, -err); |
889 | goto out; | 920 | goto out; |
890 | } | 921 | } |
891 | } | 922 | } |
892 | dev->count++; | 923 | ubd_dev->count++; |
893 | set_disk_ro(disk, !dev->openflags.w); | 924 | set_disk_ro(disk, !ubd_dev->openflags.w); |
894 | 925 | ||
895 | /* This should no more be needed. And it didn't work anyway to exclude | 926 | /* This should no more be needed. And it didn't work anyway to exclude |
896 | * read-write remounting of filesystems.*/ | 927 | * read-write remounting of filesystems.*/ |
897 | /*if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ | 928 | /*if((filp->f_mode & FMODE_WRITE) && !ubd_dev->openflags.w){ |
898 | if(--dev->count == 0) ubd_close(dev); | 929 | if(--ubd_dev->count == 0) ubd_close_dev(ubd_dev); |
899 | err = -EROFS; | 930 | err = -EROFS; |
900 | }*/ | 931 | }*/ |
901 | out: | 932 | out: |
@@ -905,10 +936,10 @@ static int ubd_open(struct inode *inode, struct file *filp) | |||
905 | static int ubd_release(struct inode * inode, struct file * file) | 936 | static int ubd_release(struct inode * inode, struct file * file) |
906 | { | 937 | { |
907 | struct gendisk *disk = inode->i_bdev->bd_disk; | 938 | struct gendisk *disk = inode->i_bdev->bd_disk; |
908 | struct ubd *dev = disk->private_data; | 939 | struct ubd *ubd_dev = disk->private_data; |
909 | 940 | ||
910 | if(--dev->count == 0) | 941 | if(--ubd_dev->count == 0) |
911 | ubd_close(dev); | 942 | ubd_close_dev(ubd_dev); |
912 | return(0); | 943 | return(0); |
913 | } | 944 | } |
914 | 945 | ||
@@ -976,12 +1007,12 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, | |||
976 | static int prepare_request(struct request *req, struct io_thread_req *io_req) | 1007 | static int prepare_request(struct request *req, struct io_thread_req *io_req) |
977 | { | 1008 | { |
978 | struct gendisk *disk = req->rq_disk; | 1009 | struct gendisk *disk = req->rq_disk; |
979 | struct ubd *dev = disk->private_data; | 1010 | struct ubd *ubd_dev = disk->private_data; |
980 | __u64 offset; | 1011 | __u64 offset; |
981 | int len; | 1012 | int len; |
982 | 1013 | ||
983 | /* This should be impossible now */ | 1014 | /* This should be impossible now */ |
984 | if((rq_data_dir(req) == WRITE) && !dev->openflags.w){ | 1015 | if((rq_data_dir(req) == WRITE) && !ubd_dev->openflags.w){ |
985 | printk("Write attempted on readonly ubd device %s\n", | 1016 | printk("Write attempted on readonly ubd device %s\n", |
986 | disk->disk_name); | 1017 | disk->disk_name); |
987 | end_request(req, 0); | 1018 | end_request(req, 0); |
@@ -991,8 +1022,8 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) | |||
991 | offset = ((__u64) req->sector) << 9; | 1022 | offset = ((__u64) req->sector) << 9; |
992 | len = req->current_nr_sectors << 9; | 1023 | len = req->current_nr_sectors << 9; |
993 | 1024 | ||
994 | io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; | 1025 | io_req->fds[0] = (ubd_dev->cow.file != NULL) ? ubd_dev->cow.fd : ubd_dev->fd; |
995 | io_req->fds[1] = dev->fd; | 1026 | io_req->fds[1] = ubd_dev->fd; |
996 | io_req->cow_offset = -1; | 1027 | io_req->cow_offset = -1; |
997 | io_req->offset = offset; | 1028 | io_req->offset = offset; |
998 | io_req->length = len; | 1029 | io_req->length = len; |
@@ -1001,13 +1032,13 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) | |||
1001 | 1032 | ||
1002 | io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; | 1033 | io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; |
1003 | io_req->offsets[0] = 0; | 1034 | io_req->offsets[0] = 0; |
1004 | io_req->offsets[1] = dev->cow.data_offset; | 1035 | io_req->offsets[1] = ubd_dev->cow.data_offset; |
1005 | io_req->buffer = req->buffer; | 1036 | io_req->buffer = req->buffer; |
1006 | io_req->sectorsize = 1 << 9; | 1037 | io_req->sectorsize = 1 << 9; |
1007 | 1038 | ||
1008 | if(dev->cow.file != NULL) | 1039 | if(ubd_dev->cow.file != NULL) |
1009 | cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset, | 1040 | cowify_req(io_req, ubd_dev->cow.bitmap, ubd_dev->cow.bitmap_offset, |
1010 | dev->cow.bitmap_len); | 1041 | ubd_dev->cow.bitmap_len); |
1011 | 1042 | ||
1012 | return(0); | 1043 | return(0); |
1013 | } | 1044 | } |
@@ -1033,7 +1064,7 @@ static void do_ubd_request(request_queue_t *q) | |||
1033 | return; | 1064 | return; |
1034 | err = prepare_request(req, &io_req); | 1065 | err = prepare_request(req, &io_req); |
1035 | if(!err){ | 1066 | if(!err){ |
1036 | do_ubd = ubd_handler; | 1067 | do_ubd = 1; |
1037 | n = os_write_file(thread_fd, (char *) &io_req, | 1068 | n = os_write_file(thread_fd, (char *) &io_req, |
1038 | sizeof(io_req)); | 1069 | sizeof(io_req)); |
1039 | if(n != sizeof(io_req)) | 1070 | if(n != sizeof(io_req)) |
@@ -1045,18 +1076,18 @@ static void do_ubd_request(request_queue_t *q) | |||
1045 | 1076 | ||
1046 | static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo) | 1077 | static int ubd_getgeo(struct block_device *bdev, struct hd_geometry *geo) |
1047 | { | 1078 | { |
1048 | struct ubd *dev = bdev->bd_disk->private_data; | 1079 | struct ubd *ubd_dev = bdev->bd_disk->private_data; |
1049 | 1080 | ||
1050 | geo->heads = 128; | 1081 | geo->heads = 128; |
1051 | geo->sectors = 32; | 1082 | geo->sectors = 32; |
1052 | geo->cylinders = dev->size / (128 * 32 * 512); | 1083 | geo->cylinders = ubd_dev->size / (128 * 32 * 512); |
1053 | return 0; | 1084 | return 0; |
1054 | } | 1085 | } |
1055 | 1086 | ||
1056 | static int ubd_ioctl(struct inode * inode, struct file * file, | 1087 | static int ubd_ioctl(struct inode * inode, struct file * file, |
1057 | unsigned int cmd, unsigned long arg) | 1088 | unsigned int cmd, unsigned long arg) |
1058 | { | 1089 | { |
1059 | struct ubd *dev = inode->i_bdev->bd_disk->private_data; | 1090 | struct ubd *ubd_dev = inode->i_bdev->bd_disk->private_data; |
1060 | struct hd_driveid ubd_id = { | 1091 | struct hd_driveid ubd_id = { |
1061 | .cyls = 0, | 1092 | .cyls = 0, |
1062 | .heads = 128, | 1093 | .heads = 128, |
@@ -1066,7 +1097,7 @@ static int ubd_ioctl(struct inode * inode, struct file * file, | |||
1066 | switch (cmd) { | 1097 | switch (cmd) { |
1067 | struct cdrom_volctrl volume; | 1098 | struct cdrom_volctrl volume; |
1068 | case HDIO_GET_IDENTITY: | 1099 | case HDIO_GET_IDENTITY: |
1069 | ubd_id.cyls = dev->size / (128 * 32 * 512); | 1100 | ubd_id.cyls = ubd_dev->size / (128 * 32 * 512); |
1070 | if(copy_to_user((char __user *) arg, (char *) &ubd_id, | 1101 | if(copy_to_user((char __user *) arg, (char *) &ubd_id, |
1071 | sizeof(ubd_id))) | 1102 | sizeof(ubd_id))) |
1072 | return(-EFAULT); | 1103 | return(-EFAULT); |
@@ -1353,8 +1384,8 @@ void do_io(struct io_thread_req *req) | |||
1353 | */ | 1384 | */ |
1354 | int kernel_fd = -1; | 1385 | int kernel_fd = -1; |
1355 | 1386 | ||
1356 | /* Only changed by the io thread */ | 1387 | /* Only changed by the io thread. XXX: currently unused. */ |
1357 | int io_count = 0; | 1388 | static int io_count = 0; |
1358 | 1389 | ||
1359 | int io_thread(void *arg) | 1390 | int io_thread(void *arg) |
1360 | { | 1391 | { |
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, | |||
136 | return(pid); | 136 | return(pid); |
137 | } | 137 | } |
138 | 138 | ||
139 | if(data->stack == 0) free_stack(stack, 0); | ||
140 | |||
141 | if (data->direct_rcv) { | 139 | if (data->direct_rcv) { |
142 | new = os_rcv_fd(fd, &data->helper_pid); | 140 | new = os_rcv_fd(fd, &data->helper_pid); |
143 | } else { | 141 | } else { |
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 | |||
61 | 61 | ||
62 | struct mconsole_request request; | 62 | struct mconsole_request request; |
63 | struct mconsole_command *cmd; | 63 | struct mconsole_command *cmd; |
64 | union uml_pt_regs regs; | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | extern char mconsole_socket_name[]; | 67 | 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 { | |||
14 | struct mc_request request; | 14 | struct mc_request request; |
15 | }; | 15 | }; |
16 | 16 | ||
17 | /* All these methods are called in process context. */ | ||
17 | struct mc_device { | 18 | struct mc_device { |
18 | struct list_head list; | 19 | struct list_head list; |
19 | char *name; | 20 | char *name; |
diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 6516f6dca96..13a86bd383d 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h | |||
@@ -233,6 +233,8 @@ extern unsigned long __do_user_copy(void *to, const void *from, int n, | |||
233 | void (*op)(void *to, const void *from, | 233 | void (*op)(void *to, const void *from, |
234 | int n), int *faulted_out); | 234 | int n), int *faulted_out); |
235 | 235 | ||
236 | /* execvp.c */ | ||
237 | extern int execvp_noalloc(char *buf, const char *file, char *const argv[]); | ||
236 | /* helper.c */ | 238 | /* helper.c */ |
237 | extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | 239 | extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, |
238 | unsigned long *stack_out); | 240 | unsigned long *stack_out); |
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 @@ | |||
1 | #ifndef __SYSDEP_I386_BARRIER_H | ||
2 | #define __SYSDEP_I386_BARRIER_H | ||
3 | |||
4 | /* Copied from include/asm-i386 for use by userspace. i386 has the option | ||
5 | * of using mfence, but I'm just using this, which works everywhere, for now. | ||
6 | */ | ||
7 | #define mb() asm volatile("lock; addl $0,0(%esp)") | ||
8 | |||
9 | #endif | ||
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h index 052bb061a97..0cb4645cbeb 100644 --- a/arch/um/include/sysdep-i386/checksum.h +++ b/arch/um/include/sysdep-i386/checksum.h | |||
@@ -20,8 +20,7 @@ | |||
20 | * | 20 | * |
21 | * it's best to have buff aligned on a 32-bit boundary | 21 | * it's best to have buff aligned on a 32-bit boundary |
22 | */ | 22 | */ |
23 | unsigned int csum_partial(const unsigned char * buff, int len, | 23 | __wsum csum_partial(const void *buff, int len, __wsum sum); |
24 | unsigned int sum); | ||
25 | 24 | ||
26 | /* | 25 | /* |
27 | * Note: when you get a NULL pointer exception here this means someone | 26 | * Note: when you get a NULL pointer exception here this means someone |
@@ -32,8 +31,8 @@ unsigned int csum_partial(const unsigned char * buff, int len, | |||
32 | */ | 31 | */ |
33 | 32 | ||
34 | static __inline__ | 33 | static __inline__ |
35 | unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, | 34 | __wsum csum_partial_copy_nocheck(const void *src, void *dst, |
36 | int len, int sum) | 35 | int len, __wsum sum) |
37 | { | 36 | { |
38 | memcpy(dst, src, len); | 37 | memcpy(dst, src, len); |
39 | return csum_partial(dst, len, sum); | 38 | return csum_partial(dst, len, sum); |
@@ -48,36 +47,25 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
48 | */ | 47 | */ |
49 | 48 | ||
50 | static __inline__ | 49 | static __inline__ |
51 | unsigned int csum_partial_copy_from_user(const unsigned char __user *src, | 50 | __wsum csum_partial_copy_from_user(const void __user *src, void *dst, |
52 | unsigned char *dst, | 51 | int len, __wsum sum, int *err_ptr) |
53 | int len, int sum, int *err_ptr) | ||
54 | { | 52 | { |
55 | if(copy_from_user(dst, src, len)){ | 53 | if (copy_from_user(dst, src, len)) { |
56 | *err_ptr = -EFAULT; | 54 | *err_ptr = -EFAULT; |
57 | return(-1); | 55 | return (__force __wsum)-1; |
58 | } | 56 | } |
59 | 57 | ||
60 | return csum_partial(dst, len, sum); | 58 | return csum_partial(dst, len, sum); |
61 | } | 59 | } |
62 | 60 | ||
63 | /* | 61 | /* |
64 | * These are the old (and unsafe) way of doing checksums, a warning message | ||
65 | * will be printed if they are used and an exception occurs. | ||
66 | * | ||
67 | * these functions should go away after some time. | ||
68 | */ | ||
69 | |||
70 | #define csum_partial_copy_fromuser csum_partial_copy_from_user | ||
71 | |||
72 | /* | ||
73 | * This is a version of ip_compute_csum() optimized for IP headers, | 62 | * This is a version of ip_compute_csum() optimized for IP headers, |
74 | * which always checksum on 4 octet boundaries. | 63 | * which always checksum on 4 octet boundaries. |
75 | * | 64 | * |
76 | * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by | 65 | * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by |
77 | * Arnt Gulbrandsen. | 66 | * Arnt Gulbrandsen. |
78 | */ | 67 | */ |
79 | static inline unsigned short ip_fast_csum(unsigned char * iph, | 68 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) |
80 | unsigned int ihl) | ||
81 | { | 69 | { |
82 | unsigned int sum; | 70 | unsigned int sum; |
83 | 71 | ||
@@ -105,29 +93,29 @@ static inline unsigned short ip_fast_csum(unsigned char * iph, | |||
105 | : "=r" (sum), "=r" (iph), "=r" (ihl) | 93 | : "=r" (sum), "=r" (iph), "=r" (ihl) |
106 | : "1" (iph), "2" (ihl) | 94 | : "1" (iph), "2" (ihl) |
107 | : "memory"); | 95 | : "memory"); |
108 | return sum; | 96 | return (__force __sum16)sum; |
109 | } | 97 | } |
110 | 98 | ||
111 | /* | 99 | /* |
112 | * Fold a partial checksum | 100 | * Fold a partial checksum |
113 | */ | 101 | */ |
114 | 102 | ||
115 | static inline unsigned int csum_fold(unsigned int sum) | 103 | static inline __sum16 csum_fold(__wsum sum) |
116 | { | 104 | { |
117 | __asm__( | 105 | __asm__( |
118 | "addl %1, %0 ;\n" | 106 | "addl %1, %0 ;\n" |
119 | "adcl $0xffff, %0 ;\n" | 107 | "adcl $0xffff, %0 ;\n" |
120 | : "=r" (sum) | 108 | : "=r" (sum) |
121 | : "r" (sum << 16), "0" (sum & 0xffff0000) | 109 | : "r" ((__force u32)sum << 16), |
110 | "0" ((__force u32)sum & 0xffff0000) | ||
122 | ); | 111 | ); |
123 | return (~sum) >> 16; | 112 | return (__force __sum16)(~(__force u32)sum >> 16); |
124 | } | 113 | } |
125 | 114 | ||
126 | static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, | 115 | static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, |
127 | unsigned long daddr, | ||
128 | unsigned short len, | 116 | unsigned short len, |
129 | unsigned short proto, | 117 | unsigned short proto, |
130 | unsigned int sum) | 118 | __wsum sum) |
131 | { | 119 | { |
132 | __asm__( | 120 | __asm__( |
133 | "addl %1, %0 ;\n" | 121 | "addl %1, %0 ;\n" |
@@ -135,7 +123,7 @@ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, | |||
135 | "adcl %3, %0 ;\n" | 123 | "adcl %3, %0 ;\n" |
136 | "adcl $0, %0 ;\n" | 124 | "adcl $0, %0 ;\n" |
137 | : "=r" (sum) | 125 | : "=r" (sum) |
138 | : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum)); | 126 | : "g" (daddr), "g"(saddr), "g"((len + proto) << 8), "0"(sum)); |
139 | return sum; | 127 | return sum; |
140 | } | 128 | } |
141 | 129 | ||
@@ -143,11 +131,10 @@ static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, | |||
143 | * computes the checksum of the TCP/UDP pseudo-header | 131 | * computes the checksum of the TCP/UDP pseudo-header |
144 | * returns a 16-bit checksum, already complemented | 132 | * returns a 16-bit checksum, already complemented |
145 | */ | 133 | */ |
146 | static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, | 134 | static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, |
147 | unsigned long daddr, | ||
148 | unsigned short len, | 135 | unsigned short len, |
149 | unsigned short proto, | 136 | unsigned short proto, |
150 | unsigned int sum) | 137 | __wsum sum) |
151 | { | 138 | { |
152 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); | 139 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); |
153 | } | 140 | } |
@@ -157,17 +144,16 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, | |||
157 | * in icmp.c | 144 | * in icmp.c |
158 | */ | 145 | */ |
159 | 146 | ||
160 | static inline unsigned short ip_compute_csum(unsigned char * buff, int len) | 147 | static inline __sum16 ip_compute_csum(const void *buff, int len) |
161 | { | 148 | { |
162 | return csum_fold (csum_partial(buff, len, 0)); | 149 | return csum_fold (csum_partial(buff, len, 0)); |
163 | } | 150 | } |
164 | 151 | ||
165 | #define _HAVE_ARCH_IPV6_CSUM | 152 | #define _HAVE_ARCH_IPV6_CSUM |
166 | static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, | 153 | static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, |
167 | struct in6_addr *daddr, | 154 | const struct in6_addr *daddr, |
168 | __u32 len, | 155 | __u32 len, unsigned short proto, |
169 | unsigned short proto, | 156 | __wsum sum) |
170 | unsigned int sum) | ||
171 | { | 157 | { |
172 | __asm__( | 158 | __asm__( |
173 | "addl 0(%1), %0 ;\n" | 159 | "addl 0(%1), %0 ;\n" |
@@ -192,14 +178,14 @@ static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, | |||
192 | * Copy and checksum to user | 178 | * Copy and checksum to user |
193 | */ | 179 | */ |
194 | #define HAVE_CSUM_COPY_USER | 180 | #define HAVE_CSUM_COPY_USER |
195 | static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, | 181 | static __inline__ __wsum csum_and_copy_to_user(const void *src, |
196 | unsigned char __user *dst, | 182 | void __user *dst, |
197 | int len, int sum, int *err_ptr) | 183 | int len, __wsum sum, int *err_ptr) |
198 | { | 184 | { |
199 | if (access_ok(VERIFY_WRITE, dst, len)){ | 185 | if (access_ok(VERIFY_WRITE, dst, len)) { |
200 | if(copy_to_user(dst, src, len)){ | 186 | if (copy_to_user(dst, src, len)) { |
201 | *err_ptr = -EFAULT; | 187 | *err_ptr = -EFAULT; |
202 | return(-1); | 188 | return (__force __wsum)-1; |
203 | } | 189 | } |
204 | 190 | ||
205 | return csum_partial(src, len, sum); | 191 | return csum_partial(src, len, sum); |
@@ -208,7 +194,7 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, | |||
208 | if (len) | 194 | if (len) |
209 | *err_ptr = -EFAULT; | 195 | *err_ptr = -EFAULT; |
210 | 196 | ||
211 | return -1; /* invalid checksum */ | 197 | return (__force __wsum)-1; /* invalid checksum */ |
212 | } | 198 | } |
213 | 199 | ||
214 | #endif | 200 | #endif |
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 @@ | |||
1 | #ifndef __SYSDEP_X86_64_BARRIER_H | ||
2 | #define __SYSDEP_X86_64_BARRIER_H | ||
3 | |||
4 | /* Copied from include/asm-x86_64 for use by userspace. */ | ||
5 | #define mb() asm volatile("mfence":::"memory") | ||
6 | |||
7 | #endif | ||
diff --git a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h index ea97005af69..a5be9031ea8 100644 --- a/arch/um/include/sysdep-x86_64/checksum.h +++ b/arch/um/include/sysdep-x86_64/checksum.h | |||
@@ -9,8 +9,7 @@ | |||
9 | #include "linux/in6.h" | 9 | #include "linux/in6.h" |
10 | #include "asm/uaccess.h" | 10 | #include "asm/uaccess.h" |
11 | 11 | ||
12 | extern unsigned csum_partial(const unsigned char *buff, unsigned len, | 12 | extern __wsum csum_partial(const void *buff, int len, __wsum sum); |
13 | unsigned sum); | ||
14 | 13 | ||
15 | /* | 14 | /* |
16 | * Note: when you get a NULL pointer exception here this means someone | 15 | * Note: when you get a NULL pointer exception here this means someone |
@@ -21,21 +20,21 @@ extern unsigned csum_partial(const unsigned char *buff, unsigned len, | |||
21 | */ | 20 | */ |
22 | 21 | ||
23 | static __inline__ | 22 | static __inline__ |
24 | unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, | 23 | __wsum csum_partial_copy_nocheck(const void *src, void *dst, |
25 | int len, int sum) | 24 | int len, __wsum sum) |
26 | { | 25 | { |
27 | memcpy(dst, src, len); | 26 | memcpy(dst, src, len); |
28 | return(csum_partial(dst, len, sum)); | 27 | return(csum_partial(dst, len, sum)); |
29 | } | 28 | } |
30 | 29 | ||
31 | static __inline__ | 30 | static __inline__ |
32 | unsigned int csum_partial_copy_from_user(const unsigned char *src, | 31 | __wsum csum_partial_copy_from_user(const void __user *src, |
33 | unsigned char *dst, int len, int sum, | 32 | void *dst, int len, __wsum sum, |
34 | int *err_ptr) | 33 | int *err_ptr) |
35 | { | 34 | { |
36 | if(copy_from_user(dst, src, len)){ | 35 | if (copy_from_user(dst, src, len)) { |
37 | *err_ptr = -EFAULT; | 36 | *err_ptr = -EFAULT; |
38 | return(-1); | 37 | return (__force __wsum)-1; |
39 | } | 38 | } |
40 | return csum_partial(dst, len, sum); | 39 | return csum_partial(dst, len, sum); |
41 | } | 40 | } |
@@ -48,15 +47,16 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, | |||
48 | * the last step before putting a checksum into a packet. | 47 | * the last step before putting a checksum into a packet. |
49 | * Make sure not to mix with 64bit checksums. | 48 | * Make sure not to mix with 64bit checksums. |
50 | */ | 49 | */ |
51 | static inline unsigned int csum_fold(unsigned int sum) | 50 | static inline __sum16 csum_fold(__wsum sum) |
52 | { | 51 | { |
53 | __asm__( | 52 | __asm__( |
54 | " addl %1,%0\n" | 53 | " addl %1,%0\n" |
55 | " adcl $0xffff,%0" | 54 | " adcl $0xffff,%0" |
56 | : "=r" (sum) | 55 | : "=r" (sum) |
57 | : "r" (sum << 16), "0" (sum & 0xffff0000) | 56 | : "r" ((__force u32)sum << 16), |
57 | "0" ((__force u32)sum & 0xffff0000) | ||
58 | ); | 58 | ); |
59 | return (~sum) >> 16; | 59 | return (__force __sum16)(~(__force u32)sum >> 16); |
60 | } | 60 | } |
61 | 61 | ||
62 | /** | 62 | /** |
@@ -70,28 +70,27 @@ static inline unsigned int csum_fold(unsigned int sum) | |||
70 | * Returns the pseudo header checksum the input data. Result is | 70 | * Returns the pseudo header checksum the input data. Result is |
71 | * 32bit unfolded. | 71 | * 32bit unfolded. |
72 | */ | 72 | */ |
73 | static inline unsigned long | 73 | static inline __wsum |
74 | csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len, | 74 | csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, |
75 | unsigned short proto, unsigned int sum) | 75 | unsigned short proto, __wsum sum) |
76 | { | 76 | { |
77 | asm(" addl %1, %0\n" | 77 | asm(" addl %1, %0\n" |
78 | " adcl %2, %0\n" | 78 | " adcl %2, %0\n" |
79 | " adcl %3, %0\n" | 79 | " adcl %3, %0\n" |
80 | " adcl $0, %0\n" | 80 | " adcl $0, %0\n" |
81 | : "=r" (sum) | 81 | : "=r" (sum) |
82 | : "g" (daddr), "g" (saddr), "g" ((ntohs(len)<<16)+proto*256), "0" (sum)); | 82 | : "g" (daddr), "g" (saddr), "g" ((len + proto) << 8), "0" (sum)); |
83 | return sum; | 83 | return sum; |
84 | } | 84 | } |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * computes the checksum of the TCP/UDP pseudo-header | 87 | * computes the checksum of the TCP/UDP pseudo-header |
88 | * returns a 16-bit checksum, already complemented | 88 | * returns a 16-bit checksum, already complemented |
89 | */ | 89 | */ |
90 | static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, | 90 | static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, |
91 | unsigned long daddr, | 91 | unsigned short len, |
92 | unsigned short len, | 92 | unsigned short proto, |
93 | unsigned short proto, | 93 | __wsum sum) |
94 | unsigned int sum) | ||
95 | { | 94 | { |
96 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); | 95 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); |
97 | } | 96 | } |
@@ -101,7 +100,7 @@ static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, | |||
101 | * iph: ipv4 header | 100 | * iph: ipv4 header |
102 | * ihl: length of header / 4 | 101 | * ihl: length of header / 4 |
103 | */ | 102 | */ |
104 | static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) | 103 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) |
105 | { | 104 | { |
106 | unsigned int sum; | 105 | unsigned int sum; |
107 | 106 | ||
@@ -128,7 +127,7 @@ static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) | |||
128 | : "=r" (sum), "=r" (iph), "=r" (ihl) | 127 | : "=r" (sum), "=r" (iph), "=r" (ihl) |
129 | : "1" (iph), "2" (ihl) | 128 | : "1" (iph), "2" (ihl) |
130 | : "memory"); | 129 | : "memory"); |
131 | return(sum); | 130 | return (__force __sum16)sum; |
132 | } | 131 | } |
133 | 132 | ||
134 | static inline unsigned add32_with_carry(unsigned a, unsigned b) | 133 | static inline unsigned add32_with_carry(unsigned a, unsigned b) |
@@ -140,6 +139,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b) | |||
140 | return a; | 139 | return a; |
141 | } | 140 | } |
142 | 141 | ||
143 | extern unsigned short ip_compute_csum(unsigned char * buff, int len); | 142 | extern __sum16 ip_compute_csum(const void *buff, int len); |
144 | 143 | ||
145 | #endif | 144 | #endif |
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 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __UM_MALLOC_H__ | ||
7 | #define __UM_MALLOC_H__ | ||
8 | |||
9 | extern void *um_kmalloc(int size); | ||
10 | extern void *um_kmalloc_atomic(int size); | ||
11 | extern void kfree(const void *ptr); | ||
12 | |||
13 | extern void *um_vmalloc(int size); | ||
14 | extern void *um_vmalloc_atomic(int size); | ||
15 | extern void vfree(void *ptr); | ||
16 | |||
17 | #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, ...) | |||
11 | extern int printk(const char *fmt, ...) | 11 | extern int printk(const char *fmt, ...) |
12 | __attribute__ ((format (printf, 1, 2))); | 12 | __attribute__ ((format (printf, 1, 2))); |
13 | extern void schedule(void); | 13 | extern void schedule(void); |
14 | extern void *um_kmalloc(int size); | ||
15 | extern void *um_kmalloc_atomic(int size); | ||
16 | extern void kfree(void *ptr); | ||
17 | extern int in_aton(char *str); | 14 | extern int in_aton(char *str); |
18 | extern int open_gdb_chan(void); | 15 | extern int open_gdb_chan(void); |
19 | /* These use size_t, however unsigned long is correct on both i386 and x86_64. */ | 16 | /* These use size_t, however unsigned long is correct on both i386 and x86_64. */ |
20 | extern unsigned long strlcpy(char *, const char *, unsigned long); | 17 | extern unsigned long strlcpy(char *, const char *, unsigned long); |
21 | extern unsigned long strlcat(char *, const char *, unsigned long); | 18 | extern unsigned long strlcat(char *, const char *, unsigned long); |
22 | extern void *um_vmalloc(int size); | ||
23 | extern void *um_vmalloc_atomic(int size); | ||
24 | extern void vfree(void *ptr); | ||
25 | 19 | ||
26 | #endif | 20 | #endif |
27 | 21 | ||
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); | |||
52 | extern void set_cmdline(char *cmd); | 52 | extern void set_cmdline(char *cmd); |
53 | extern void input_cb(void (*proc)(void *), void *arg, int arg_len); | 53 | extern void input_cb(void (*proc)(void *), void *arg, int arg_len); |
54 | extern int get_pty(void); | 54 | extern int get_pty(void); |
55 | extern void *um_kmalloc(int size); | ||
56 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); | 55 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); |
57 | extern void do_exec(int old_pid, int new_pid); | 56 | extern void do_exec(int old_pid, int new_pid); |
58 | extern void tracer_panic(char *msg, ...) | 57 | 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 | |||
14 | * is remapped.*/ | 14 | * is remapped.*/ |
15 | __binary_start = .; | 15 | __binary_start = .; |
16 | . = ALIGN(4096); /* Init code and data */ | 16 | . = ALIGN(4096); /* Init code and data */ |
17 | _text = .; | ||
17 | _stext = .; | 18 | _stext = .; |
18 | __init_begin = .; | 19 | __init_begin = .; |
19 | .init.text : { | 20 | .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 @@ | |||
31 | #include "irq_kern.h" | 31 | #include "irq_kern.h" |
32 | #include "os.h" | 32 | #include "os.h" |
33 | #include "sigio.h" | 33 | #include "sigio.h" |
34 | #include "um_malloc.h" | ||
34 | #include "misc_constants.h" | 35 | #include "misc_constants.h" |
35 | 36 | ||
36 | /* | 37 | /* |
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 @@ | |||
46 | #include "mode.h" | 46 | #include "mode.h" |
47 | #include "mode_kern.h" | 47 | #include "mode_kern.h" |
48 | #include "choose-mode.h" | 48 | #include "choose-mode.h" |
49 | #include "um_malloc.h" | ||
49 | 50 | ||
50 | /* This is a per-cpu array. A processor only modifies its entry and it only | 51 | /* This is a per-cpu array. A processor only modifies its entry and it only |
51 | * cares about its entry, so it's OK if another processor is modifying its | 52 | * cares about its entry, so it's OK if another processor is modifying its |
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 { | |||
176 | int signal_index[32]; | 176 | int signal_index[32]; |
177 | int nsignals = 0; | 177 | int nsignals = 0; |
178 | int debug_trace = 0; | 178 | int debug_trace = 0; |
179 | extern int io_nsignals, io_count, intr_count; | ||
180 | 179 | ||
181 | extern void signal_usr1(int sig); | 180 | extern void signal_usr1(int sig); |
182 | 181 | ||
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 | |||
25 | . = ALIGN(4096); /* Init code and data */ | 25 | . = ALIGN(4096); /* Init code and data */ |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | _text = .; | ||
28 | _stext = .; | 29 | _stext = .; |
29 | __init_begin = .; | 30 | __init_begin = .; |
30 | .init.text : { | 31 | .init.text : { |
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile index b4183929b32..2f8c7946401 100644 --- a/arch/um/os-Linux/Makefile +++ b/arch/um/os-Linux/Makefile | |||
@@ -3,8 +3,8 @@ | |||
3 | # Licensed under the GPL | 3 | # Licensed under the GPL |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y = aio.o elf_aux.o file.o helper.o irq.o main.o mem.o process.o sigio.o \ | 6 | obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ |
7 | signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ | 7 | sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ |
8 | user_syms.o util.o drivers/ sys-$(SUBARCH)/ | 8 | user_syms.o util.o drivers/ sys-$(SUBARCH)/ |
9 | 9 | ||
10 | obj-$(CONFIG_MODE_SKAS) += skas/ | 10 | obj-$(CONFIG_MODE_SKAS) += skas/ |
@@ -15,9 +15,9 @@ user-objs-$(CONFIG_MODE_TT) += tt.o | |||
15 | obj-$(CONFIG_TTY_LOG) += tty_log.o | 15 | obj-$(CONFIG_TTY_LOG) += tty_log.o |
16 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 16 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o |
17 | 17 | ||
18 | USER_OBJS := $(user-objs-y) aio.o elf_aux.o file.o helper.o irq.o main.o mem.o \ | 18 | USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ |
19 | process.o sigio.o signal.o start_up.o time.o trap.o tty.o tls.o \ | 19 | main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \ |
20 | uaccess.o umid.o util.o | 20 | tls.o uaccess.o umid.o util.o |
21 | 21 | ||
22 | CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) | 22 | CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) |
23 | 23 | ||
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 @@ | |||
20 | #include "net_user.h" | 20 | #include "net_user.h" |
21 | #include "etap.h" | 21 | #include "etap.h" |
22 | #include "os.h" | 22 | #include "os.h" |
23 | #include "um_malloc.h" | ||
23 | 24 | ||
24 | #define MAX_PACKET ETH_MAX_PACKET | 25 | #define MAX_PACKET ETH_MAX_PACKET |
25 | 26 | ||
diff --git a/arch/um/os-Linux/execvp.c b/arch/um/os-Linux/execvp.c new file mode 100644 index 00000000000..66e583a4031 --- /dev/null +++ b/arch/um/os-Linux/execvp.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* Copyright (C) 2006 by Paolo Giarrusso - modified from glibc' execvp.c. | ||
2 | Original copyright notice follows: | ||
3 | |||
4 | Copyright (C) 1991,92,1995-99,2002,2004 Free Software Foundation, Inc. | ||
5 | This file is part of the GNU C Library. | ||
6 | |||
7 | The GNU C Library is free software; you can redistribute it and/or | ||
8 | modify it under the terms of the GNU Lesser General Public | ||
9 | License as published by the Free Software Foundation; either | ||
10 | version 2.1 of the License, or (at your option) any later version. | ||
11 | |||
12 | The GNU C Library is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | Lesser General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU Lesser General Public | ||
18 | License along with the GNU C Library; if not, write to the Free | ||
19 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
20 | 02111-1307 USA. */ | ||
21 | #include <unistd.h> | ||
22 | |||
23 | #include <stdbool.h> | ||
24 | #include <stdlib.h> | ||
25 | #include <string.h> | ||
26 | #include <errno.h> | ||
27 | #include <limits.h> | ||
28 | |||
29 | #ifndef TEST | ||
30 | #include "um_malloc.h" | ||
31 | #else | ||
32 | #include <stdio.h> | ||
33 | #define um_kmalloc malloc | ||
34 | #endif | ||
35 | #include "os.h" | ||
36 | |||
37 | /* Execute FILE, searching in the `PATH' environment variable if it contains | ||
38 | no slashes, with arguments ARGV and environment from `environ'. */ | ||
39 | int execvp_noalloc(char *buf, const char *file, char *const argv[]) | ||
40 | { | ||
41 | if (*file == '\0') { | ||
42 | return -ENOENT; | ||
43 | } | ||
44 | |||
45 | if (strchr (file, '/') != NULL) { | ||
46 | /* Don't search when it contains a slash. */ | ||
47 | execv(file, argv); | ||
48 | } else { | ||
49 | int got_eacces; | ||
50 | size_t len, pathlen; | ||
51 | char *name, *p; | ||
52 | char *path = getenv("PATH"); | ||
53 | if (path == NULL) | ||
54 | path = ":/bin:/usr/bin"; | ||
55 | |||
56 | len = strlen(file) + 1; | ||
57 | pathlen = strlen(path); | ||
58 | /* Copy the file name at the top. */ | ||
59 | name = memcpy(buf + pathlen + 1, file, len); | ||
60 | /* And add the slash. */ | ||
61 | *--name = '/'; | ||
62 | |||
63 | got_eacces = 0; | ||
64 | p = path; | ||
65 | do { | ||
66 | char *startp; | ||
67 | |||
68 | path = p; | ||
69 | //Let's avoid this GNU extension. | ||
70 | //p = strchrnul (path, ':'); | ||
71 | p = strchr(path, ':'); | ||
72 | if (!p) | ||
73 | p = strchr(path, '\0'); | ||
74 | |||
75 | if (p == path) | ||
76 | /* Two adjacent colons, or a colon at the beginning or the end | ||
77 | of `PATH' means to search the current directory. */ | ||
78 | startp = name + 1; | ||
79 | else | ||
80 | startp = memcpy(name - (p - path), path, p - path); | ||
81 | |||
82 | /* Try to execute this name. If it works, execv will not return. */ | ||
83 | execv(startp, argv); | ||
84 | |||
85 | /* | ||
86 | if (errno == ENOEXEC) { | ||
87 | } | ||
88 | */ | ||
89 | |||
90 | switch (errno) { | ||
91 | case EACCES: | ||
92 | /* Record the we got a `Permission denied' error. If we end | ||
93 | up finding no executable we can use, we want to diagnose | ||
94 | that we did find one but were denied access. */ | ||
95 | got_eacces = 1; | ||
96 | case ENOENT: | ||
97 | case ESTALE: | ||
98 | case ENOTDIR: | ||
99 | /* Those errors indicate the file is missing or not executable | ||
100 | by us, in which case we want to just try the next path | ||
101 | directory. */ | ||
102 | case ENODEV: | ||
103 | case ETIMEDOUT: | ||
104 | /* Some strange filesystems like AFS return even | ||
105 | stranger error numbers. They cannot reasonably mean | ||
106 | anything else so ignore those, too. */ | ||
107 | case ENOEXEC: | ||
108 | /* We won't go searching for the shell | ||
109 | * if it is not executable - the Linux | ||
110 | * kernel already handles this enough, | ||
111 | * for us. */ | ||
112 | break; | ||
113 | |||
114 | default: | ||
115 | /* Some other error means we found an executable file, but | ||
116 | something went wrong executing it; return the error to our | ||
117 | caller. */ | ||
118 | return -errno; | ||
119 | } | ||
120 | } while (*p++ != '\0'); | ||
121 | |||
122 | /* We tried every element and none of them worked. */ | ||
123 | if (got_eacces) | ||
124 | /* At least one failure was due to permissions, so report that | ||
125 | error. */ | ||
126 | return -EACCES; | ||
127 | } | ||
128 | |||
129 | /* Return the error from the last attempt (probably ENOENT). */ | ||
130 | return -errno; | ||
131 | } | ||
132 | #ifdef TEST | ||
133 | int main(int argc, char**argv) | ||
134 | { | ||
135 | char buf[PATH_MAX]; | ||
136 | int ret; | ||
137 | argc--; | ||
138 | if (!argc) { | ||
139 | fprintf(stderr, "Not enough arguments\n"); | ||
140 | return 1; | ||
141 | } | ||
142 | argv++; | ||
143 | if (ret = execvp_noalloc(buf, argv[0], argv)) { | ||
144 | errno = -ret; | ||
145 | perror("execvp_noalloc"); | ||
146 | } | ||
147 | return 0; | ||
148 | } | ||
149 | #endif | ||
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c index cd15b9df5b5..c7ad6306e22 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c | |||
@@ -8,18 +8,21 @@ | |||
8 | #include <unistd.h> | 8 | #include <unistd.h> |
9 | #include <errno.h> | 9 | #include <errno.h> |
10 | #include <sched.h> | 10 | #include <sched.h> |
11 | #include <limits.h> | ||
11 | #include <sys/signal.h> | 12 | #include <sys/signal.h> |
12 | #include <sys/wait.h> | 13 | #include <sys/wait.h> |
13 | #include "user.h" | 14 | #include "user.h" |
14 | #include "kern_util.h" | 15 | #include "kern_util.h" |
15 | #include "user_util.h" | 16 | #include "user_util.h" |
16 | #include "os.h" | 17 | #include "os.h" |
18 | #include "um_malloc.h" | ||
17 | 19 | ||
18 | struct helper_data { | 20 | struct helper_data { |
19 | void (*pre_exec)(void*); | 21 | void (*pre_exec)(void*); |
20 | void *pre_data; | 22 | void *pre_data; |
21 | char **argv; | 23 | char **argv; |
22 | int fd; | 24 | int fd; |
25 | char *buf; | ||
23 | }; | 26 | }; |
24 | 27 | ||
25 | /* Debugging aid, changed only from gdb */ | 28 | /* Debugging aid, changed only from gdb */ |
@@ -35,22 +38,22 @@ static int helper_child(void *arg) | |||
35 | char **argv = data->argv; | 38 | char **argv = data->argv; |
36 | int errval; | 39 | int errval; |
37 | 40 | ||
38 | if(helper_pause){ | 41 | if (helper_pause){ |
39 | signal(SIGHUP, helper_hup); | 42 | signal(SIGHUP, helper_hup); |
40 | pause(); | 43 | pause(); |
41 | } | 44 | } |
42 | if(data->pre_exec != NULL) | 45 | if (data->pre_exec != NULL) |
43 | (*data->pre_exec)(data->pre_data); | 46 | (*data->pre_exec)(data->pre_data); |
44 | execvp(argv[0], argv); | 47 | errval = execvp_noalloc(data->buf, argv[0], argv); |
45 | errval = -errno; | 48 | printk("helper_child - execvp of '%s' failed - errno = %d\n", argv[0], -errval); |
46 | printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); | ||
47 | os_write_file(data->fd, &errval, sizeof(errval)); | 49 | os_write_file(data->fd, &errval, sizeof(errval)); |
48 | kill(os_getpid(), SIGKILL); | 50 | kill(os_getpid(), SIGKILL); |
49 | return(0); | 51 | return 0; |
50 | } | 52 | } |
51 | 53 | ||
52 | /* Returns either the pid of the child process we run or -E* on failure. | 54 | /* Returns either the pid of the child process we run or -E* on failure. |
53 | * XXX The alloc_stack here breaks if this is called in the tracing thread */ | 55 | * XXX The alloc_stack here breaks if this is called in the tracing thread, so |
56 | * we need to receive a preallocated stack (a local buffer is ok). */ | ||
54 | int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | 57 | int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, |
55 | unsigned long *stack_out) | 58 | unsigned long *stack_out) |
56 | { | 59 | { |
@@ -58,20 +61,21 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
58 | unsigned long stack, sp; | 61 | unsigned long stack, sp; |
59 | int pid, fds[2], ret, n; | 62 | int pid, fds[2], ret, n; |
60 | 63 | ||
61 | if((stack_out != NULL) && (*stack_out != 0)) | 64 | if ((stack_out != NULL) && (*stack_out != 0)) |
62 | stack = *stack_out; | 65 | stack = *stack_out; |
63 | else stack = alloc_stack(0, __cant_sleep()); | 66 | else |
64 | if(stack == 0) | 67 | stack = alloc_stack(0, __cant_sleep()); |
68 | if (stack == 0) | ||
65 | return -ENOMEM; | 69 | return -ENOMEM; |
66 | 70 | ||
67 | ret = os_pipe(fds, 1, 0); | 71 | ret = os_pipe(fds, 1, 0); |
68 | if(ret < 0){ | 72 | if (ret < 0) { |
69 | printk("run_helper : pipe failed, ret = %d\n", -ret); | 73 | printk("run_helper : pipe failed, ret = %d\n", -ret); |
70 | goto out_free; | 74 | goto out_free; |
71 | } | 75 | } |
72 | 76 | ||
73 | ret = os_set_exec_close(fds[1], 1); | 77 | ret = os_set_exec_close(fds[1], 1); |
74 | if(ret < 0){ | 78 | if (ret < 0) { |
75 | printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", | 79 | printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", |
76 | -ret); | 80 | -ret); |
77 | goto out_close; | 81 | goto out_close; |
@@ -82,11 +86,13 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
82 | data.pre_data = pre_data; | 86 | data.pre_data = pre_data; |
83 | data.argv = argv; | 87 | data.argv = argv; |
84 | data.fd = fds[1]; | 88 | data.fd = fds[1]; |
89 | data.buf = __cant_sleep() ? um_kmalloc_atomic(PATH_MAX) : | ||
90 | um_kmalloc(PATH_MAX); | ||
85 | pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); | 91 | pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); |
86 | if(pid < 0){ | 92 | if (pid < 0) { |
87 | ret = -errno; | 93 | ret = -errno; |
88 | printk("run_helper : clone failed, errno = %d\n", errno); | 94 | printk("run_helper : clone failed, errno = %d\n", errno); |
89 | goto out_close; | 95 | goto out_free2; |
90 | } | 96 | } |
91 | 97 | ||
92 | close(fds[1]); | 98 | close(fds[1]); |
@@ -95,10 +101,10 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
95 | /* Read the errno value from the child, if the exec failed, or get 0 if | 101 | /* Read the errno value from the child, if the exec failed, or get 0 if |
96 | * the exec succeeded because the pipe fd was set as close-on-exec. */ | 102 | * the exec succeeded because the pipe fd was set as close-on-exec. */ |
97 | n = os_read_file(fds[0], &ret, sizeof(ret)); | 103 | n = os_read_file(fds[0], &ret, sizeof(ret)); |
98 | if(n == 0) | 104 | if (n == 0) { |
99 | ret = pid; | 105 | ret = pid; |
100 | else { | 106 | } else { |
101 | if(n < 0){ | 107 | if (n < 0) { |
102 | printk("run_helper : read on pipe failed, ret = %d\n", | 108 | printk("run_helper : read on pipe failed, ret = %d\n", |
103 | -n); | 109 | -n); |
104 | ret = n; | 110 | ret = n; |
@@ -107,15 +113,16 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
107 | CATCH_EINTR(waitpid(pid, NULL, 0)); | 113 | CATCH_EINTR(waitpid(pid, NULL, 0)); |
108 | } | 114 | } |
109 | 115 | ||
116 | out_free2: | ||
117 | kfree(data.buf); | ||
110 | out_close: | 118 | out_close: |
111 | if (fds[1] != -1) | 119 | if (fds[1] != -1) |
112 | close(fds[1]); | 120 | close(fds[1]); |
113 | close(fds[0]); | 121 | close(fds[0]); |
114 | out_free: | 122 | out_free: |
115 | if(stack_out == NULL) | 123 | if ((stack_out == NULL) || (*stack_out == 0)) |
116 | free_stack(stack, 0); | 124 | free_stack(stack, 0); |
117 | else *stack_out = stack; | 125 | return ret; |
118 | return(ret); | ||
119 | } | 126 | } |
120 | 127 | ||
121 | int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, | 128 | int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, |
@@ -125,31 +132,32 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, | |||
125 | int pid, status, err; | 132 | int pid, status, err; |
126 | 133 | ||
127 | stack = alloc_stack(stack_order, __cant_sleep()); | 134 | stack = alloc_stack(stack_order, __cant_sleep()); |
128 | if(stack == 0) return(-ENOMEM); | 135 | if (stack == 0) |
136 | return -ENOMEM; | ||
129 | 137 | ||
130 | sp = stack + (page_size() << stack_order) - sizeof(void *); | 138 | sp = stack + (page_size() << stack_order) - sizeof(void *); |
131 | pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); | 139 | pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); |
132 | if(pid < 0){ | 140 | if (pid < 0) { |
133 | err = -errno; | 141 | err = -errno; |
134 | printk("run_helper_thread : clone failed, errno = %d\n", | 142 | printk("run_helper_thread : clone failed, errno = %d\n", |
135 | errno); | 143 | errno); |
136 | return err; | 144 | return err; |
137 | } | 145 | } |
138 | if(stack_out == NULL){ | 146 | if (stack_out == NULL) { |
139 | CATCH_EINTR(pid = waitpid(pid, &status, 0)); | 147 | CATCH_EINTR(pid = waitpid(pid, &status, 0)); |
140 | if(pid < 0){ | 148 | if (pid < 0) { |
141 | err = -errno; | 149 | err = -errno; |
142 | printk("run_helper_thread - wait failed, errno = %d\n", | 150 | printk("run_helper_thread - wait failed, errno = %d\n", |
143 | errno); | 151 | errno); |
144 | pid = err; | 152 | pid = err; |
145 | } | 153 | } |
146 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) | 154 | if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) |
147 | printk("run_helper_thread - thread returned status " | 155 | printk("run_helper_thread - thread returned status " |
148 | "0x%x\n", status); | 156 | "0x%x\n", status); |
149 | free_stack(stack, stack_order); | 157 | free_stack(stack, stack_order); |
150 | } | 158 | } else |
151 | else *stack_out = stack; | 159 | *stack_out = stack; |
152 | return(pid); | 160 | return pid; |
153 | } | 161 | } |
154 | 162 | ||
155 | int helper_wait(int pid) | 163 | int helper_wait(int pid) |
@@ -157,9 +165,9 @@ int helper_wait(int pid) | |||
157 | int ret; | 165 | int ret; |
158 | 166 | ||
159 | CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); | 167 | CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); |
160 | if(ret < 0){ | 168 | if (ret < 0) { |
161 | ret = -errno; | 169 | ret = -errno; |
162 | printk("helper_wait : waitpid failed, errno = %d\n", errno); | 170 | printk("helper_wait : waitpid failed, errno = %d\n", errno); |
163 | } | 171 | } |
164 | return(ret); | 172 | return ret; |
165 | } | 173 | } |
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 @@ | |||
18 | #include "sigio.h" | 18 | #include "sigio.h" |
19 | #include "irq_user.h" | 19 | #include "irq_user.h" |
20 | #include "os.h" | 20 | #include "os.h" |
21 | #include "um_malloc.h" | ||
21 | 22 | ||
22 | static struct pollfd *pollfds = NULL; | 23 | static struct pollfd *pollfds = NULL; |
23 | static int pollfds_num = 0; | 24 | 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 @@ | |||
23 | #include "choose-mode.h" | 23 | #include "choose-mode.h" |
24 | #include "uml-config.h" | 24 | #include "uml-config.h" |
25 | #include "os.h" | 25 | #include "os.h" |
26 | #include "um_malloc.h" | ||
26 | 27 | ||
27 | /* Set in set_stklim, which is called from main and __wrap_malloc. | 28 | /* Set in set_stklim, which is called from main and __wrap_malloc. |
28 | * __wrap_malloc only calls it if main hasn't started. | 29 | * __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 @@ | |||
7 | #include <stdio.h> | 7 | #include <stdio.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <signal.h> | 9 | #include <signal.h> |
10 | #include <linux/unistd.h> | ||
11 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
12 | #include <sys/wait.h> | 11 | #include <sys/wait.h> |
13 | #include <sys/mman.h> | 12 | #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 @@ | |||
19 | #include "user_util.h" | 19 | #include "user_util.h" |
20 | #include "sigio.h" | 20 | #include "sigio.h" |
21 | #include "os.h" | 21 | #include "os.h" |
22 | #include "um_malloc.h" | ||
22 | 23 | ||
23 | /* Protected by sigio_lock(), also used by sigio_cleanup, which is an | 24 | /* Protected by sigio_lock(), also used by sigio_cleanup, which is an |
24 | * exitcall. | 25 | * 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 @@ | |||
15 | #include "user.h" | 15 | #include "user.h" |
16 | #include "signal_kern.h" | 16 | #include "signal_kern.h" |
17 | #include "sysdep/sigcontext.h" | 17 | #include "sysdep/sigcontext.h" |
18 | #include "sysdep/barrier.h" | ||
18 | #include "sigcontext.h" | 19 | #include "sigcontext.h" |
19 | #include "mode.h" | 20 | #include "mode.h" |
20 | #include "os.h" | 21 | #include "os.h" |
@@ -34,8 +35,12 @@ | |||
34 | #define SIGALRM_BIT 2 | 35 | #define SIGALRM_BIT 2 |
35 | #define SIGALRM_MASK (1 << SIGALRM_BIT) | 36 | #define SIGALRM_MASK (1 << SIGALRM_BIT) |
36 | 37 | ||
37 | static int signals_enabled = 1; | 38 | /* These are used by both the signal handlers and |
38 | static int pending = 0; | 39 | * block/unblock_signals. I don't want modifications cached in a |
40 | * register - they must go straight to memory. | ||
41 | */ | ||
42 | static volatile int signals_enabled = 1; | ||
43 | static volatile int pending = 0; | ||
39 | 44 | ||
40 | void sig_handler(int sig, struct sigcontext *sc) | 45 | void sig_handler(int sig, struct sigcontext *sc) |
41 | { | 46 | { |
@@ -152,6 +157,12 @@ int change_sig(int signal, int on) | |||
152 | void block_signals(void) | 157 | void block_signals(void) |
153 | { | 158 | { |
154 | signals_enabled = 0; | 159 | signals_enabled = 0; |
160 | /* This must return with signals disabled, so this barrier | ||
161 | * ensures that writes are flushed out before the return. | ||
162 | * This might matter if gcc figures out how to inline this and | ||
163 | * decides to shuffle this code into the caller. | ||
164 | */ | ||
165 | mb(); | ||
155 | } | 166 | } |
156 | 167 | ||
157 | void unblock_signals(void) | 168 | void unblock_signals(void) |
@@ -171,9 +182,23 @@ void unblock_signals(void) | |||
171 | */ | 182 | */ |
172 | signals_enabled = 1; | 183 | signals_enabled = 1; |
173 | 184 | ||
185 | /* Setting signals_enabled and reading pending must | ||
186 | * happen in this order. | ||
187 | */ | ||
188 | mb(); | ||
189 | |||
174 | save_pending = pending; | 190 | save_pending = pending; |
175 | if(save_pending == 0) | 191 | if(save_pending == 0){ |
192 | /* This must return with signals enabled, so | ||
193 | * this barrier ensures that writes are | ||
194 | * flushed out before the return. This might | ||
195 | * matter if gcc figures out how to inline | ||
196 | * this (unlikely, given its size) and decides | ||
197 | * to shuffle this code into the caller. | ||
198 | */ | ||
199 | mb(); | ||
176 | return; | 200 | return; |
201 | } | ||
177 | 202 | ||
178 | pending = 0; | 203 | pending = 0; |
179 | 204 | ||
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 @@ | |||
14 | #include <sys/mman.h> | 14 | #include <sys/mman.h> |
15 | #include <sys/user.h> | 15 | #include <sys/user.h> |
16 | #include <sys/time.h> | 16 | #include <sys/time.h> |
17 | #include <asm/unistd.h> | 17 | #include <sys/syscall.h> |
18 | #include <asm/types.h> | 18 | #include <asm/types.h> |
19 | #include "user.h" | 19 | #include "user.h" |
20 | #include "sysdep/ptrace.h" | 20 | #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 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <linux/unistd.h> | 2 | #include <linux/unistd.h> |
3 | |||
3 | #include <sys/syscall.h> | 4 | #include <sys/syscall.h> |
5 | #include <unistd.h> | ||
6 | |||
4 | #include "sysdep/tls.h" | 7 | #include "sysdep/tls.h" |
5 | #include "user_util.h" | 8 | #include "user_util.h" |
6 | 9 | ||
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 @@ | |||
16 | #include "process.h" | 16 | #include "process.h" |
17 | #include "kern_constants.h" | 17 | #include "kern_constants.h" |
18 | #include "os.h" | 18 | #include "os.h" |
19 | #include "uml-config.h" | ||
19 | 20 | ||
20 | int set_interval(int is_virtual) | 21 | int set_interval(int is_virtual) |
21 | { | 22 | { |
@@ -30,7 +31,7 @@ int set_interval(int is_virtual) | |||
30 | return 0; | 31 | return 0; |
31 | } | 32 | } |
32 | 33 | ||
33 | #ifdef CONFIG_MODE_TT | 34 | #ifdef UML_CONFIG_MODE_TT |
34 | void enable_timer(void) | 35 | void enable_timer(void) |
35 | { | 36 | { |
36 | set_interval(1); | 37 | 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 @@ | |||
1 | #include <errno.h> | 1 | #include <errno.h> |
2 | #include <unistd.h> | ||
2 | #include <sys/ptrace.h> | 3 | #include <sys/ptrace.h> |
3 | #include <sys/syscall.h> | 4 | #include <sys/syscall.h> |
4 | #include <asm/ldt.h> | 5 | #include <asm/ldt.h> |
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 @@ | |||
5 | 5 | ||
6 | #include <linux/mman.h> | 6 | #include <linux/mman.h> |
7 | #include <asm/unistd.h> | 7 | #include <asm/unistd.h> |
8 | #include <sys/syscall.h> | ||
9 | 8 | ||
9 | static int errno; | ||
10 | |||
11 | static inline _syscall2(int,munmap,void *,start,size_t,len) | ||
12 | static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) | ||
10 | int switcheroo(int fd, int prot, void *from, void *to, int size) | 13 | int switcheroo(int fd, int prot, void *from, void *to, int size) |
11 | { | 14 | { |
12 | if (syscall(__NR_munmap, to, size) < 0){ | 15 | if(munmap(to, size) < 0){ |
13 | return(-1); | 16 | return(-1); |
14 | } | 17 | } |
15 | if (syscall(__NR_mmap2, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ | 18 | if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){ |
16 | return(-1); | 19 | return(-1); |
17 | } | 20 | } |
18 | if (syscall(__NR_munmap, from, size) < 0){ | 21 | if(munmap(from, size) < 0){ |
19 | return(-1); | 22 | return(-1); |
20 | } | 23 | } |
21 | return(0); | 24 | return(0); |
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 @@ | |||
5 | 5 | ||
6 | #include <linux/mman.h> | 6 | #include <linux/mman.h> |
7 | #include <asm/unistd.h> | 7 | #include <asm/unistd.h> |
8 | #include <sys/syscall.h> | ||
9 | 8 | ||
9 | static int errno; | ||
10 | |||
11 | static inline _syscall2(int,munmap,void *,start,size_t,len) | ||
12 | static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset) | ||
10 | int switcheroo(int fd, int prot, void *from, void *to, int size) | 13 | int switcheroo(int fd, int prot, void *from, void *to, int size) |
11 | { | 14 | { |
12 | if (syscall(__NR_munmap, to, size) < 0){ | 15 | if(munmap(to, size) < 0){ |
13 | return(-1); | 16 | return(-1); |
14 | } | 17 | } |
15 | if (syscall(__NR_mmap, to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ | 18 | if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){ |
16 | return(-1); | 19 | return(-1); |
17 | } | 20 | } |
18 | if (syscall(__NR_munmap, from, size) < 0){ | 21 | if(munmap(from, size) < 0){ |
19 | return(-1); | 22 | return(-1); |
20 | } | 23 | } |
21 | return(0); | 24 | return(0); |