diff options
Diffstat (limited to 'arch/um')
58 files changed, 442 insertions, 263 deletions
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index d75307589d74..5ac1f2963ae3 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 |
| @@ -25,6 +30,19 @@ config PCI | |||
| 25 | config PCMCIA | 30 | config PCMCIA |
| 26 | bool | 31 | bool |
| 27 | 32 | ||
| 33 | # Yet to do! | ||
| 34 | config TRACE_IRQFLAGS_SUPPORT | ||
| 35 | bool | ||
| 36 | default n | ||
| 37 | |||
| 38 | config LOCKDEP_SUPPORT | ||
| 39 | bool | ||
| 40 | default y | ||
| 41 | |||
| 42 | config STACKTRACE_SUPPORT | ||
| 43 | bool | ||
| 44 | default y | ||
| 45 | |||
| 28 | config GENERIC_CALIBRATE_DELAY | 46 | config GENERIC_CALIBRATE_DELAY |
| 29 | bool | 47 | bool |
| 30 | default y | 48 | default y |
| @@ -37,13 +55,16 @@ config IRQ_RELEASE_METHOD | |||
| 37 | menu "UML-specific options" | 55 | menu "UML-specific options" |
| 38 | 56 | ||
| 39 | config MODE_TT | 57 | config MODE_TT |
| 40 | bool "Tracing thread support" | 58 | bool "Tracing thread support (DEPRECATED)" |
| 41 | default n | 59 | default n |
| 60 | depends on BROKEN | ||
| 42 | help | 61 | help |
| 43 | This option controls whether tracing thread support is compiled | 62 | This option controls whether tracing thread support is compiled |
| 44 | into UML. This option is largely obsolete, given that skas0 provides | 63 | into UML. This option is largely obsolete, given that skas0 provides |
| 45 | skas security and performance without needing to patch the host. | 64 | skas security and performance without needing to patch the host. |
| 46 | It is safe to say 'N' here. | 65 | It is safe to say 'N' here; saying 'Y' may cause additional problems |
| 66 | with the resulting binary even if you run UML in SKAS mode, and running | ||
| 67 | in TT mode is strongly *NOT RECOMMENDED*. | ||
| 47 | 68 | ||
| 48 | config STATIC_LINK | 69 | config STATIC_LINK |
| 49 | bool "Force a static link" | 70 | bool "Force a static link" |
| @@ -56,6 +77,9 @@ config STATIC_LINK | |||
| 56 | for use in a chroot jail. So, if you intend to run UML inside a | 77 | for use in a chroot jail. So, if you intend to run UML inside a |
| 57 | chroot, and you disable CONFIG_MODE_TT, you probably want to say Y | 78 | chroot, and you disable CONFIG_MODE_TT, you probably want to say Y |
| 58 | here. | 79 | here. |
| 80 | Additionally, this option enables using higher memory spaces (up to | ||
| 81 | 2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads | ||
| 82 | to best results for this. | ||
| 59 | 83 | ||
| 60 | config KERNEL_HALF_GIGS | 84 | config KERNEL_HALF_GIGS |
| 61 | int "Kernel address space size (in .5G units)" | 85 | int "Kernel address space size (in .5G units)" |
| @@ -72,10 +96,13 @@ config MODE_SKAS | |||
| 72 | default y | 96 | default y |
| 73 | help | 97 | help |
| 74 | This option controls whether skas (separate kernel address space) | 98 | This option controls whether skas (separate kernel address space) |
| 75 | support is compiled in. If you have applied the skas patch to the | 99 | support is compiled in. |
| 76 | host, then you certainly want to say Y here (and consider saying N | 100 | Unless you have specific needs to use TT mode (which applies almost only |
| 77 | to CONFIG_MODE_TT). Otherwise, it is safe to say Y. Disabling this | 101 | to developers), you should say Y here. |
| 78 | option will shrink the UML binary slightly. | 102 | SKAS mode will make use of the SKAS3 patch if it is applied on the host |
| 103 | (and your UML will run in SKAS3 mode), but if no SKAS patch is applied | ||
| 104 | on the host it will run in SKAS0 mode, which is anyway faster than TT | ||
| 105 | mode. | ||
| 79 | 106 | ||
| 80 | source "arch/um/Kconfig.arch" | 107 | source "arch/um/Kconfig.arch" |
| 81 | source "mm/Kconfig" | 108 | source "mm/Kconfig" |
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char index 62d87b71179b..e03e40c7aac3 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/Kconfig.i386 b/arch/um/Kconfig.i386 index f6eb72d117b9..f191a550a079 100644 --- a/arch/um/Kconfig.i386 +++ b/arch/um/Kconfig.i386 | |||
| @@ -16,23 +16,42 @@ config SEMAPHORE_SLEEPERS | |||
| 16 | bool | 16 | bool |
| 17 | default y | 17 | default y |
| 18 | 18 | ||
| 19 | config HOST_2G_2G | 19 | choice |
| 20 | bool "2G/2G host address space split" | 20 | prompt "Host memory split" |
| 21 | default n | 21 | default HOST_VMSPLIT_3G |
| 22 | help | 22 | ---help--- |
| 23 | This is needed when the host on which you run has a 2G/2G memory | 23 | This is needed when the host kernel on which you run has a non-default |
| 24 | split, instead of the customary 3G/1G. | 24 | (like 2G/2G) memory split, instead of the customary 3G/1G. If you did |
| 25 | 25 | not recompile your own kernel but use the default distro's one, you can | |
| 26 | Note that to enable such a host | 26 | safely accept the "Default split" option. |
| 27 | configuration, which makes sense only in some cases, you need special | 27 | |
| 28 | host patches. | 28 | It can be enabled on recent (>=2.6.16-rc2) vanilla kernels via |
| 29 | 29 | CONFIG_VM_SPLIT_*, or on previous kernels with special patches (-ck | |
| 30 | So, if you do not know what to do here, say 'N'. | 30 | patchset by Con Kolivas, or other ones) - option names match closely the |
| 31 | host CONFIG_VM_SPLIT_* ones. | ||
| 32 | |||
| 33 | A lower setting (where 1G/3G is lowest and 3G/1G is higher) will | ||
| 34 | tolerate even more "normal" host kernels, but an higher setting will be | ||
| 35 | stricter. | ||
| 36 | |||
| 37 | So, if you do not know what to do here, say 'Default split'. | ||
| 38 | |||
| 39 | config HOST_VMSPLIT_3G | ||
| 40 | bool "Default split (3G/1G user/kernel host split)" | ||
| 41 | config HOST_VMSPLIT_3G_OPT | ||
| 42 | bool "3G/1G user/kernel host split (for full 1G low memory)" | ||
| 43 | config HOST_VMSPLIT_2G | ||
| 44 | bool "2G/2G user/kernel host split" | ||
| 45 | config HOST_VMSPLIT_1G | ||
| 46 | bool "1G/3G user/kernel host split" | ||
| 47 | endchoice | ||
| 31 | 48 | ||
| 32 | config TOP_ADDR | 49 | config TOP_ADDR |
| 33 | hex | 50 | hex |
| 34 | default 0xc0000000 if !HOST_2G_2G | 51 | default 0xB0000000 if HOST_VMSPLIT_3G_OPT |
| 35 | default 0x80000000 if HOST_2G_2G | 52 | default 0x78000000 if HOST_VMSPLIT_2G |
| 53 | default 0x40000000 if HOST_VMSPLIT_1G | ||
| 54 | default 0xC0000000 | ||
| 36 | 55 | ||
| 37 | config 3_LEVEL_PGTABLES | 56 | config 3_LEVEL_PGTABLES |
| 38 | bool "Three-level pagetables (EXPERIMENTAL)" | 57 | bool "Three-level pagetables (EXPERIMENTAL)" |
diff --git a/arch/um/Makefile b/arch/um/Makefile index c8016a98483b..5d5ed726faa0 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 b65ca115ef77..c9f1c5b24c9a 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 11154b6773ec..69ecea63fdae 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 | |||
| @@ -1,15 +1,15 @@ | |||
| 1 | # Copyright 2003 - 2004 Pathscale, Inc | 1 | # Copyright 2003 - 2004 Pathscale, Inc |
| 2 | # Released under the GPL | 2 | # Released under the GPL |
| 3 | 3 | ||
| 4 | core-y += arch/um/sys-x86_64/ | 4 | core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/ |
| 5 | START := 0x60000000 | 5 | START := 0x60000000 |
| 6 | 6 | ||
| 7 | _extra_flags_ = -fno-builtin -m64 -mcmodel=kernel | 7 | _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/cow_sys.h b/arch/um/drivers/cow_sys.h index 7a5b4afde692..c6a308464acb 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 77954ea77043..310af0f1e49e 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 108b7dafbd0e..218aa0e9b792 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 4d2bd39a85bc..8138f5ea1bf7 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 d08bd036ccb8..7b172160fe04 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 17068eb746c0..75aef6f7ef6e 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 9a3b5daf6250..df3516e47d4d 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 f3a3f8a29c7a..0ffd7ac295d4 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 2ef641ded960..11921a7baa7b 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 f2e8fc42ecc2..bc6afaf74c1a 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 abec620e8380..829a5eca8c07 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 8460285c69a5..7eddacc53b6e 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 11de3ac1eb5c..d95d64309eaf 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 bc458f57921b..49c047b75cc5 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 386f8b952982..850221d9b4c9 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/common-offsets.h b/arch/um/include/common-offsets.h index 356390d1f8b9..461175f8b1d9 100644 --- a/arch/um/include/common-offsets.h +++ b/arch/um/include/common-offsets.h | |||
| @@ -1,9 +1,16 @@ | |||
| 1 | /* for use by sys-$SUBARCH/kernel-offsets.c */ | 1 | /* for use by sys-$SUBARCH/kernel-offsets.c */ |
| 2 | 2 | ||
| 3 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
| 4 | #ifdef CONFIG_MODE_TT | ||
| 5 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
| 6 | #endif | ||
| 7 | |||
| 3 | OFFSET(HOST_TASK_REGS, task_struct, thread.regs); | 8 | OFFSET(HOST_TASK_REGS, task_struct, thread.regs); |
| 4 | OFFSET(HOST_TASK_PID, task_struct, pid); | 9 | OFFSET(HOST_TASK_PID, task_struct, pid); |
| 10 | |||
| 5 | DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); | 11 | DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); |
| 6 | DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); | 12 | DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); |
| 13 | |||
| 7 | DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); | 14 | DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); |
| 8 | DEFINE_STR(UM_KERN_ALERT, KERN_ALERT); | 15 | DEFINE_STR(UM_KERN_ALERT, KERN_ALERT); |
| 9 | DEFINE_STR(UM_KERN_CRIT, KERN_CRIT); | 16 | DEFINE_STR(UM_KERN_CRIT, KERN_CRIT); |
| @@ -12,6 +19,10 @@ DEFINE_STR(UM_KERN_WARNING, KERN_WARNING); | |||
| 12 | DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); | 19 | DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); |
| 13 | DEFINE_STR(UM_KERN_INFO, KERN_INFO); | 20 | DEFINE_STR(UM_KERN_INFO, KERN_INFO); |
| 14 | DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); | 21 | DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); |
| 22 | |||
| 15 | DEFINE(UM_ELF_CLASS, ELF_CLASS); | 23 | DEFINE(UM_ELF_CLASS, ELF_CLASS); |
| 16 | DEFINE(UM_ELFCLASS32, ELFCLASS32); | 24 | DEFINE(UM_ELFCLASS32, ELFCLASS32); |
| 17 | DEFINE(UM_ELFCLASS64, ELFCLASS64); | 25 | DEFINE(UM_ELFCLASS64, ELFCLASS64); |
| 26 | |||
| 27 | /* For crypto assembler code. */ | ||
| 28 | DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); | ||
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 59cfa9e0cad0..cec9fcc57bf5 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
| @@ -6,7 +6,6 @@ | |||
| 6 | #ifndef __KERN_UTIL_H__ | 6 | #ifndef __KERN_UTIL_H__ |
| 7 | #define __KERN_UTIL_H__ | 7 | #define __KERN_UTIL_H__ |
| 8 | 8 | ||
| 9 | #include "linux/threads.h" | ||
| 10 | #include "sysdep/ptrace.h" | 9 | #include "sysdep/ptrace.h" |
| 11 | #include "sysdep/faultinfo.h" | 10 | #include "sysdep/faultinfo.h" |
| 12 | 11 | ||
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h index e93c6d3e893b..e860bc5848e0 100644 --- a/arch/um/include/longjmp.h +++ b/arch/um/include/longjmp.h | |||
| @@ -12,7 +12,8 @@ extern void longjmp(jmp_buf, int); | |||
| 12 | } while(0) | 12 | } while(0) |
| 13 | 13 | ||
| 14 | #define UML_SETJMP(buf) ({ \ | 14 | #define UML_SETJMP(buf) ({ \ |
| 15 | int n, enable; \ | 15 | int n; \ |
| 16 | volatile int enable; \ | ||
| 16 | enable = get_signals(); \ | 17 | enable = get_signals(); \ |
| 17 | n = setjmp(*buf); \ | 18 | n = setjmp(*buf); \ |
| 18 | if(n != 0) \ | 19 | if(n != 0) \ |
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h index 58f67d391105..2666815b6af5 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 d0b690197fd7..1ea6d928e1cd 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 120ca21a513a..6516f6dca96d 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h | |||
| @@ -201,6 +201,7 @@ extern int os_getpgrp(void); | |||
| 201 | 201 | ||
| 202 | #ifdef UML_CONFIG_MODE_TT | 202 | #ifdef UML_CONFIG_MODE_TT |
| 203 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); | 203 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); |
| 204 | extern void stop(void); | ||
| 204 | #endif | 205 | #endif |
| 205 | extern void init_new_thread_signals(void); | 206 | extern void init_new_thread_signals(void); |
| 206 | extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); | 207 | extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); |
diff --git a/arch/um/include/sysdep-i386/barrier.h b/arch/um/include/sysdep-i386/barrier.h new file mode 100644 index 000000000000..b58d52c5b2f4 --- /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/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h index 2c13de321f2f..97ec9d894d75 100644 --- a/arch/um/include/sysdep-i386/kernel-offsets.h +++ b/arch/um/include/sysdep-i386/kernel-offsets.h | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | #include <linux/stddef.h> | 1 | #include <linux/stddef.h> |
| 2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
| 3 | #include <linux/elf.h> | 3 | #include <linux/elf.h> |
| 4 | #include <linux/crypto.h> | ||
| 4 | #include <asm/mman.h> | 5 | #include <asm/mman.h> |
| 5 | 6 | ||
| 6 | #define DEFINE(sym, val) \ | 7 | #define DEFINE(sym, val) \ |
| @@ -17,9 +18,5 @@ | |||
| 17 | void foo(void) | 18 | void foo(void) |
| 18 | { | 19 | { |
| 19 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); | 20 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); |
| 20 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
| 21 | #ifdef CONFIG_MODE_TT | ||
| 22 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
| 23 | #endif | ||
| 24 | #include <common-offsets.h> | 21 | #include <common-offsets.h> |
| 25 | } | 22 | } |
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 000000000000..7b610befdc8f --- /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/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index 91d129fb3930..a307237b7964 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h | |||
| @@ -2,6 +2,7 @@ | |||
| 2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
| 3 | #include <linux/time.h> | 3 | #include <linux/time.h> |
| 4 | #include <linux/elf.h> | 4 | #include <linux/elf.h> |
| 5 | #include <linux/crypto.h> | ||
| 5 | #include <asm/page.h> | 6 | #include <asm/page.h> |
| 6 | #include <asm/mman.h> | 7 | #include <asm/mman.h> |
| 7 | 8 | ||
| @@ -18,9 +19,5 @@ | |||
| 18 | 19 | ||
| 19 | void foo(void) | 20 | void foo(void) |
| 20 | { | 21 | { |
| 21 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
| 22 | #ifdef CONFIG_MODE_TT | ||
| 23 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
| 24 | #endif | ||
| 25 | #include <common-offsets.h> | 22 | #include <common-offsets.h> |
| 26 | } | 23 | } |
diff --git a/arch/um/include/um_malloc.h b/arch/um/include/um_malloc.h new file mode 100644 index 000000000000..0363a9b53f8d --- /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 39f8c8801076..acadce3f271f 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 802d7842514d..06625fefef33 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 68ed24df5c8f..e36f92b463ce 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 ef259569fd8c..5c1e611f628d 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 fe6c64abda5b..348b272bb766 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/skas/mmu.c b/arch/um/kernel/skas/mmu.c index c17eddcf89b3..2c6d090a2e87 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c | |||
| @@ -60,10 +60,7 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc, | |||
| 60 | #endif | 60 | #endif |
| 61 | 61 | ||
| 62 | *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); | 62 | *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); |
| 63 | /* This is wrong for the code page, but it doesn't matter since the | 63 | *pte = pte_mkread(*pte); |
| 64 | * stub is mapped by hand with the correct permissions. | ||
| 65 | */ | ||
| 66 | *pte = pte_mkwrite(*pte); | ||
| 67 | return(0); | 64 | return(0); |
| 68 | 65 | ||
| 69 | out_pmd: | 66 | out_pmd: |
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 9882342206ec..b9195355075a 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/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c index 6c92bbccb49c..ed1abcf4d057 100644 --- a/arch/um/kernel/tt/uaccess_user.c +++ b/arch/um/kernel/tt/uaccess_user.c | |||
| @@ -4,13 +4,13 @@ | |||
| 4 | * Licensed under the GPL | 4 | * Licensed under the GPL |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <setjmp.h> | ||
| 8 | #include <string.h> | 7 | #include <string.h> |
| 9 | #include "user_util.h" | 8 | #include "user_util.h" |
| 10 | #include "uml_uaccess.h" | 9 | #include "uml_uaccess.h" |
| 11 | #include "task.h" | 10 | #include "task.h" |
| 12 | #include "kern_util.h" | 11 | #include "kern_util.h" |
| 13 | #include "os.h" | 12 | #include "os.h" |
| 13 | #include "longjmp.h" | ||
| 14 | 14 | ||
| 15 | int __do_copy_from_user(void *to, const void *from, int n, | 15 | int __do_copy_from_user(void *to, const void *from, int n, |
| 16 | void **fault_addr, void **fault_catcher) | 16 | void **fault_addr, void **fault_catcher) |
| @@ -80,10 +80,10 @@ int __do_strnlen_user(const char *str, unsigned long n, | |||
| 80 | struct tt_regs save = TASK_REGS(get_current())->tt; | 80 | struct tt_regs save = TASK_REGS(get_current())->tt; |
| 81 | int ret; | 81 | int ret; |
| 82 | unsigned long *faddrp = (unsigned long *)fault_addr; | 82 | unsigned long *faddrp = (unsigned long *)fault_addr; |
| 83 | sigjmp_buf jbuf; | 83 | jmp_buf jbuf; |
| 84 | 84 | ||
| 85 | *fault_catcher = &jbuf; | 85 | *fault_catcher = &jbuf; |
| 86 | if(sigsetjmp(jbuf, 1) == 0) | 86 | if(UML_SETJMP(&jbuf) == 0) |
| 87 | ret = strlen(str) + 1; | 87 | ret = strlen(str) + 1; |
| 88 | else ret = *faddrp - (unsigned long) str; | 88 | else ret = *faddrp - (unsigned long) str; |
| 89 | 89 | ||
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 8eca47a6ff08..f6301274cf3c 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/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c index f559bdf746e6..863981ba1468 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/helper.c b/arch/um/os-Linux/helper.c index cd15b9df5b5c..d13299cfa318 100644 --- a/arch/um/os-Linux/helper.c +++ b/arch/um/os-Linux/helper.c | |||
| @@ -35,22 +35,23 @@ static int helper_child(void *arg) | |||
| 35 | char **argv = data->argv; | 35 | char **argv = data->argv; |
| 36 | int errval; | 36 | int errval; |
| 37 | 37 | ||
| 38 | if(helper_pause){ | 38 | if (helper_pause){ |
| 39 | signal(SIGHUP, helper_hup); | 39 | signal(SIGHUP, helper_hup); |
| 40 | pause(); | 40 | pause(); |
| 41 | } | 41 | } |
| 42 | if(data->pre_exec != NULL) | 42 | if (data->pre_exec != NULL) |
| 43 | (*data->pre_exec)(data->pre_data); | 43 | (*data->pre_exec)(data->pre_data); |
| 44 | execvp(argv[0], argv); | 44 | execvp(argv[0], argv); |
| 45 | errval = -errno; | 45 | errval = -errno; |
| 46 | printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); | 46 | printk("helper_child - execve of '%s' failed - errno = %d\n", argv[0], errno); |
| 47 | os_write_file(data->fd, &errval, sizeof(errval)); | 47 | os_write_file(data->fd, &errval, sizeof(errval)); |
| 48 | kill(os_getpid(), SIGKILL); | 48 | kill(os_getpid(), SIGKILL); |
| 49 | return(0); | 49 | return 0; |
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | /* Returns either the pid of the child process we run or -E* on failure. | 52 | /* 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 */ | 53 | * XXX The alloc_stack here breaks if this is called in the tracing thread, so |
| 54 | * 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, | 55 | int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, |
| 55 | unsigned long *stack_out) | 56 | unsigned long *stack_out) |
| 56 | { | 57 | { |
| @@ -58,20 +59,21 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
| 58 | unsigned long stack, sp; | 59 | unsigned long stack, sp; |
| 59 | int pid, fds[2], ret, n; | 60 | int pid, fds[2], ret, n; |
| 60 | 61 | ||
| 61 | if((stack_out != NULL) && (*stack_out != 0)) | 62 | if ((stack_out != NULL) && (*stack_out != 0)) |
| 62 | stack = *stack_out; | 63 | stack = *stack_out; |
| 63 | else stack = alloc_stack(0, __cant_sleep()); | 64 | else |
| 64 | if(stack == 0) | 65 | stack = alloc_stack(0, __cant_sleep()); |
| 66 | if (stack == 0) | ||
| 65 | return -ENOMEM; | 67 | return -ENOMEM; |
| 66 | 68 | ||
| 67 | ret = os_pipe(fds, 1, 0); | 69 | ret = os_pipe(fds, 1, 0); |
| 68 | if(ret < 0){ | 70 | if (ret < 0) { |
| 69 | printk("run_helper : pipe failed, ret = %d\n", -ret); | 71 | printk("run_helper : pipe failed, ret = %d\n", -ret); |
| 70 | goto out_free; | 72 | goto out_free; |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | ret = os_set_exec_close(fds[1], 1); | 75 | ret = os_set_exec_close(fds[1], 1); |
| 74 | if(ret < 0){ | 76 | if (ret < 0) { |
| 75 | printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", | 77 | printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", |
| 76 | -ret); | 78 | -ret); |
| 77 | goto out_close; | 79 | goto out_close; |
| @@ -83,7 +85,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, | |||
| 83 | data.argv = argv; | 85 | data.argv = argv; |
| 84 | data.fd = fds[1]; | 86 | data.fd = fds[1]; |
| 85 | pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); | 87 | pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); |
| 86 | if(pid < 0){ | 88 | if (pid < 0) { |
| 87 | ret = -errno; | 89 | ret = -errno; |
| 88 | printk("run_helper : clone failed, errno = %d\n", errno); | 90 | printk("run_helper : clone failed, errno = %d\n", errno); |
| 89 | goto out_close; | 91 | goto out_close; |
| @@ -95,10 +97,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 | 97 | /* 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. */ | 98 | * the exec succeeded because the pipe fd was set as close-on-exec. */ |
| 97 | n = os_read_file(fds[0], &ret, sizeof(ret)); | 99 | n = os_read_file(fds[0], &ret, sizeof(ret)); |
| 98 | if(n == 0) | 100 | if (n == 0) { |
| 99 | ret = pid; | 101 | ret = pid; |
| 100 | else { | 102 | } else { |
| 101 | if(n < 0){ | 103 | if (n < 0) { |
| 102 | printk("run_helper : read on pipe failed, ret = %d\n", | 104 | printk("run_helper : read on pipe failed, ret = %d\n", |
| 103 | -n); | 105 | -n); |
| 104 | ret = n; | 106 | ret = n; |
| @@ -112,10 +114,9 @@ out_close: | |||
| 112 | close(fds[1]); | 114 | close(fds[1]); |
| 113 | close(fds[0]); | 115 | close(fds[0]); |
| 114 | out_free: | 116 | out_free: |
| 115 | if(stack_out == NULL) | 117 | if ((stack_out == NULL) || (*stack_out == 0)) |
| 116 | free_stack(stack, 0); | 118 | free_stack(stack, 0); |
| 117 | else *stack_out = stack; | 119 | return ret; |
| 118 | return(ret); | ||
| 119 | } | 120 | } |
| 120 | 121 | ||
| 121 | int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, | 122 | int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, |
| @@ -125,31 +126,32 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, | |||
| 125 | int pid, status, err; | 126 | int pid, status, err; |
| 126 | 127 | ||
| 127 | stack = alloc_stack(stack_order, __cant_sleep()); | 128 | stack = alloc_stack(stack_order, __cant_sleep()); |
| 128 | if(stack == 0) return(-ENOMEM); | 129 | if (stack == 0) |
| 130 | return -ENOMEM; | ||
| 129 | 131 | ||
| 130 | sp = stack + (page_size() << stack_order) - sizeof(void *); | 132 | sp = stack + (page_size() << stack_order) - sizeof(void *); |
| 131 | pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); | 133 | pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); |
| 132 | if(pid < 0){ | 134 | if (pid < 0) { |
| 133 | err = -errno; | 135 | err = -errno; |
| 134 | printk("run_helper_thread : clone failed, errno = %d\n", | 136 | printk("run_helper_thread : clone failed, errno = %d\n", |
| 135 | errno); | 137 | errno); |
| 136 | return err; | 138 | return err; |
| 137 | } | 139 | } |
| 138 | if(stack_out == NULL){ | 140 | if (stack_out == NULL) { |
| 139 | CATCH_EINTR(pid = waitpid(pid, &status, 0)); | 141 | CATCH_EINTR(pid = waitpid(pid, &status, 0)); |
| 140 | if(pid < 0){ | 142 | if (pid < 0) { |
| 141 | err = -errno; | 143 | err = -errno; |
| 142 | printk("run_helper_thread - wait failed, errno = %d\n", | 144 | printk("run_helper_thread - wait failed, errno = %d\n", |
| 143 | errno); | 145 | errno); |
| 144 | pid = err; | 146 | pid = err; |
| 145 | } | 147 | } |
| 146 | if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) | 148 | if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) |
| 147 | printk("run_helper_thread - thread returned status " | 149 | printk("run_helper_thread - thread returned status " |
| 148 | "0x%x\n", status); | 150 | "0x%x\n", status); |
| 149 | free_stack(stack, stack_order); | 151 | free_stack(stack, stack_order); |
| 150 | } | 152 | } else |
| 151 | else *stack_out = stack; | 153 | *stack_out = stack; |
| 152 | return(pid); | 154 | return pid; |
| 153 | } | 155 | } |
| 154 | 156 | ||
| 155 | int helper_wait(int pid) | 157 | int helper_wait(int pid) |
| @@ -157,9 +159,9 @@ int helper_wait(int pid) | |||
| 157 | int ret; | 159 | int ret; |
| 158 | 160 | ||
| 159 | CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); | 161 | CATCH_EINTR(ret = waitpid(pid, NULL, WNOHANG)); |
| 160 | if(ret < 0){ | 162 | if (ret < 0) { |
| 161 | ret = -errno; | 163 | ret = -errno; |
| 162 | printk("helper_wait : waitpid failed, errno = %d\n", errno); | 164 | printk("helper_wait : waitpid failed, errno = %d\n", errno); |
| 163 | } | 165 | } |
| 164 | return(ret); | 166 | return ret; |
| 165 | } | 167 | } |
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c index a97206df5b52..d46b818c1311 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 d1c5670787dc..685feaab65d2 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 51f0893640a6..c692a192957a 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 f6457765b17d..925a65240cfe 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 6b81739279d1..b897e8592d77 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 cb9ab54146cc..9b34fe65949a 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 6e945ab45843..256532034c62 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 38be096e750f..2115b8beb541 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 a2de2580b8af..16215b990804 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/os-Linux/tt.c b/arch/um/os-Linux/tt.c index 5461a065bbb9..3dc3a02d6263 100644 --- a/arch/um/os-Linux/tt.c +++ b/arch/um/os-Linux/tt.c | |||
| @@ -10,7 +10,6 @@ | |||
| 10 | #include <errno.h> | 10 | #include <errno.h> |
| 11 | #include <stdarg.h> | 11 | #include <stdarg.h> |
| 12 | #include <stdlib.h> | 12 | #include <stdlib.h> |
| 13 | #include <setjmp.h> | ||
| 14 | #include <sys/time.h> | 13 | #include <sys/time.h> |
| 15 | #include <sys/ptrace.h> | 14 | #include <sys/ptrace.h> |
| 16 | #include <linux/ptrace.h> | 15 | #include <linux/ptrace.h> |
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index 3f5b1514e8a7..56b8a50e8bc2 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
| @@ -80,11 +80,18 @@ void setup_machinename(char *machine_out) | |||
| 80 | struct utsname host; | 80 | struct utsname host; |
| 81 | 81 | ||
| 82 | uname(&host); | 82 | uname(&host); |
| 83 | #if defined(UML_CONFIG_UML_X86) && !defined(UML_CONFIG_64BIT) | 83 | #ifdef UML_CONFIG_UML_X86 |
| 84 | # ifndef UML_CONFIG_64BIT | ||
| 84 | if (!strcmp(host.machine, "x86_64")) { | 85 | if (!strcmp(host.machine, "x86_64")) { |
| 85 | strcpy(machine_out, "i686"); | 86 | strcpy(machine_out, "i686"); |
| 86 | return; | 87 | return; |
| 87 | } | 88 | } |
| 89 | # else | ||
| 90 | if (!strcmp(host.machine, "i686")) { | ||
| 91 | strcpy(machine_out, "x86_64"); | ||
| 92 | return; | ||
| 93 | } | ||
| 94 | # endif | ||
| 88 | #endif | 95 | #endif |
| 89 | strcpy(machine_out, host.machine); | 96 | strcpy(machine_out, host.machine); |
| 90 | } | 97 | } |
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c index 8e55cd5d3d07..1b0ad0e4adcd 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/ksyms.c b/arch/um/sys-x86_64/ksyms.c index 859273808203..12c593607c59 100644 --- a/arch/um/sys-x86_64/ksyms.c +++ b/arch/um/sys-x86_64/ksyms.c | |||
| @@ -14,6 +14,3 @@ EXPORT_SYMBOL(__up_wakeup); | |||
| 14 | 14 | ||
| 15 | /*XXX: we need them because they would be exported by x86_64 */ | 15 | /*XXX: we need them because they would be exported by x86_64 */ |
| 16 | EXPORT_SYMBOL(__memcpy); | 16 | EXPORT_SYMBOL(__memcpy); |
| 17 | |||
| 18 | /* Networking helper routines. */ | ||
| 19 | EXPORT_SYMBOL(ip_compute_csum); | ||
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c index 1c967026c957..652fa34c2cd3 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #include <stddef.h> | 6 | #include <stddef.h> |
| 7 | #include <signal.h> | 7 | #include <signal.h> |
| 8 | #include <linux/compiler.h> | ||
| 9 | #include <asm/unistd.h> | 8 | #include <asm/unistd.h> |
| 10 | #include "uml-config.h" | 9 | #include "uml-config.h" |
| 11 | #include "sysdep/sigcontext.h" | 10 | #include "sysdep/sigcontext.h" |
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c index 57c9286a701b..f4a4bffd8a18 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); |
