Merge to uml-2.6.7-2um
authorMark Huang <mlhuang@cs.princeton.edu>
Fri, 20 Aug 2004 19:33:57 +0000 (19:33 +0000)
committerMark Huang <mlhuang@cs.princeton.edu>
Fri, 20 Aug 2004 19:33:57 +0000 (19:33 +0000)
84 files changed:
arch/um/Kconfig
arch/um/Kconfig_char
arch/um/Makefile
arch/um/Makefile-i386
arch/um/defconfig
arch/um/drivers/Makefile
arch/um/drivers/chan_kern.c
arch/um/drivers/chan_user.c
arch/um/drivers/fd.c
arch/um/drivers/hostaudio_kern.c
arch/um/drivers/hostaudio_user.c [deleted file]
arch/um/drivers/mconsole_kern.c
arch/um/drivers/net_kern.c
arch/um/drivers/net_user.c
arch/um/drivers/port_user.c
arch/um/drivers/pty.c
arch/um/drivers/slip_user.c
arch/um/drivers/slirp_user.c
arch/um/drivers/tty.c
arch/um/drivers/ubd_kern.c
arch/um/drivers/ubd_user.c
arch/um/drivers/xterm.c
arch/um/dyn.lds.S
arch/um/include/hostaudio.h [deleted file]
arch/um/include/init.h
arch/um/include/irq_user.h
arch/um/include/mem.h
arch/um/include/os.h
arch/um/include/time_user.h
arch/um/include/user.h
arch/um/include/user_util.h
arch/um/kernel/Makefile
arch/um/kernel/frame.c
arch/um/kernel/helper.c
arch/um/kernel/irq_user.c
arch/um/kernel/ksyms.c
arch/um/kernel/mem_user.c
arch/um/kernel/mprot.h [deleted file]
arch/um/kernel/process.c
arch/um/kernel/process_kern.c
arch/um/kernel/sigio_kern.c
arch/um/kernel/sigio_user.c
arch/um/kernel/skas/exec_user.c
arch/um/kernel/skas/include/mode.h
arch/um/kernel/skas/process.c
arch/um/kernel/skas/process_kern.c
arch/um/kernel/skas/trap_user.c
arch/um/kernel/smp.c
arch/um/kernel/time.c
arch/um/kernel/time_kern.c
arch/um/kernel/trap_kern.c
arch/um/kernel/trap_user.c
arch/um/kernel/tt/exec_kern.c
arch/um/kernel/tt/exec_user.c
arch/um/kernel/tt/process_kern.c
arch/um/kernel/tt/ptproxy/proxy.c
arch/um/kernel/tt/tracer.c
arch/um/kernel/tt/trap_user.c
arch/um/kernel/tt/uaccess_user.c
arch/um/kernel/tty_log.c
arch/um/kernel/uaccess_user.c
arch/um/kernel/um_arch.c
arch/um/kernel/umid.c
arch/um/kernel/user_util.c
arch/um/main.c
arch/um/os-Linux/Makefile
arch/um/os-Linux/drivers/ethertap_user.c
arch/um/os-Linux/drivers/tuntap_user.c
arch/um/os-Linux/file.c
arch/um/os-Linux/process.c
arch/um/sys-i386/Makefile
arch/um/sys-i386/bugs.c
arch/um/sys-i386/ldt.c
arch/um/sys-i386/ptrace_user.c
arch/um/sys-i386/time.c [deleted file]
arch/um/util/Makefile
arch/um/util/mk_constants [deleted file]
arch/um/util/mk_task [deleted file]
fs/Makefile
fs/hostfs/hostfs_kern.c [deleted file]
fs/hostfs/hostfs_user.c [deleted file]
include/asm-um/bug.h
include/asm-um/irq.h
include/asm-um/processor-generic.h

index 48a6341..e472073 100644 (file)
@@ -78,6 +78,9 @@ config NET
 
 source "fs/Kconfig.binfmt"
 
+config EXTERNFS
+       tristate "Support for host-based filesystems"
+
 config HOSTFS
        tristate "Host filesystem"
        help
@@ -99,6 +102,10 @@ config HOSTFS
         If you'd like to be able to work with files stored on the host, 
         say Y or M here; otherwise say N.
 
+config HUMFS
+       tristate 'Usable host filesystem'
+       depends on EXTERNFS
+
 config HPPFS
        tristate "HoneyPot ProcFS"
        help
index a21cbbc..8a6afe6 100644 (file)
@@ -108,11 +108,55 @@ config SSL_CHAN
 
 config UNIX98_PTYS
        bool "Unix98 PTY support"
-
-config UNIX98_PTY_COUNT
-       int "Maximum number of Unix98 PTYs in use (0-2048)"
-       depends on UNIX98_PTYS
+       ---help---
+         A pseudo terminal (PTY) is a software device consisting of two
+         halves: a master and a slave. The slave device behaves identical to
+         a physical terminal; the master device is used by a process to
+         read data from and write data to the slave, thereby emulating a
+         terminal. Typical programs for the master side are telnet servers
+         and xterms.
+
+         Linux has traditionally used the BSD-like names /dev/ptyxx for
+         masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
+         has a number of problems. The GNU C library glibc 2.1 and later,
+         however, supports the Unix98 naming standard: in order to acquire a
+         pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
+         terminal is then made available to the process and the pseudo
+         terminal slave can be accessed as /dev/pts/<number>. What was
+         traditionally /dev/ttyp2 will then be /dev/pts/2, for example.
+
+         All modern Linux systems use the Unix98 ptys.  Say Y unless
+         you're on an embedded system and want to conserve memory.
+
+config LEGACY_PTYS
+       bool "Legacy (BSD) PTY support"
+       default y
+       ---help---
+         A pseudo terminal (PTY) is a software device consisting of two
+         halves: a master and a slave. The slave device behaves identical to
+         a physical terminal; the master device is used by a process to
+         read data from and write data to the slave, thereby emulating a
+         terminal. Typical programs for the master side are telnet servers
+         and xterms.
+
+         Linux has traditionally used the BSD-like names /dev/ptyxx
+         for masters and /dev/ttyxx for slaves of pseudo
+         terminals. This scheme has a number of problems, including
+         security.  This option enables these legacy devices; on most
+         systems, it is safe to say N.
+
+
+config LEGACY_PTY_COUNT
+       int "Maximum number of legacy PTY in use"
+       depends on LEGACY_PTYS
        default "256"
+       ---help---
+         The maximum number of legacy PTYs that can be used at any one time.
+         The default is 256, and should be more than enough.  Embedded
+         systems may want to reduce this to save memory.
+
+         When not in use, each legacy PTY occupies 12 bytes on 32-bit
+         architectures and 24 bytes on 64-bit architectures.
 
 config WATCHDOG
        bool "Watchdog Timer Support"
index 4e9bbef..5dfc320 100644 (file)
@@ -48,7 +48,7 @@ endif
 include $(ARCH_DIR)/Makefile-$(SUBARCH)
 include $(ARCH_DIR)/Makefile-os-$(OS)
 
-EXTRAVERSION := $(EXTRAVERSION)-1um
+EXTRAVERSION := $(EXTRAVERSION)-2um
 
 ARCH_INCLUDE = -I$(ARCH_DIR)/include
 
@@ -61,13 +61,17 @@ CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
        -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
        -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
 
+check_gcc = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi)
+
+CFLAGS += $(call check_gcc,-fno-unit-at-a-time,)
+
 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
 
 # These are needed for clean and mrproper, since in that case .config is not
 # included; the values here are meaningless
 
 CONFIG_NEST_LEVEL ?= 0
-CONFIG_KERNEL_HALF_GIGS ?=  0
+CONFIG_KERNEL_HALF_GIGS ?= 0
 
 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
 
@@ -111,8 +115,12 @@ CPP_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT)
 CONFIG_KERNEL_STACK_ORDER ?= 2
 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
 
+ifndef START
+  START = $$(($(TOP_ADDR) - $(SIZE)))
+endif
+
 AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
-       -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
+       -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
        -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
        -DKERNEL_STACK_SIZE=$(STACK_SIZE))
 
@@ -207,3 +215,9 @@ $(ARCH_DIR)/util: FORCE
        $(Q)$(MAKE) $(build)=$@
 
 export SUBARCH USER_CFLAGS OS 
+
+all: linux
+
+define archhelp
+    echo  '* linux     - Binary kernel image (./linux)'
+endef
index 36b1f69..1b7e163 100644 (file)
@@ -4,7 +4,18 @@ else
 TOP_ADDR = 0xc0000000
 endif
 
+ifeq ($(CONFIG_MODE_SKAS),y)
+  ifneq ($(CONFIG_MODE_TT),y)
+     START = 0x8048000
+  endif
+endif
+
 CFLAGS += -U__$(SUBARCH)__ -U$(SUBARCH)
+
+ifneq ($(CONFIG_GPROF),y)
+ARCH_CFLAGS += -DUM_FASTCALL
+endif
+
 ELF_ARCH = $(SUBARCH)
 ELF_FORMAT = elf32-$(SUBARCH)
 
index 06fe817..825e495 100644 (file)
@@ -14,7 +14,9 @@ CONFIG_MODE_SKAS=y
 CONFIG_NET=y
 CONFIG_BINFMT_ELF=y
 CONFIG_BINFMT_MISC=y
+CONFIG_EXTERNFS=y
 CONFIG_HOSTFS=y
+CONFIG_HUMFS=y
 CONFIG_HPPFS=y
 CONFIG_MCONSOLE=y
 CONFIG_MAGIC_SYSRQ=y
@@ -41,15 +43,23 @@ CONFIG_BROKEN_ON_SMP=y
 #
 CONFIG_SWAP=y
 CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
+# CONFIG_POSIX_MQUEUE is not set
 CONFIG_BSD_PROCESS_ACCT=y
+
+#
+# Class Based Kernel Resource Management
+#
+# CONFIG_CKRM is not set
+# CONFIG_BSD_PROCESS_ACCT_V3 is not set
 CONFIG_SYSCTL=y
-CONFIG_AUDIT=y
+# CONFIG_AUDIT is not set
 CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_HOTPLUG is not set
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
+# CONFIG_DELAY_ACCT is not set
 CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_IOSCHED_NOOP=y
@@ -66,6 +76,7 @@ CONFIG_IOSCHED_CFQ=y
 #
 # Generic Driver Options
 #
+CONFIG_PREVENT_FIRMWARE_BUILD=y
 
 #
 # Character Devices
@@ -82,7 +93,8 @@ CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
 CONFIG_CON_CHAN="xterm"
 CONFIG_SSL_CHAN="pty"
 CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_WATCHDOG is not set
 CONFIG_UML_SOUND=y
 CONFIG_SOUND=y
@@ -163,6 +175,7 @@ CONFIG_INET=y
 # QoS and/or fair queueing
 #
 # CONFIG_NET_SCHED is not set
+# CONFIG_NET_CLS_ROUTE is not set
 
 #
 # Network testing
@@ -173,7 +186,6 @@ CONFIG_INET=y
 # CONFIG_HAMRADIO is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
-# CONFIG_TUX is not set
 CONFIG_DUMMY=y
 # CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
@@ -231,11 +243,8 @@ CONFIG_EXT2_FS=y
 CONFIG_REISERFS_FS=y
 # CONFIG_REISERFS_CHECK is not set
 # CONFIG_REISERFS_PROC_INFO is not set
-CONFIG_REISERFS_FS_XATTR=y
-CONFIG_REISERFS_FS_POSIX_ACL=y
-CONFIG_REISERFS_FS_SECURITY=y
+# CONFIG_REISERFS_FS_XATTR is not set
 # CONFIG_JFS_FS is not set
-CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 CONFIG_MINIX_FS=y
 # CONFIG_ROMFS_FS is not set
@@ -260,6 +269,8 @@ CONFIG_ISO9660_FS=y
 CONFIG_FAT_FS=y
 CONFIG_MSDOS_FS=y
 CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
 # CONFIG_NTFS_FS is not set
 
 #
@@ -275,6 +286,7 @@ CONFIG_DEVFS_MOUNT=y
 CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
+# CONFIG_RELAYFS_FS is not set
 
 #
 # Miscellaneous filesystems
@@ -288,7 +300,9 @@ CONFIG_RAMFS=y
 # CONFIG_EFS_FS is not set
 CONFIG_JFFS_FS=y
 CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_JFFS_PROC_FS is not set
 # CONFIG_JFFS2_FS is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
 # CONFIG_HPFS_FS is not set
@@ -342,6 +356,7 @@ CONFIG_NLS_DEFAULT="iso8859-1"
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_CODEPAGE_1250 is not set
 # CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -382,6 +397,7 @@ CONFIG_INOXID_GID24=y
 #
 # Library routines
 #
+# CONFIG_CRC_CCITT is not set
 # CONFIG_CRC32 is not set
 # CONFIG_LIBCRC32C is not set
 
@@ -417,6 +433,16 @@ CONFIG_MTD_BLOCK=y
 #
 # CONFIG_MTD_CFI is not set
 # CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
 # CONFIG_MTD_RAM is not set
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
@@ -431,6 +457,7 @@ CONFIG_MTD_BLOCK=y
 # Self-contained MTD device drivers
 #
 # CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
 CONFIG_MTD_BLKMTD=y
 
index 7dd1547..ba1aabb 100644 (file)
@@ -15,7 +15,7 @@ mcast-objs := mcast_kern.o mcast_user.o
 #pcap-objs := pcap_kern.o pcap_user.o $(PCAP)
 net-objs := net_kern.o net_user.o
 mconsole-objs := mconsole_kern.o mconsole_user.o
-hostaudio-objs := hostaudio_kern.o hostaudio_user.o
+hostaudio-objs := hostaudio_kern.o
 ubd-objs := ubd_kern.o ubd_user.o
 port-objs := port_kern.o port_user.o
 harddog-objs := harddog_kern.o harddog_user.o
index 56e19fa..9ffd300 100644 (file)
@@ -17,6 +17,7 @@
 #include "irq_user.h"
 #include "sigio.h"
 #include "line.h"
+#include "os.h"
 
 static void *not_configged_init(char *str, int device, struct chan_opts *opts)
 {
@@ -87,6 +88,54 @@ static struct chan_ops not_configged_ops = {
        .winch          = 0,
 };
 
+void generic_close(int fd, void *unused)
+{
+       os_close_file(fd);
+}
+
+int generic_read(int fd, char *c_out, void *unused)
+{
+       int n;
+
+       n = os_read_file(fd, c_out, sizeof(*c_out));
+
+       if(n == -EAGAIN)
+               return(0);
+       else if(n == 0)
+               return(-EIO);
+       return(n);
+}
+
+/* XXX Trivial wrapper around os_write_file */
+
+int generic_write(int fd, const char *buf, int n, void *unused)
+{
+       return(os_write_file(fd, buf, n));
+}
+
+int generic_window_size(int fd, void *unused, unsigned short *rows_out,
+                       unsigned short *cols_out)
+{
+       int rows, cols;
+       int ret;
+
+       ret = os_window_size(fd, &rows, &cols);
+       if(ret < 0)
+               return(ret);
+
+       ret = ((*rows_out != rows) || (*cols_out != cols));
+
+       *rows_out = rows;
+       *cols_out = cols;
+
+       return(ret);
+}
+
+void generic_free(void *data)
+{
+       kfree(data);
+}
+
 static void tty_receive_char(struct tty_struct *tty, char ch)
 {
        if(tty == NULL) return;
index 7319ddd..bbc5b4c 100644 (file)
 #include "choose-mode.h"
 #include "mode.h"
 
-void generic_close(int fd, void *unused)
+static void winch_handler(int sig)
 {
-       os_close_file(fd);
 }
 
-int generic_read(int fd, char *c_out, void *unused)
-{
-       int n;
-
-       n = os_read_file(fd, c_out, sizeof(*c_out));
-
-       if(n == -EAGAIN) 
-               return(0);
-       else if(n == 0) 
-               return(-EIO);
-       return(n);
-}
-
-/* XXX Trivial wrapper around os_write_file */
-
-int generic_write(int fd, const char *buf, int n, void *unused)
-{
-       return(os_write_file(fd, buf, n));
-}
+struct winch_data {
+       int pty_fd;
+       int pipe_fd;
+       int close_me;
+};
 
+/* XXX This breaks horribly (by hanging UML) when moved to chan_kern.c - 
+ * needs investigation
+ */
 int generic_console_write(int fd, const char *buf, int n, void *unused)
 {
        struct termios save, new;
@@ -62,39 +50,6 @@ int generic_console_write(int fd, const char *buf, int n, void *unused)
        return(err);
 }
 
-int generic_window_size(int fd, void *unused, unsigned short *rows_out,
-                       unsigned short *cols_out)
-{
-       int rows, cols;
-       int ret;
-
-       ret = os_window_size(fd, &rows, &cols);
-       if(ret < 0)
-               return(ret);
-
-       ret = ((*rows_out != rows) || (*cols_out != cols));
-
-       *rows_out = rows;
-       *cols_out = cols;
-
-       return(ret);
-}
-
-void generic_free(void *data)
-{
-       kfree(data);
-}
-
-static void winch_handler(int sig)
-{
-}
-
-struct winch_data {
-       int pty_fd;
-       int pipe_fd;
-       int close_me;
-};
-
 static int winch_thread(void *arg)
 {
        struct winch_data *data = arg;
index 33c6c78..42cba3f 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <termios.h>
+#include <errno.h>
 #include "user.h"
 #include "user_util.h"
 #include "chan_user.h"
@@ -45,10 +46,16 @@ void *fd_init(char *str, int device, struct chan_opts *opts)
 int fd_open(int input, int output, int primary, void *d, char **dev_out)
 {
        struct fd_chan *data = d;
+       int err;
 
        if(data->raw && isatty(data->fd)){
-               tcgetattr(data->fd, &data->tt);
-               raw(data->fd, 0);
+               CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
+               if(err)
+                       return(err);
+
+               err = raw(data->fd);
+               if(err)
+                       return(err);
        }
        sprintf(data->str, "%d", data->fd);
        *dev_out = data->str;
@@ -58,9 +65,13 @@ int fd_open(int input, int output, int primary, void *d, char **dev_out)
 void fd_close(int fd, void *d)
 {
        struct fd_chan *data = d;
+       int err;
 
        if(data->raw && isatty(fd)){
-               tcsetattr(fd, TCSAFLUSH, &data->tt);
+               CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
+               if(err)
+                       printk("Failed to restore terminal state - " 
+                              "errno = %d\n", -err);
                data->raw = 0;
        }
 }
index 9f9ae27..7f965c8 100644 (file)
 #include "asm/uaccess.h"
 #include "kern_util.h"
 #include "init.h"
-#include "hostaudio.h"
+#include "os.h"
+
+struct hostaudio_state {
+       int fd;
+};
+
+struct hostmixer_state {
+       int fd;
+};
+
+#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
+#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
 
 /* Only changed from linux_main at boot time */
 char *dsp = HOSTAUDIO_DEV_DSP;
@@ -24,7 +35,7 @@ char *mixer = HOSTAUDIO_DEV_MIXER;
 "    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
 
 #define MIXER_HELP \
-"    This is used to specify the host mixer device to the hostaudio driver.\n" \
+"    This is used to specify the host mixer device to the hostaudio driver.\n"\
 "    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
 
 #ifndef MODULE
@@ -71,7 +82,7 @@ static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
        if(kbuf == NULL)
                return(-ENOMEM);
 
-        err = hostaudio_read_user(state, kbuf, count, ppos);
+       err = os_read_file(state->fd, kbuf, count);
        if(err < 0)
                goto out;
 
@@ -102,9 +113,10 @@ static ssize_t hostaudio_write(struct file *file, const char *buffer,
        if(copy_from_user(kbuf, buffer, count))
                goto out;
 
-        err = hostaudio_write_user(state, kbuf, count, ppos);
+       err = os_write_file(state->fd, kbuf, count);
        if(err < 0)
                goto out;
+       *ppos += err;
 
  out:
        kfree(kbuf);
@@ -147,7 +159,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
                break;
        }
 
-        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
+       err = os_ioctl_generic(state->fd, cmd, (unsigned long) &data);
 
        switch(cmd){
        case SNDCTL_DSP_SPEED:
@@ -177,17 +189,19 @@ static int hostaudio_open(struct inode *inode, struct file *file)
 #endif
 
         state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
-        if(state == NULL) return(-ENOMEM);
+        if(state == NULL) 
+               return(-ENOMEM);
 
         if(file->f_mode & FMODE_READ) r = 1;
         if(file->f_mode & FMODE_WRITE) w = 1;
 
-        ret = hostaudio_open_user(state, r, w, dsp);
+       ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
         if(ret < 0){
                kfree(state);
                return(ret);
         }
 
+       state->fd = ret;
         file->private_data = state;
         return(0);
 }
@@ -195,16 +209,15 @@ static int hostaudio_open(struct inode *inode, struct file *file)
 static int hostaudio_release(struct inode *inode, struct file *file)
 {
         struct hostaudio_state *state = file->private_data;
-        int ret;
 
 #ifdef DEBUG
         printk("hostaudio: release called\n");
 #endif
 
-        ret = hostaudio_release_user(state);
+       os_close_file(state->fd);
         kfree(state);
 
-        return(ret);
+        return(0);
 }
 
 /* /dev/mixer file operations */
@@ -218,7 +231,7 @@ static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
         printk("hostmixer: ioctl called\n");
 #endif
 
-        return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
+       return(os_ioctl_generic(state->fd, cmd, arg));
 }
 
 static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
@@ -237,9 +250,11 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
         if(file->f_mode & FMODE_READ) r = 1;
         if(file->f_mode & FMODE_WRITE) w = 1;
 
-        ret = hostmixer_open_mixdev_user(state, r, w, mixer);
+       ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
         
         if(ret < 0){
+               printk("hostaudio_open_mixdev failed to open '%s', err = %d\n",
+                      dsp, -ret);
                kfree(state);
                return(ret);
         }
@@ -251,16 +266,15 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
 static int hostmixer_release(struct inode *inode, struct file *file)
 {
         struct hostmixer_state *state = file->private_data;
-       int ret;
 
 #ifdef DEBUG
         printk("hostmixer: release called\n");
 #endif
 
-        ret = hostmixer_release_mixdev_user(state);
+       os_close_file(state->fd);
         kfree(state);
 
-        return(ret);
+        return(0);
 }
 
 
diff --git a/arch/um/drivers/hostaudio_user.c b/arch/um/drivers/hostaudio_user.c
deleted file mode 100644 (file)
index b89fefb..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-/* 
- * Copyright (C) 2002 Steve Schmidtke 
- * Licensed under the GPL
- */
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <errno.h>
-#include "hostaudio.h"
-#include "user_util.h"
-#include "kern_util.h"
-#include "user.h"
-#include "os.h"
-
-/* /dev/dsp file operations */
-
-ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, 
-                           size_t count, loff_t *ppos)
-{
-#ifdef DEBUG
-        printk("hostaudio: read_user called, count = %d\n", count);
-#endif
-
-       return(os_read_file(state->fd, buffer, count));
-}
-
-ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
-                            size_t count, loff_t *ppos)
-{
-#ifdef DEBUG
-        printk("hostaudio: write_user called, count = %d\n", count);
-#endif
-
-       return(os_write_file(state->fd, buffer, count));
-}
-
-int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, 
-                        unsigned long arg)
-{
-#ifdef DEBUG
-        printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
-#endif
-
-       return(os_ioctl_generic(state->fd, cmd, arg));
-}
-
-int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
-{
-#ifdef DEBUG
-        printk("hostaudio: open_user called\n");
-#endif
-
-       state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
-
-       if(state->fd < 0) {
-               printk("hostaudio_open_user failed to open '%s', err = %d\n",
-                      dsp, -state->fd);
-               return(state->fd); 
-       }
-        
-       return(0);
-}
-
-int hostaudio_release_user(struct hostaudio_state *state)
-{
-#ifdef DEBUG
-        printk("hostaudio: release called\n");
-#endif
-       if(state->fd >= 0){
-               os_close_file(state->fd);
-               state->fd = -1;
-       }
-
-        return(0);
-}
-
-/* /dev/mixer file operations */
-
-int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
-                               unsigned int cmd, unsigned long arg)
-{
-#ifdef DEBUG
-        printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
-#endif
-
-       return(os_ioctl_generic(state->fd, cmd, arg));
-}
-
-int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
-                              char *mixer)
-{
-#ifdef DEBUG
-        printk("hostmixer: open_user called\n");
-#endif
-
-        state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
-
-       if(state->fd < 0) {
-               printk("hostaudio_open_mixdev_user failed to open '%s', "
-                      "err = %d\n", mixer, state->fd);
-               return(state->fd); 
-       }
-        
-       return(0);
-}
-
-int hostmixer_release_mixdev_user(struct hostmixer_state *state)
-{
-#ifdef DEBUG
-        printk("hostmixer: release_user called\n");
-#endif
-
-        if(state->fd >= 0){
-               os_close_file(state->fd);
-               state->fd = -1;
-        }
-
-        return 0;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index d8af144..3396ba4 100644 (file)
@@ -51,27 +51,26 @@ static struct notifier_block reboot_notifier = {
 
 LIST_HEAD(mc_requests);
 
-void mc_work_proc(void *unused)
+static void mc_work_proc(void *unused)
 {
        struct mconsole_entry *req;
        unsigned long flags;
-       int done;
 
-       do {
+       while(!list_empty(&mc_requests)){
                local_save_flags(flags);
                req = list_entry(mc_requests.next, struct mconsole_entry, 
                                 list);
                list_del(&req->list);
-               done = list_empty(&mc_requests);
                local_irq_restore(flags);
                req->request.cmd->handler(&req->request);
                kfree(req);
-       } while(!done);
+       }
 }
 
 DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
 
-irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t mconsole_interrupt(int irq, void *dev_id, 
+                                     struct pt_regs *regs)
 {
        int fd;
        struct mconsole_entry *new;
@@ -91,7 +90,8 @@ irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
                        }
                }
        }
-       if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
+       if(!list_empty(&mc_requests)) 
+               schedule_work(&mconsole_work);
        reactivate_fd(fd, MCONSOLE_IRQ);
        return(IRQ_HANDLED);
 }
@@ -374,8 +374,8 @@ void mconsole_sysrq(struct mc_request *req)
        ptr += strlen("sysrq");
        while(isspace(*ptr)) ptr++;
 
-       handle_sysrq(*ptr, &current->thread.regs, NULL);
        mconsole_reply(req, "", 0, 0);
+       handle_sysrq(*ptr, &current->thread.regs, NULL);
 }
 #else
 void mconsole_sysrq(struct mc_request *req)
index c97dbe0..20c4732 100644 (file)
@@ -19,6 +19,8 @@
 #include "linux/inetdevice.h"
 #include "linux/ctype.h"
 #include "linux/bootmem.h"
+#include "linux/ethtool.h"
+#include "asm/uaccess.h"
 #include "user_util.h"
 #include "kern_util.h"
 #include "net_kern.h"
@@ -240,7 +242,30 @@ static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
 
 static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-       return(-EINVAL);
+       static const struct ethtool_drvinfo info = {
+               .cmd     = ETHTOOL_GDRVINFO,
+               .driver  = "uml virtual ethernet",
+               .version = "42",
+       };
+       void *useraddr;
+       u32 ethcmd;
+
+       switch (cmd) {
+       case SIOCETHTOOL:
+               useraddr = ifr->ifr_data;
+               if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
+                       return -EFAULT;
+               switch (ethcmd) {
+               case ETHTOOL_GDRVINFO:
+                       if (copy_to_user(useraddr, &info, sizeof(info)))
+                               return -EFAULT;
+                       return 0;
+               default:
+                       return -EOPNOTSUPP;
+               }
+       default:
+               return -EINVAL;
+       }
 }
 
 void uml_net_user_timer_expire(unsigned long _conn)
index c9fc286..8753188 100644 (file)
@@ -173,9 +173,10 @@ static int change_tramp(char **argv, char *output, int output_len)
        pe_data.stdout = fds[1];
        pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
 
-       os_close_file(fds[1]);
        read_output(fds[0], output, output_len);
-       waitpid(pid, NULL, 0);  
+       os_close_file(fds[0]);
+       os_close_file(fds[1]);
+       CATCH_EINTR(waitpid(pid, NULL, 0));     
        return(pid);
 }
 
index 8dbad94..92a6d4e 100644 (file)
@@ -76,12 +76,17 @@ void port_free(void *d)
 int port_open(int input, int output, int primary, void *d, char **dev_out)
 {
        struct port_chan *data = d;
-       int fd;
+       int fd, err;
 
        fd = port_wait(data->kernel_data);
        if((fd >= 0) && data->raw){
-               tcgetattr(fd, &data->tt);
-               raw(fd, 0);
+               CATCH_EINTR(err = tcgetattr(fd, &data->tt));
+               if(err)
+                       return(err);
+
+               err = raw(fd);
+               if(err)
+                       return(err);
        }
        *dev_out = data->dev;
        return(fd);
@@ -118,12 +123,18 @@ struct chan_ops port_ops = {
 int port_listen_fd(int port)
 {
        struct sockaddr_in addr;
-       int fd, err;
+       int fd, err, arg;
 
        fd = socket(PF_INET, SOCK_STREAM, 0);
        if(fd == -1) 
                return(-errno);
 
+       arg = 1;
+       if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){
+               err = -errno;
+               goto out;
+       }
+
        addr.sin_family = AF_INET;
        addr.sin_port = htons(port);
        addr.sin_addr.s_addr = htonl(INADDR_ANY);
index bfa08d8..d674171 100644 (file)
@@ -38,7 +38,7 @@ int pts_open(int input, int output, int primary, void *d, char **dev_out)
 {
        struct pty_chan *data = d;
        char *dev;
-       int fd;
+       int fd, err;
 
        fd = get_pty();
        if(fd < 0){
@@ -46,8 +46,13 @@ int pts_open(int input, int output, int primary, void *d, char **dev_out)
                return(-errno);
        }
        if(data->raw){
-               tcgetattr(fd, &data->tt);
-               raw(fd, 0);
+               CATCH_EINTR(err = tcgetattr(fd, &data->tt));
+               if(err)
+                       return(err);
+
+               err = raw(fd);
+               if(err)
+                       return(err);
        }
 
        dev = ptsname(fd);
@@ -89,13 +94,19 @@ int getmaster(char *line)
 int pty_open(int input, int output, int primary, void *d, char **dev_out)
 {
        struct pty_chan *data = d;
-       int fd;
+       int fd, err;
        char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
 
        fd = getmaster(dev);
-       if(fd < 0) return(-errno);
+       if(fd < 0) 
+               return(-errno);
+       
+       if(data->raw){
+               err = raw(fd);
+               if(err)
+                       return(err);
+       }
        
-       if(data->raw) raw(fd, 0);
        if(data->announce) (*data->announce)(dev, data->dev);
 
        sprintf(data->dev_name, "%s", dev);
index 1a52559..3d8d4ca 100644 (file)
@@ -4,7 +4,7 @@
 #include <stddef.h>
 #include <sched.h>
 #include <string.h>
-#include <sys/errno.h>
+#include <errno.h>
 #include <sys/termios.h>
 #include <sys/wait.h>
 #include <sys/signal.h>
@@ -100,7 +100,9 @@ static int slip_tramp(char **argv, int fd)
                        printk("%s", output);
                        kfree(output);
                }
-               if(waitpid(pid, &status, 0) < 0) err = errno;
+               CATCH_EINTR(err = waitpid(pid, &status, 0));
+               if(err < 0)
+                       err = errno;
                else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
                        printk("'%s' didn't exit with status 0\n", argv[0]);
                        err = -EINVAL;
index edb45d9..e95fcab 100644 (file)
@@ -4,7 +4,7 @@
 #include <stddef.h>
 #include <sched.h>
 #include <string.h>
-#include <sys/errno.h>
+#include <errno.h>
 #include <sys/wait.h>
 #include <sys/signal.h>
 #include "user_util.h"
@@ -113,13 +113,13 @@ static void slirp_close(int fd, void *data)
        }
 #endif
 
-       err = waitpid(pri->pid, &status, WNOHANG);
-       if(err<0) {
+       CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
+       if(err < 0) {
                printk("slirp_close: waitpid returned %d\n", errno);
                return;
        }
 
-       if(err==0) {
+       if(err == 0) {
                printk("slirp_close: process %d has not exited\n");
                return;
        }
index b3676e9..54aadef 100644 (file)
@@ -41,13 +41,18 @@ void *tty_chan_init(char *str, int device, struct chan_opts *opts)
 int tty_open(int input, int output, int primary, void *d, char **dev_out)
 {
        struct tty_chan *data = d;
-       int fd;
+       int fd, err;
 
        fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0);
        if(fd < 0) return(fd);
        if(data->raw){
-               tcgetattr(fd, &data->tt);
-               raw(fd, 0);
+               CATCH_EINTR(err = tcgetattr(fd, &data->tt));
+               if(err)
+                       return(err);
+
+               err = raw(fd);
+               if(err)
+                       return(err);
        }
 
        *dev_out = data->dev;
index ee47b82..bad209b 100644 (file)
@@ -1004,7 +1004,7 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req)
                 * to write the data to disk first, then we can map the disk
                 * page in and continue normally from there.
                 */
-               if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
+               if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer, dev->fd, io_req->offset + dev->cow.data_offset)){
                        io_req->map_fd = dev->fd;
                        io_req->map_offset = io_req->offset + 
                                dev->cow.data_offset;
@@ -1134,12 +1134,20 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
 }
 
 static int ubd_check_remapped(int fd, unsigned long address, int is_write,
-                             __u64 offset)
+                             __u64 offset, int is_user)
 {
        __u64 bitmap_offset;
        unsigned long new_bitmap[2];
        int i, err, n;
 
+       /* This can only fix kernelspace faults */
+       if(is_user)
+               return(0);
+
+       /* ubd-mmap is only enabled in skas mode */
+       if(CHOOSE_MODE(1, 0))
+               return(0);
+
        /* If it's not a write access, we can't do anything about it */
        if(!is_write)
                return(0);
index 28458a6..400c2a0 100644 (file)
@@ -44,7 +44,9 @@ static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
                printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
                return(1);
        }
-       if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
+       if((buf1.ust_major == buf2.ust_major) && 
+          (buf1.ust_minor == buf2.ust_minor) && 
+          (buf1.ust_ino == buf2.ust_ino))
                return(1);
 
        printk("Backing file mismatch - \"%s\" requested,\n"
@@ -189,6 +191,7 @@ int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
                            data_offset_out);
        if(!err)
                return(fd);
+
        os_close_file(fd);
  out:
        return(err);
index dccdf3e..f417b3b 100644 (file)
@@ -83,6 +83,7 @@ __uml_setup("xterm=", xterm_setup,
 "    are 'xterm=gnome-terminal,-t,-x'.\n\n"
 );
 
+/* XXX This badly needs some cleaning up in the error paths */
 int xterm_open(int input, int output, int primary, void *d, char **dev_out)
 {
        struct xterm_chan *data = d;
@@ -141,8 +142,19 @@ int xterm_open(int input, int output, int primary, void *d, char **dev_out)
                goto out;
        }
 
-       tcgetattr(new, &data->tt);
-       if(data->raw) raw(new, 0);
+       CATCH_EINTR(err = tcgetattr(new, &data->tt));
+       if(err){
+               new = err;
+               goto out;
+       }
+
+       if(data->raw){
+               err = raw(new);
+               if(err){
+                       new = err;
+                       goto out;
+               }
+       }
 
        data->pid = pid;
        *dev_out = NULL;
index f1df348..a331e2b 100644 (file)
@@ -5,9 +5,6 @@ OUTPUT_ARCH(ELF_ARCH)
 ENTRY(_start)
 jiffies = jiffies_64;
 
-SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
-/* Do we need any of these for elf?
-   __DYNAMIC = 0;    */
 SECTIONS
 {
   . = START + SIZEOF_HEADERS;
diff --git a/arch/um/include/hostaudio.h b/arch/um/include/hostaudio.h
deleted file mode 100644 (file)
index 797b3f2..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/* 
- * Copyright (C) 2002 Steve Schmidtke 
- * Licensed under the GPL
- */
-
-#ifndef HOSTAUDIO_H
-#define HOSTAUDIO_H
-
-#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
-#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
-
-struct hostaudio_state {
-  int fd;
-};
-
-struct hostmixer_state {
-  int fd;
-};
-
-/* UML user-side protoypes */
-extern ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer,
-                                  size_t count, loff_t *ppos);
-extern ssize_t hostaudio_write_user(struct hostaudio_state *state, 
-                                   const char *buffer, size_t count, 
-                                   loff_t *ppos);
-extern int hostaudio_ioctl_user(struct hostaudio_state *state, 
-                               unsigned int cmd, unsigned long arg);
-extern int hostaudio_open_user(struct hostaudio_state *state, int r, int w, 
-                              char *dsp);
-extern int hostaudio_release_user(struct hostaudio_state *state);
-extern int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
-                               unsigned int cmd, unsigned long arg);
-extern int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, 
-                                     int w, char *mixer);
-extern int hostmixer_release_mixdev_user(struct hostmixer_state *state);
-
-#endif /* HOSTAUDIO_H */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index f1d82e0..52c393f 100644 (file)
@@ -100,6 +100,16 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
 #define __uml_postsetup_call   __attribute__ ((unused,__section__ (".uml.postsetup.init")))
 #define __uml_exit_call                __attribute__ ((unused,__section__ (".uml.exitcall.exit")))
 
+#ifndef __KERNEL__
+
+#define __initcall(fn) static initcall_t __initcall_##fn __init_call = fn
+#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
+
+#define __init_call __attribute__ ((unused,__section__ (".initcall.init")))
+#define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit")))
+
+#endif
+
 #endif /* _LINUX_UML_INIT_H */
 
 /*
index 087bd39..0df4076 100644 (file)
@@ -14,6 +14,7 @@ extern void free_irq_by_irq_and_dev(int irq, void *dev_id);
 extern void free_irq_by_fd(int fd);
 extern void reactivate_fd(int fd, int irqnum);
 extern void deactivate_fd(int fd, int irqnum);
+extern int deactivate_all_fds(void);
 extern void forward_interrupts(int pid);
 extern void init_irq_signals(int on_sigstack);
 extern void forward_ipi(int fd, int pid);
index 10c46c3..7d3bc63 100644 (file)
@@ -10,7 +10,7 @@
 
 extern int phys_mapping(unsigned long phys, __u64 *offset_out);
 extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
-extern int is_remapped(void *virt);
+extern int is_remapped(const void *virt, int fd, __u64 offset);
 extern int physmem_remove_mapping(void *virt);
 extern void physmem_forget_descriptor(int fd);
 
index 269156e..08a174e 100644 (file)
@@ -29,7 +29,8 @@
  * (if they are wrong here, they are wrong there...).
  */
 struct uml_stat {
-       int                ust_dev;        /* device */
+       int                ust_major;      /* device */
+       int                ust_minor;
        unsigned long long ust_ino;        /* inode */
        int                ust_mode;       /* protection */
        int                ust_nlink;      /* number of hard links */
@@ -41,6 +42,8 @@ struct uml_stat {
        unsigned long      ust_atime;      /* time of last access */
        unsigned long      ust_mtime;      /* time of last modification */
        unsigned long      ust_ctime;      /* time of last change */
+       int                ust_rmajor;
+       int                ust_rminor;
 };
 
 struct openflags {
@@ -52,10 +55,12 @@ struct openflags {
        unsigned int a : 1;     /* O_APPEND */
        unsigned int e : 1;     /* O_EXCL */
        unsigned int cl : 1;    /* FD_CLOEXEC */
+       unsigned int d : 1;     /* O_DIRECT */
 };
 
 #define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
-                                         .t = 0, .a = 0, .e = 0, .cl = 0 })
+                                         .t = 0, .a = 0, .e = 0, .cl = 0, \
+                                         .d = 0 })
 
 static inline struct openflags of_read(struct openflags flags)
 {
@@ -117,9 +122,20 @@ static inline struct openflags of_cloexec(struct openflags flags)
        return(flags); 
 }
   
+static inline struct openflags of_direct(struct openflags flags)
+{ 
+       flags.d = 1; 
+       return(flags); 
+}
+
 extern int os_stat_file(const char *file_name, struct uml_stat *buf);
+extern int os_lstat_file(const char *file_name, struct uml_stat *ubuf);
 extern int os_stat_fd(const int fd, struct uml_stat *buf);
 extern int os_access(const char *file, int mode);
+extern int os_set_file_time(const char *file, unsigned long access, 
+                           unsigned long mod);
+extern int os_set_file_perms(const char *file, int mode);
+extern int os_set_file_owner(const char *file, int owner, int group);
 extern void os_print_error(int error, const char* str);
 extern int os_get_exec_close(int fd, int *close_on_exec);
 extern int os_set_exec_close(int fd, int close_on_exec);
@@ -134,15 +150,33 @@ extern int os_mode_fd(int fd, int mode);
 
 extern int os_seek_file(int fd, __u64 offset);
 extern int os_open_file(char *file, struct openflags flags, int mode);
+extern void *os_open_dir(char *dir, int *err_out);
+extern int os_seek_dir(void *stream, unsigned long long pos);
+extern int os_read_dir(void *stream, unsigned long long *ino_out, 
+                      char **name_out);
+extern int os_tell_dir(void *stream);
+extern int os_close_dir(void *stream);
+extern int os_remove_file(const char *file);
+extern int os_move_file(const char *from, const char *to);
+extern int os_truncate_file(const char *file, unsigned long long len);
+extern int os_truncate_fd(int fd, unsigned long long len);
 extern int os_read_file(int fd, void *buf, int len);
 extern int os_write_file(int fd, const void *buf, int count);
 extern int os_file_size(char *file, long long *size_out);
+extern int os_fd_size(int fd, long long *size_out);
 extern int os_file_modtime(char *file, unsigned long *modtime);
 extern int os_pipe(int *fd, int stream, int close_on_exec);
 extern int os_set_fd_async(int fd, int owner);
+extern int os_clear_fd_async(int fd);
 extern int os_set_fd_block(int fd, int blocking);
 extern int os_accept_connection(int fd);
 extern int os_create_unix_socket(char *file, int len, int close_on_exec);
+extern int os_make_symlink(const char *to, const char *from);
+extern int os_read_symlink(const char *file, char *buf, int size);
+extern int os_link_file(const char *to, const char *from);
+extern int os_make_dir(const char *dir, int mode);
+extern int os_remove_dir(const char *dir);
+extern int os_make_dev(const char *name, int mode, int major, int minor);
 extern int os_shutdown_socket(int fd, int r, int w);
 extern void os_close_file(int fd);
 extern int os_rcv_fd(int fd, int *helper_pid_out);
@@ -165,6 +199,13 @@ extern int os_protect_memory(void *addr, unsigned long len,
                             int r, int w, int x);
 extern int os_unmap_memory(void *addr, int len);
 extern void os_flush_stdout(void);
+extern int os_stat_filesystem(char *path, long *bsize_out, 
+                             long long *blocks_out, long long *bfree_out,
+                             long long *bavail_out, long long *files_out,
+                             long long *ffree_out, void *fsid_out, 
+                             int fsid_size, long *namelen_out, 
+                             long *spare_out);
+extern unsigned long long os_usecs(void);
 
 #endif
 
index 9ddb749..6793a2f 100644 (file)
@@ -11,6 +11,7 @@ extern void switch_timers(int to_real);
 extern void set_interval(int timer_type);
 extern void idle_sleep(int secs);
 extern void enable_timer(void);
+extern void disable_timer(void);
 extern unsigned long time_lock(void);
 extern void time_unlock(unsigned long);
 
index e9cf19e..57ee9e2 100644 (file)
@@ -15,6 +15,8 @@ extern void kfree(void *ptr);
 extern int in_aton(char *str);
 extern int open_gdb_chan(void);
 extern int strlcpy(char *, const char *, int);
+extern void *um_vmalloc(int size);
+extern void vfree(void *ptr);
 
 #endif
 
index 5880128..ab089d7 100644 (file)
@@ -8,6 +8,8 @@
 
 #include "sysdep/ptrace.h"
 
+#define CATCH_EINTR(expr) while (((expr) < 0) && (errno == EINTR))
+
 extern int mode_tt;
 
 extern int grantpt(int __fd);
@@ -62,7 +64,6 @@ extern void set_cmdline(char *cmd);
 extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
 extern int get_pty(void);
 extern void *um_kmalloc(int size);
-extern int raw(int fd, int complain);
 extern int switcheroo(int fd, int prot, void *from, void *to, int size);
 extern void setup_machinename(char *machine_out);
 extern void setup_hostinfo(void);
@@ -73,7 +74,6 @@ extern void do_exec(int old_pid, int new_pid);
 extern void tracer_panic(char *msg, ...);
 extern char *get_umid(int only_if_set);
 extern void do_longjmp(void *p, int val);
-extern void suspend_new_thread(int fd);
 extern int detach(int pid, int sig);
 extern int attach(int pid);
 extern void kill_child_dead(int pid);
@@ -89,6 +89,8 @@ extern int arch_fixup(unsigned long address, void *sc_ptr);
 extern void forward_pending_sigio(int target);
 extern int can_do_skas(void);
 extern void arch_init_thread(void);
+extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
+extern int raw(int fd);
 
 #endif
 
index 70da5fa..6cce266 100644 (file)
@@ -5,13 +5,18 @@
 
 extra-y := vmlinux.lds.s
 
-obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
-       helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
-       physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
-       sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
-       syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
-       time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
-       um_arch.o umid.o user_util.o
+# Descend into ../util for make clean.  This is here because it doesn't work
+# in arch/um/Makefile.
+
+subdir- = ../util
+
+obj-y = checksum.o config.o exec_kern.o exitcode.o filehandle.o frame_kern.o \
+       frame.o helper.o init_task.o irq.o irq_user.o ksyms.o mem.o \
+       mem_user.o physmem.o process.o process_kern.o ptrace.o reboot.o \
+       resource.o sigio_user.o sigio_kern.o signal_kern.o signal_user.o \
+       smp.o syscall_kern.o syscall_user.o sysrq.o sys_call_table.o \
+       tempfile.o time.o time_kern.o tlb.o trap_kern.o trap_user.o \
+       uaccess_user.o um_arch.o umid.o user_util.o
 
 obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
 obj-$(CONFIG_GPROF)    += gprof_syms.o
index c18386a..4b349f2 100644 (file)
@@ -21,6 +21,7 @@
 #include "sysdep/sigcontext.h"
 #include "frame_user.h"
 #include "kern_util.h"
+#include "user_util.h"
 #include "ptrace_user.h"
 #include "os.h"
 
@@ -40,7 +41,7 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
        /* Wait for it to stop itself and continue it with a SIGUSR1 to force 
         * it into the signal handler.
         */
-       n = waitpid(pid, &status, WUNTRACED);
+       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if(n < 0){
                printf("capture_stack : waitpid failed - errno = %d\n", errno);
                exit(1);
@@ -60,7 +61,7 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
         * At this point, the handler has stuffed the addresses of
         * sig, sc, and SA_RESTORER in raw.
         */
-       n = waitpid(pid, &status, WUNTRACED);
+       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if(n < 0){
                printf("capture_stack : waitpid failed - errno = %d\n", errno);
                exit(1);
@@ -82,7 +83,8 @@ static int capture_stack(int (*child)(void *arg), void *arg, void *sp,
                       errno);
                exit(1);
        }
-       if(waitpid(pid, &status, 0) < 0){
+       CATCH_EINTR(n = waitpid(pid, &status, 0));
+       if(n < 0){
                printf("capture_stack : waitpid failed - errno = %d\n", errno);
                exit(1);
        }
index 6d0a1f9..29cceb0 100644 (file)
@@ -12,6 +12,7 @@
 #include <sys/wait.h>
 #include "user.h"
 #include "kern_util.h"
+#include "user_util.h"
 #include "os.h"
 
 struct helper_data {
@@ -93,24 +94,20 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
        if(n < 0){
                printk("run_helper : read on pipe failed, err = %d\n", -n);
                err = n;
-               goto out_kill;
+               os_kill_process(pid, 1);
        }
        else if(n != 0){
-               waitpid(pid, NULL, 0);
+               CATCH_EINTR(n = waitpid(pid, NULL, 0));
                pid = -errno;
        }
+       err = pid;
 
-       if(stack_out == NULL) free_stack(stack, 0);
-        else *stack_out = stack;
-       return(pid);
-
- out_kill:
-       os_kill_process(pid, 1);
  out_close:
        os_close_file(fds[0]);
-       os_close_file(fds[1]);
  out_free:
-       free_stack(stack, 0);
+       if(stack_out == NULL) 
+               free_stack(stack, 0);
+        else *stack_out = stack;
        return(err);
 }
 
index 87ac2b0..38e66ac 100644 (file)
@@ -364,6 +364,20 @@ void deactivate_fd(int fd, int irqnum)
        irq_unlock(flags);
 }
 
+int deactivate_all_fds(void)
+{
+       struct irq_fd *irq;
+       int err;
+
+       for(irq=active_fds;irq != NULL;irq = irq->next){
+               err = os_clear_fd_async(irq->fd);
+               if(err)
+                       return(err);
+       }
+
+       return(0);
+}
+
 void forward_ipi(int fd, int pid)
 {
        int err;
index 4ed2807..cb12aa8 100644 (file)
@@ -50,11 +50,13 @@ EXPORT_SYMBOL(handle_page_fault);
 EXPORT_SYMBOL(find_iomem);
 
 #ifdef CONFIG_MODE_TT
+EXPORT_SYMBOL(strncpy_from_user_tt);
 EXPORT_SYMBOL(copy_from_user_tt);
 EXPORT_SYMBOL(copy_to_user_tt);
 #endif
 
 #ifdef CONFIG_MODE_SKAS
+EXPORT_SYMBOL(strncpy_from_user_skas);
 EXPORT_SYMBOL(copy_to_user_skas);
 EXPORT_SYMBOL(copy_from_user_skas);
 #endif
index c52744b..b6d6a61 100644 (file)
@@ -143,7 +143,7 @@ static int __init parse_iomem(char *str, int *add)
        struct iomem_region *new;
        struct uml_stat buf;
        char *file, *driver;
-       int fd, err;
+       int fd, err, size;
 
        driver = str;
        file = strchr(str,',');
@@ -171,10 +171,12 @@ static int __init parse_iomem(char *str, int *add)
                goto out_close;
        }
 
+       size = (buf.ust_size + UM_KERN_PAGE_SIZE) & ~(UM_KERN_PAGE_SIZE - 1);
+
        *new = ((struct iomem_region) { .next           = iomem_regions,
                                        .driver         = driver,
                                        .fd             = fd,
-                                       .size           = buf.ust_size,
+                                       .size           = size,
                                        .phys           = 0,
                                        .virt           = 0 });
        iomem_regions = new;
@@ -206,6 +208,39 @@ int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
        return(0);
 }
 
+#if 0
+/* Debugging facility for dumping stuff out to the host, avoiding the timing
+ * problems that come with printf and breakpoints.
+ * Enable in case of emergency.
+ */
+
+int logging = 1;
+int logging_fd = -1;
+
+int logging_line = 0;
+char logging_buf[512];
+
+void log(char *fmt, ...)
+{
+        va_list ap;
+        struct timeval tv;
+        struct openflags flags;
+
+        if(logging == 0) return;
+        if(logging_fd < 0){
+                flags = of_create(of_trunc(of_rdwr(OPENFLAGS())));
+                logging_fd = os_open_file("log", flags, 0644);
+        }
+        gettimeofday(&tv, NULL);
+        sprintf(logging_buf, "%d\t %u.%u  ", logging_line++, tv.tv_sec, 
+                tv.tv_usec);
+        va_start(ap, fmt);
+        vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
+        va_end(ap);
+        write(logging_fd, logging_buf, strlen(logging_buf));
+}
+#endif
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/mprot.h b/arch/um/kernel/mprot.h
deleted file mode 100644 (file)
index 83dc8cc..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __MPROT_H__
-#define __MPROT_H__
-
-extern void no_access(unsigned long addr, unsigned int len);
-
-#endif
index 01ad098..694a9c9 100644 (file)
@@ -45,7 +45,7 @@ void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
        int flags = 0, pages;
 
        if(sig_stack != NULL){
-               pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2;
+               pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
                set_sigstack(sig_stack, pages * page_size());
                flags = SA_ONSTACK;
        }
@@ -56,11 +56,7 @@ void init_new_thread_signals(int altstack)
 {
        int flags = altstack ? SA_ONSTACK : 0;
 
-       /* NODEFER is set here because SEGV isn't turned back on when the 
-        * handler is ready to receive signals.  This causes any segfault
-        * during a copy_user to kill the process because the fault is blocked.
-        */
-       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
+       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags, 
                    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 
                    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
@@ -73,7 +69,7 @@ void init_new_thread_signals(int altstack)
        set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, 
                    SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
-                   SA_NOMASK | flags, -1);
+                   flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
        signal(SIGHUP, SIG_IGN);
 
        init_irq_signals(altstack);
@@ -123,10 +119,14 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
 
        /* Start the process and wait for it to kill itself */
        new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
-       if(new_pid < 0) return(-errno);
-       while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ;
-       if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
-                         errno);
+       if(new_pid < 0) 
+               return(new_pid);
+
+       CATCH_EINTR(err = waitpid(new_pid, &status, 0));
+       if(err < 0) 
+               panic("Waiting for outer trampoline failed - errno = %d", 
+                     errno);
+
        if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
                panic("outer trampoline didn't exit with SIGKILL, "
                      "status = %d", status);
@@ -134,16 +134,6 @@ int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
        return(arg.pid);
 }
 
-void suspend_new_thread(int fd)
-{
-       char c;
-
-       os_stop_process(os_getpid());
-
-       if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
-               panic("read failed in suspend_new_thread");
-}
-
 static int ptrace_child(void *arg)
 {
        int pid = os_getpid();
@@ -170,7 +160,7 @@ static int start_ptraced_child(void **stack_out)
        pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
        if(pid < 0)
                panic("check_ptrace : clone failed, errno = %d", errno);
-       n = waitpid(pid, &status, WUNTRACED);
+       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if(n < 0)
                panic("check_ptrace : wait failed, errno = %d", errno);
        if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
@@ -187,7 +177,7 @@ static void stop_ptraced_child(int pid, void *stack, int exitcode)
 
        if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
                panic("check_ptrace : ptrace failed, errno = %d", errno);
-       n = waitpid(pid, &status, 0);
+       CATCH_EINTR(n = waitpid(pid, &status, 0));
        if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode))
                panic("check_ptrace : child exited with status 0x%x", status);
 
@@ -207,7 +197,7 @@ void __init check_ptrace(void)
                if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
                        panic("check_ptrace : ptrace failed, errno = %d", 
                              errno);
-               n = waitpid(pid, &status, WUNTRACED);
+               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
                if(n < 0)
                        panic("check_ptrace : wait failed, errno = %d", errno);
                if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
@@ -231,7 +221,7 @@ void __init check_ptrace(void)
 
 int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
 {
-       jmp_buf buf;
+       sigjmp_buf buf;
        int n;
 
        *jmp_ptr = &buf;
index ea000e6..8eb2d3b 100644 (file)
@@ -16,6 +16,7 @@
 #include "linux/module.h"
 #include "linux/init.h"
 #include "linux/capability.h"
+#include "linux/vmalloc.h"
 #include "linux/spinlock.h"
 #include "asm/unistd.h"
 #include "asm/mman.h"
@@ -164,8 +165,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
                struct pt_regs *regs)
 {
        p->thread = (struct thread_struct) INIT_THREAD;
-       p->thread.kernel_stack = 
-               (unsigned long) p->thread_info + 2 * PAGE_SIZE;
        return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, 
                                clone_flags, sp, stack_top, p, regs));
 }
@@ -301,6 +300,11 @@ void *um_kmalloc_atomic(int size)
        return(kmalloc(size, GFP_ATOMIC));
 }
 
+void *um_vmalloc(int size)
+{
+       return(vmalloc(size));
+}
+
 unsigned long get_fault_addr(void)
 {
        return((unsigned long) current->thread.fault_addr);
@@ -320,8 +324,7 @@ int user_context(unsigned long sp)
        unsigned long stack;
 
        stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER);
-       stack += 2 * PAGE_SIZE;
-       return(stack != current->thread.kernel_stack);
+       return(stack != (unsigned long) current_thread);
 }
 
 extern void remove_umid_dir(void);
index 92658ea..2cb3911 100644 (file)
@@ -16,7 +16,7 @@
 /* Protected by sigio_lock() called from write_sigio_workaround */
 static int sigio_irq_fd = -1;
 
-irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
+static irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
 {
        read_sigio_fd(sigio_irq_fd);
        reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
@@ -25,10 +25,14 @@ irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
 
 int write_sigio_irq(int fd)
 {
-       if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
-                         SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", 
-                         NULL)){
-               printk("write_sigio_irq : um_request_irq failed\n");
+       int err;
+
+       err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
+                            SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", 
+                            NULL);
+       if(err){
+               printk("write_sigio_irq : um_request_irq failed, err = %d\n",
+                      err);
                return(-1);
        }
        sigio_irq_fd = fd;
index 6a9b389..80fe2cd 100644 (file)
@@ -16,6 +16,7 @@
 #include "init.h"
 #include "user.h"
 #include "kern_util.h"
+#include "user_util.h"
 #include "sigio.h"
 #include "helper.h"
 #include "os.h"
@@ -50,7 +51,6 @@ static void openpty_cb(void *arg)
 void __init check_one_sigio(void (*proc)(int, int))
 {
        struct sigaction old, new;
-       struct termios tt;
        struct openpty_arg pty = { .master = -1, .slave = -1 };
        int master, slave, err;
 
@@ -68,12 +68,10 @@ void __init check_one_sigio(void (*proc)(int, int))
                return;
        }
 
-       /* XXX These can fail with EINTR */
-       if(tcgetattr(master, &tt) < 0)
-               panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
-       cfmakeraw(&tt);
-       if(tcsetattr(master, TCSADRAIN, &tt) < 0)
-               panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
+       /* Not now, but complain so we now where we failed. */
+       err = raw(master);
+       if (err < 0)
+               panic("check_sigio : __raw failed, errno = %d\n", -err);
 
        err = os_sigio_async(master, slave);
        if(err < 0)
index c9942b6..d50633a 100644 (file)
@@ -11,6 +11,7 @@
 #include <sys/ptrace.h>
 #include "user.h"
 #include "kern_util.h"
+#include "user_util.h"
 #include "os.h"
 #include "time_user.h"
 
@@ -26,7 +27,7 @@ static int user_thread_tramp(void *arg)
 
 int user_thread(unsigned long stack, int flags)
 {
-       int pid, status;
+       int pid, status, err;
 
        pid = clone(user_thread_tramp, (void *) stack_sp(stack), 
                    flags | CLONE_FILES | SIGCHLD, NULL);
@@ -35,7 +36,8 @@ int user_thread(unsigned long stack, int flags)
                return(pid);
        }
 
-       if(waitpid(pid, &status, WUNTRACED) < 0){
+       CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
+       if(err < 0){
                printk("user_thread - waitpid failed, errno = %d\n", errno);
                return(-errno);
        }
index aa16dc0..ca5b840 100644 (file)
@@ -6,6 +6,8 @@
 #ifndef __MODE_SKAS_H__
 #define __MODE_SKAS_H__
 
+#include <sysdep/ptrace.h>
+
 extern unsigned long exec_regs[];
 extern unsigned long exec_fp_regs[];
 extern unsigned long exec_fpx_regs[];
index 7e48986..a1a6b8d 100644 (file)
@@ -78,7 +78,7 @@ static void handle_trap(int pid, union uml_pt_regs *regs)
                panic("handle_trap - continuing to end of syscall failed, "
                      "errno = %d\n", errno);
 
-       err = waitpid(pid, &status, WUNTRACED);
+       CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
        if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
                panic("handle_trap - failed to wait at end of syscall, "
                      "errno = %d, status = %d\n", errno, status);
@@ -117,7 +117,7 @@ void start_userspace(int cpu)
                panic("start_userspace : clone failed, errno = %d", errno);
 
        do {
-               n = waitpid(pid, &status, WUNTRACED);
+               CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
                if(n < 0)
                        panic("start_userspace : wait failed, errno = %d", 
                              errno);
@@ -144,7 +144,7 @@ void userspace(union uml_pt_regs *regs)
                panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
                       errno);
        while(1){
-               err = waitpid(pid, &status, WUNTRACED);
+               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
                if(err < 0)
                        panic("userspace - waitpid failed, errno = %d\n", 
                              errno);
@@ -190,7 +190,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
                void (*handler)(int))
 {
        unsigned long flags;
-       jmp_buf switch_buf, fork_buf;
+       sigjmp_buf switch_buf, fork_buf;
 
        *switch_buf_ptr = &switch_buf;
        *fork_buf_ptr = &fork_buf;
@@ -214,7 +214,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
 
 void thread_wait(void *sw, void *fb)
 {
-       jmp_buf buf, **switch_buf = sw, *fork_buf;
+       sigjmp_buf buf, **switch_buf = sw, *fork_buf;
 
        *switch_buf = &buf;
        fork_buf = fb;
@@ -276,23 +276,23 @@ void restore_registers(union uml_pt_regs *regs)
 
 void switch_threads(void *me, void *next)
 {
-       jmp_buf my_buf, **me_ptr = me, *next_buf = next;
+       sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
        
        *me_ptr = &my_buf;
        if(sigsetjmp(my_buf, 1) == 0)
                siglongjmp(*next_buf, 1);
 }
 
-static jmp_buf initial_jmpbuf;
+static sigjmp_buf initial_jmpbuf;
 
 /* XXX Make these percpu */
 static void (*cb_proc)(void *arg);
 static void *cb_arg;
-static jmp_buf *cb_back;
+static sigjmp_buf *cb_back;
 
 int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
 {
-       jmp_buf **switch_buf = switch_buf_ptr;
+       sigjmp_buf **switch_buf = switch_buf_ptr;
        int n;
 
        *fork_buf_ptr = &initial_jmpbuf;
@@ -328,7 +328,7 @@ void remove_sigstack(void)
 
 void initial_thread_cb_skas(void (*proc)(void *), void *arg)
 {
-       jmp_buf here;
+       sigjmp_buf here;
 
        cb_proc = proc;
        cb_arg = arg;
@@ -356,28 +356,6 @@ void reboot_skas(void)
        siglongjmp(initial_jmpbuf, 4);
 }
 
-int new_mm(int from)
-{
-       struct proc_mm_op copy;
-       int n, fd = os_open_file("/proc/mm", 
-                                of_cloexec(of_write(OPENFLAGS())), 0);
-
-       if(fd < 0)
-               return(fd);
-
-       if(from != -1){
-               copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
-                                             .u        = 
-                                             { .copy_segments  = from } } );
-               n = os_write_file(fd, &copy, sizeof(copy));
-               if(n != sizeof(copy)) 
-                       printk("new_mm : /proc/mm copy_segments failed, "
-                              "err = %d\n", -n);
-       }
-
-       return(fd);
-}
-
 void switch_mm_skas(int mm_fd)
 {
        int err;
index ec62366..e16309d 100644 (file)
@@ -16,6 +16,8 @@
 #include "frame.h"
 #include "kern.h"
 #include "mode.h"
+#include "filehandle.h"
+#include "proc_mm.h"
 
 int singlestepping_skas(void)
 {
@@ -130,12 +132,33 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
                handler = new_thread_handler;
        }
 
-       new_thread((void *) p->thread.kernel_stack, 
-                  &p->thread.mode.skas.switch_buf, 
+       new_thread(p->thread_info, &p->thread.mode.skas.switch_buf, 
                   &p->thread.mode.skas.fork_buf, handler);
        return(0);
 }
 
+int new_mm(int from)
+{
+       struct proc_mm_op copy;
+       int n, fd;
+
+       fd = open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
+       if(fd < 0)
+               return(fd);
+
+       if(from != -1){
+               copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
+                                             .u        = 
+                                             { .copy_segments  = from } } );
+               n = os_write_file(fd, &copy, sizeof(copy));
+               if(n != sizeof(copy)) 
+                       printk("new_mm : /proc/mm copy_segments failed, "
+                              "err = %d\n", -n);
+       }
+
+       return(fd);
+}
+
 void init_idle_skas(void)
 {
        cpu_tasks[current_thread->cpu].pid = os_getpid();
@@ -164,13 +187,13 @@ int start_uml_skas(void)
 {
        start_userspace(0);
        capture_signal_stack();
-       uml_idle_timer();
 
        init_new_thread_signals(1);
+       uml_idle_timer();
 
        init_task.thread.request.u.thread.proc = start_kernel_proc;
        init_task.thread.request.u.thread.arg = NULL;
-       return(start_idle_thread((void *) init_task.thread.kernel_stack,
+       return(start_idle_thread(init_task.thread_info,
                                 &init_task.thread.mode.skas.switch_buf,
                                 &init_task.thread.mode.skas.fork_buf));
 }
index 2c47e78..9659370 100644 (file)
@@ -19,8 +19,10 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
        struct skas_regs *r;
        struct signal_info *info;
        int save_errno = errno;
+       int save_user;
 
        r = &TASK_REGS(get_current())->skas;
+       save_user = r->is_user;
        r->is_user = 0;
        r->fault_addr = SC_FAULT_ADDR(sc);
        r->fault_type = SC_FAULT_TYPE(sc);
@@ -33,6 +35,7 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
        (*info->handler)(sig, (union uml_pt_regs *) r);
 
        errno = save_errno;
+       r->is_user = save_user;
 }
 
 void user_signal(int sig, union uml_pt_regs *regs)
index 7c9737c..6ffb4d0 100644 (file)
@@ -39,14 +39,6 @@ EXPORT_SYMBOL(cpu_online_map);
  */
 struct cpuinfo_um cpu_data[NR_CPUS];
 
-spinlock_t um_bh_lock = SPIN_LOCK_UNLOCKED;
-
-atomic_t global_bh_count;
-
-/* Not used by UML */
-unsigned char global_irq_holder = NO_PROC_ID;
-unsigned volatile long global_irq_lock;
-
 /* Set when the idlers are all forked */
 int smp_threads_ready = 0;
 
@@ -65,41 +57,6 @@ void smp_send_reschedule(int cpu)
        num_reschedules_sent++;
 }
 
-static void show(char * str)
-{
-       int cpu = smp_processor_id();
-
-       printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu);
-}
-       
-#define MAXCOUNT 100000000
-
-static inline void wait_on_bh(void)
-{
-       int count = MAXCOUNT;
-       do {
-               if (!--count) {
-                       show("wait_on_bh");
-                       count = ~0;
-               }
-               /* nothing .. wait for the other bh's to go away */
-       } while (atomic_read(&global_bh_count) != 0);
-}
-
-/*
- * This is called when we want to synchronize with
- * bottom half handlers. We need to wait until
- * no other CPU is executing any bottom half handler.
- *
- * Don't wait if we're already running in an interrupt
- * context or are inside a bh handler. 
- */
-void synchronize_bh(void)
-{
-       if (atomic_read(&global_bh_count) && !in_interrupt())
-               wait_on_bh();
-}
-
 void smp_send_stop(void)
 {
        int i;
@@ -159,8 +116,7 @@ static struct task_struct *idle_thread(int cpu)
                            .task =     new_task } );
        idle_threads[cpu] = new_task;
        CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, 
-                         sizeof(c)),
-                   ({ panic("skas mode doesn't support SMP"); }));
+                                 sizeof(c)),
        wake_up_forked_process(new_task);
        return(new_task);
 }
index fa0b710..a6e7ff3 100644 (file)
@@ -53,6 +53,15 @@ void enable_timer(void)
                       errno);
 }
 
+void disable_timer(void)
+{
+       struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
+       if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) ||
+          (setitimer(ITIMER_REAL, &disable, NULL) < 0))
+               printk("disnable_timer - setitimer failed, errno = %d\n",
+                      errno);
+}
+
 void switch_timers(int to_real)
 {
        struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }});
@@ -85,49 +94,12 @@ void uml_idle_timer(void)
        set_interval(ITIMER_REAL);
 }
 
-static unsigned long long get_host_hz(void)
-{
-       char mhzline[16], *end;
-       unsigned long long mhz;
-       int ret, mult, rest, len;
-
-       ret = cpu_feature("cpu MHz", mhzline, 
-                         sizeof(mhzline) / sizeof(mhzline[0]));
-       if(!ret)
-               panic ("Could not get host MHZ");
-
-       mhz = strtoul(mhzline, &end, 10);
-
-       /* This business is to parse a floating point number without using
-        * floating types.
-        */
-
-       rest = 0;
-       mult = 0;
-       if(*end == '.'){
-               end++;
-               len = strlen(end);
-               if(len < 6)
-                       mult = 6 - len;
-               else if(len > 6)
-                       end[6] = '\0';
-               rest = strtoul(end, NULL, 10);
-               while(mult-- > 0)
-                       rest *= 10;
-       }
-
-       return(1000000 * mhz + rest);
-}
-
-unsigned long long host_hz = 0;
-
 extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
 
 void time_init(void)
 {
        struct timespec now;
  
-       host_hz = get_host_hz();
        if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
                panic("Couldn't set SIGVTALRM handler");
        set_interval(ITIMER_VIRTUAL);
index 7209ba5..c36bff0 100644 (file)
@@ -20,6 +20,7 @@
 #include "user_util.h"
 #include "time_user.h"
 #include "mode.h"
+#include "os.h"
 
 u64 jiffies_64;
 
@@ -42,10 +43,10 @@ unsigned long long sched_clock(void)
 int timer_irq_inited = 0;
 
 static int first_tick;
-static unsigned long long prev_tsc;
+static unsigned long long prev_usecs;
 static long long delta;                /* Deviation per interval */
 
-extern unsigned long long host_hz;
+#define MILLION 1000000
 
 void timer_irq(union uml_pt_regs *regs)
 {
@@ -60,21 +61,24 @@ void timer_irq(union uml_pt_regs *regs)
 
        if(first_tick){
 #if defined(CONFIG_UML_REAL_TIME_CLOCK)
-               unsigned long long tsc;
                /* We've had 1 tick */
-               tsc = time_stamp();
+               unsigned long long usecs = os_usecs();
 
-               delta += tsc - prev_tsc;
-               prev_tsc = tsc;
+               delta += usecs - prev_usecs;
+               prev_usecs = usecs;
 
-               ticks += (delta * HZ) / host_hz;
-               delta -= (ticks * host_hz) / HZ;
+               /* Protect against the host clock being set backwards */
+               if(delta < 0)
+                       delta = 0;
+
+               ticks += (delta * HZ) / MILLION;
+               delta -= (ticks * MILLION) / HZ;
 #else
                ticks = 1;
 #endif
        }
        else {
-               prev_tsc = time_stamp();
+               prev_usecs = os_usecs();
                first_tick = 1;
        }
 
@@ -149,7 +153,7 @@ void __udelay(um_udelay_t usecs)
 {
        int i, n;
 
-       n = (loops_per_jiffy * HZ * usecs) / 1000000;
+       n = (loops_per_jiffy * HZ * usecs) / MILLION;
        for(i=0;i<n;i++) ;
 }
 
@@ -157,7 +161,7 @@ void __const_udelay(um_udelay_t usecs)
 {
        int i, n;
 
-       n = (loops_per_jiffy * HZ * usecs) / 1000000;
+       n = (loops_per_jiffy * HZ * usecs) / MILLION;
        for(i=0;i<n;i++) ;
 }
 
index 7b9fac0..443b828 100644 (file)
@@ -74,13 +74,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
                        err = -ENOMEM;
                        goto out_of_memory;
                default:
-                       if (current->pid == 1) {
-                               up_read(&mm->mmap_sem);
-                               yield();
-                               down_read(&mm->mmap_sem);
-                               goto survive;
-                       }
-                       goto out;
+                       BUG();
                }
                pte = pte_offset_kernel(pmd, page);
        } while(!pte_present(*pte));
@@ -103,7 +97,6 @@ out_of_memory:
                down_read(&mm->mmap_sem);
                goto survive;
        }
-       err = -ENOMEM;
        goto out;
 }
 
@@ -114,7 +107,7 @@ void register_remapper(struct remapper *info)
        list_add(&info->list, &physmem_remappers);
 }
 
-static int check_remapped_addr(unsigned long address, int is_write)
+static int check_remapped_addr(unsigned long address, int is_write, int is_user)
 {
        struct remapper *remapper;
        struct list_head *ele;
@@ -127,7 +120,7 @@ static int check_remapped_addr(unsigned long address, int is_write)
 
        list_for_each(ele, &physmem_remappers){
                remapper = list_entry(ele, struct remapper, list);
-               if((*remapper->proc)(fd, address, is_write, offset))
+               if((*remapper->proc)(fd, address, is_write, offset, is_user))
                        return(1);
        }
 
@@ -145,7 +138,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write,
                 flush_tlb_kernel_vm();
                 return(0);
         }
-       else if(check_remapped_addr(address & PAGE_MASK, is_write))
+       else if(check_remapped_addr(address & PAGE_MASK, is_write, is_user))
                return(0);
        else if(current->mm == NULL)
                panic("Segfault with no mm");
index 6744ca6..d12eac6 100644 (file)
@@ -32,7 +32,14 @@ void kill_child_dead(int pid)
 {
        kill(pid, SIGKILL);
        kill(pid, SIGCONT);
-       while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT);
+       do {
+               int n;
+               CATCH_EINTR(n = waitpid(pid, NULL, 0));
+               if (n > 0)
+                       kill(pid, SIGCONT);
+               else
+                       break;
+       } while(1);
 }
 
 /* Unlocked - don't care if this is a bit off */
@@ -120,7 +127,7 @@ void alarm_handler(int sig, struct sigcontext sc)
 
 void do_longjmp(void *b, int val)
 {
-       jmp_buf *buf = b;
+       sigjmp_buf *buf = b;
 
        siglongjmp(*buf, val);
 }
index d8e3bfe..065b504 100644 (file)
@@ -14,6 +14,7 @@
 #include "kern_util.h"
 #include "irq_user.h"
 #include "time_user.h"
+#include "signal_user.h"
 #include "mem_user.h"
 #include "os.h"
 #include "tlb.h"
@@ -39,8 +40,7 @@ void flush_thread_tt(void)
                do_exit(SIGKILL);
        }
                
-       new_pid = start_fork_tramp((void *) current->thread.kernel_stack,
-                                  stack, 0, exec_tramp);
+       new_pid = start_fork_tramp(current->thread_info, stack, 0, exec_tramp);
        if(new_pid < 0){
                printk(KERN_ERR 
                       "flush_thread : new thread failed, errno = %d\n",
@@ -54,7 +54,9 @@ void flush_thread_tt(void)
        current->thread.request.u.exec.pid = new_pid;
        unprotect_stack((unsigned long) current_thread);
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
 
+       change_sig(SIGUSR1, 0);
        enable_timer();
        free_page(stack);
        protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
index 35d1082..6d5fa82 100644 (file)
 void do_exec(int old_pid, int new_pid)
 {
        unsigned long regs[FRAME_SIZE];
+       int err;
 
        if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
-          (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) ||
-          (waitpid(new_pid, 0, WUNTRACED) < 0))
+          (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0))
                tracer_panic("do_exec failed to attach proc - errno = %d",
                             errno);
 
+       CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
+       if (err < 0)
+               tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
+                            errno);
+
        if(ptrace_getregs(old_pid, regs) < 0)
                tracer_panic("do_exec failed to get registers - errno = %d",
                             errno);
index 2bdbdab..177cb24 100644 (file)
@@ -116,6 +116,17 @@ void exit_thread_tt(void)
        os_close_file(current->thread.mode.tt.switch_pipe[1]);
 }
 
+void suspend_new_thread(int fd)
+{
+       int err;
+       char c;
+
+       os_stop_process(os_getpid());
+       err = os_read_file(fd, &c, sizeof(c));
+       if(err != sizeof(c))
+               panic("read failed in suspend_new_thread, err = %d", -err);
+}
+
 void schedule_tail(task_t *prev);
 
 static void new_thread_handler(int sig)
@@ -150,6 +161,12 @@ static void new_thread_handler(int sig)
        local_irq_enable();
        if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
                do_exit(0);
+       
+       /* XXX No set_user_mode here because a newly execed process will
+        * immediately segfault on its non-existent IP, coming straight back
+        * to the signal handler, which will call set_user_mode on its way
+        * out.  This should probably change since it's confusing.
+        */
 }
 
 static int new_thread_proc(void *stack)
@@ -172,6 +189,7 @@ static int new_thread_proc(void *stack)
        local_irq_disable();
        init_new_thread_stack(stack, new_thread_handler);
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
        return(0);
 }
 
@@ -215,6 +233,7 @@ int fork_tramp(void *stack)
        init_new_thread_stack(stack, finish_fork_handler);
 
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
        return(0);
 }
 
@@ -236,7 +255,7 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
        err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
        if(err < 0){
                printk("copy_thread : pipe failed, err = %d\n", -err);
-               return(err);
+               goto out;
        }
 
        stack = alloc_stack(0, 0);
@@ -248,8 +267,7 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
 
        clone_flags &= CLONE_VM;
        p->thread.temp_stack = stack;
-       new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack,
-                                  clone_flags, tramp);
+       new_pid = start_fork_tramp(p->thread_info, stack, clone_flags, tramp);
        if(new_pid < 0){
                printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", 
                       -new_pid);
@@ -267,19 +285,30 @@ int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
        current->thread.request.op = OP_FORK;
        current->thread.request.u.fork.pid = new_pid;
        os_usr1_process(os_getpid());
-       return(0);
+
+       /* Enable the signal and then disable it to ensure that it is handled
+        * here, and nowhere else.
+        */
+       change_sig(SIGUSR1, 1);
+
+       change_sig(SIGUSR1, 0);
+       err = 0;
+ out:
+       return(err);
 }
 
 void reboot_tt(void)
 {
        current->thread.request.op = OP_REBOOT;
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
 }
 
 void halt_tt(void)
 {
        current->thread.request.op = OP_HALT;
        os_usr1_process(os_getpid());
+       change_sig(SIGUSR1, 1);
 }
 
 void kill_off_processes_tt(void)
@@ -306,6 +335,9 @@ void initial_thread_cb_tt(void (*proc)(void *), void *arg)
                current->thread.request.u.cb.proc = proc;
                current->thread.request.u.cb.arg = arg;
                os_usr1_process(os_getpid());
+               change_sig(SIGUSR1, 1);
+
+               change_sig(SIGUSR1, 0);
        }
 }
 
@@ -475,7 +507,7 @@ void set_init_pid(int pid)
 
        init_task.thread.mode.tt.extern_pid = pid;
        err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
-       if(err) 
+       if(err)
                panic("Can't create switch pipe for init_task, errno = %d", 
                      -err);
 }
@@ -501,9 +533,9 @@ int start_uml_tt(void)
        void *sp;
        int pages;
 
-       pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2;
-       sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE - 
-               sizeof(unsigned long);
+       pages = (1 << CONFIG_KERNEL_STACK_ORDER);
+       sp = (void *) ((unsigned long) init_task.thread_info) + 
+               pages * PAGE_SIZE - sizeof(unsigned long);
        return(tracer(start_kernel_proc, sp));
 }
 
index de417c4..458ecf9 100644 (file)
@@ -272,7 +272,7 @@ void fake_child_exit(void)
 
        child_proxy(1, W_EXITCODE(0, 0));
        while(debugger.waiting == 1){
-               pid = waitpid(debugger.pid, &status, WUNTRACED);
+               CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
                if(pid != debugger.pid){
                        printk("fake_child_exit - waitpid failed, "
                               "errno = %d\n", errno);
@@ -280,7 +280,7 @@ void fake_child_exit(void)
                }
                debugger_proxy(status, debugger.pid);
        }
-       pid = waitpid(debugger.pid, &status, WUNTRACED);
+       CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
        if(pid != debugger.pid){
                printk("fake_child_exit - waitpid failed, "
                       "errno = %d\n", errno);
index 3271e6a..1b54774 100644 (file)
@@ -192,7 +192,7 @@ int tracer(int (*init_proc)(void *), void *sp)
        printf("tracing thread pid = %d\n", tracing_pid);
 
        pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
-       n = waitpid(pid, &status, WUNTRACED);
+       CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
        if(n < 0){
                printf("waitpid on idle thread failed, errno = %d\n", errno);
                exit(1);
@@ -233,7 +233,7 @@ int tracer(int (*init_proc)(void *), void *sp)
        }
        set_cmdline("(tracing thread)");
        while(1){
-               pid = waitpid(-1, &status, WUNTRACED);
+               CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
                if(pid <= 0){
                        if(errno != ECHILD){
                                printf("wait failed - errno = %d\n", errno);
index 7a6dbf5..00bacac 100644 (file)
@@ -23,6 +23,13 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
 
        unprotect_kernel_mem();
 
+       /* This is done because to allow SIGSEGV to be delivered inside a SEGV
+        * handler.  This can happen in copy_user, and if SEGV is disabled,
+        * the process will die.
+        */
+       if(sig == SIGSEGV)
+               change_sig(SIGSEGV, 1);
+
        r = &TASK_REGS(get_current())->tt;
        save_regs = *r;
        is_user = user_context(SC_SP(sc));
@@ -30,7 +37,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
        if(sig != SIGUSR2) 
                r->syscall = -1;
 
-       change_sig(SIGUSR1, 1);
        info = &sig_info[sig];
        if(!info->is_irq) unblock_signals();
 
@@ -39,7 +45,6 @@ void sig_handler_common_tt(int sig, void *sc_ptr)
        if(is_user){
                interrupt_end();
                block_signals();
-               change_sig(SIGUSR1, 0);
                set_user_mode(NULL);
        }
        *r = save_regs;
index f084f0c..f014755 100644 (file)
@@ -72,7 +72,7 @@ int __do_strnlen_user(const char *str, unsigned long n,
        struct tt_regs save = TASK_REGS(get_current())->tt;
        int ret;
        unsigned long *faddrp = (unsigned long *)fault_addr;
-       jmp_buf jbuf;
+       sigjmp_buf jbuf;
 
        *fault_catcher = &jbuf;
        if(sigsetjmp(jbuf, 1) == 0)
index be0dec5..148b86a 100644 (file)
@@ -205,6 +205,8 @@ static int __init set_tty_log_fd(char *name, int *add)
                printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
                tty_log_fd = -1;
        }
+
+       *add = 0;
        return 0;
 }
 
index fc07951..d035257 100644 (file)
@@ -18,7 +18,7 @@ unsigned long __do_user_copy(void *to, const void *from, int n,
 {
        unsigned long *faddrp = (unsigned long *) fault_addr, ret;
 
-       jmp_buf jbuf;
+       sigjmp_buf jbuf;
        *fault_catcher = &jbuf;
        if(sigsetjmp(jbuf, 1) == 0){
                (*op)(to, from, n);
index 18a4a76..802b7fb 100644 (file)
@@ -27,7 +27,6 @@
 #include "user_util.h"
 #include "kern_util.h"
 #include "kern.h"
-#include "mprot.h"
 #include "mem_user.h"
 #include "mem.h"
 #include "umid.h"
@@ -306,7 +305,7 @@ unsigned long end_iomem;
 
 int linux_main(int argc, char **argv)
 {
-       unsigned long avail;
+       unsigned long avail, diff;
        unsigned long virtmem_size, max_physmem;
        unsigned int i, add;
 
@@ -324,6 +323,16 @@ int linux_main(int argc, char **argv)
 
        brk_start = (unsigned long) sbrk(0);
        CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start);
+       /* Increase physical memory size for exec-shield users
+       so they actually get what they asked for. This should
+       add zero for non-exec shield users */
+       
+       diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
+       if(diff > 1024 * 1024){
+               printf("Adding %ld bytes to physical memory to account for "
+                      "exec-shield gap\n", diff);
+               physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
+       }
 
        uml_physmem = uml_start;
 
@@ -380,9 +389,6 @@ int linux_main(int argc, char **argv)
 
        uml_postsetup();
 
-       init_task.thread.kernel_stack = (unsigned long) &init_thread_info + 
-               2 * PAGE_SIZE;
-
        task_protections((unsigned long) &init_thread_info);
        os_flush_stdout();
 
index 645fbfe..f609e11 100644 (file)
@@ -43,7 +43,7 @@ static int __init set_umid(char *name, int is_random,
        }
 
        if(strlen(name) > UMID_LEN - 1)
-               (*printer)("Unique machine name is being truncated to %s "
+               (*printer)("Unique machine name is being truncated to %d "
                           "characters\n", UMID_LEN);
        strlcpy(umid, name, sizeof(umid));
 
@@ -54,6 +54,7 @@ static int __init set_umid(char *name, int is_random,
 
 static int __init set_umid_arg(char *name, int *add)
 {
+       *add = 0;
        return(set_umid(name, 0, printf));
 }
 
@@ -199,17 +200,20 @@ int not_dead_yet(char *dir)
 static int __init set_uml_dir(char *name, int *add)
 {
        if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
-               uml_dir = malloc(strlen(name) + 1);
+               uml_dir = malloc(strlen(name) + 2);
                if(uml_dir == NULL){
                        printf("Failed to malloc uml_dir - error = %d\n",
                               errno);
                        uml_dir = name;
+                       /* Return 0 here because do_initcalls doesn't look at
+                        * the return value.
+                        */
                        return(0);
                }
                sprintf(uml_dir, "%s/", name);
        }
        else uml_dir = name;
-       return 0;
+       return(0);
 }
 
 static int __init make_uml_dir(void)
index d646f1d..1e7c1f1 100644 (file)
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <limits.h>
+#include <setjmp.h>
 #include <sys/mman.h> 
 #include <sys/stat.h>
 #include <sys/ptrace.h>
@@ -80,20 +81,19 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay)
        int status, ret;
 
        while(1){
-               ret = waitpid(pid, &status, WUNTRACED);
+               CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
                if((ret < 0) ||
                   !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
                        if(ret < 0){
-                               if(errno == EINTR) continue;
                                printk("wait failed, errno = %d\n",
                                       errno);
                        }
                        else if(WIFEXITED(status)) 
-                               printk("process exited with status %d\n", 
-                                      WEXITSTATUS(status));
+                               printk("process %d exited with status %d\n", 
+                                      pid, WEXITSTATUS(status));
                        else if(WIFSIGNALED(status))
-                               printk("process exited with signal %d\n", 
-                                      WTERMSIG(status));
+                               printk("process %d exited with signal %d\n", 
+                                      pid, WTERMSIG(status));
                        else if((WSTOPSIG(status) == SIGVTALRM) ||
                                (WSTOPSIG(status) == SIGALRM) ||
                                (WSTOPSIG(status) == SIGIO) ||
@@ -109,8 +109,8 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay)
                                ptrace(cont_type, pid, 0, WSTOPSIG(status));
                                continue;
                        }
-                       else printk("process stopped with signal %d\n", 
-                                   WSTOPSIG(status));
+                       else printk("process %d stopped with signal %d\n", 
+                                   pid, WSTOPSIG(status));
                        panic("wait_for_stop failed to wait for %d to stop "
                              "with %d\n", pid, sig);
                }
@@ -118,18 +118,27 @@ int wait_for_stop(int pid, int sig, int cont_type, void *relay)
        }
 }
 
-int raw(int fd, int complain)
+int raw(int fd)
 {
        struct termios tt;
        int err;
 
-       tcgetattr(fd, &tt);
+       CATCH_EINTR(err = tcgetattr(fd, &tt));
+       if (err < 0) {
+               printk("tcgetattr failed, errno = %d\n", errno);
+               return(-errno);
+       }
+
        cfmakeraw(&tt);
-       err = tcsetattr(fd, TCSANOW, &tt);
-       if((err < 0) && complain){
+
+       CATCH_EINTR(err = tcsetattr(fd, TCSADRAIN, &tt));
+       if (err < 0) {
                printk("tcsetattr failed, errno = %d\n", errno);
                return(-errno);
        }
+
+       /* XXX tcsetattr could have applied only some changes
+        * (and cfmakeraw() is a set of changes) */
        return(0);
 }
 
@@ -152,6 +161,21 @@ void setup_hostinfo(void)
                host.release, host.version, host.machine);
 }
 
+int setjmp_wrapper(void (*proc)(void *, void *), ...)
+{
+        va_list args;
+       sigjmp_buf buf;
+       int n;
+
+       n = sigsetjmp(buf, 1);
+       if(n == 0){
+               va_start(args, proc);
+               (*proc)(&buf, &args);
+       }
+       va_end(args);
+       return(n);
+}
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
index ead5e2c..9d06171 100644 (file)
@@ -17,6 +17,8 @@
 #include "kern_util.h"
 #include "mem_user.h"
 #include "signal_user.h"
+#include "time_user.h"
+#include "irq_user.h"
 #include "user.h"
 #include "init.h"
 #include "mode.h"
@@ -147,7 +149,20 @@ int main(int argc, char **argv, char **envp)
        
        /* Reboot */
        if(ret){
+               int err;
+
                printf("\n");
+
+               /* Let any pending signals fire, then disable them.  This 
+                * ensures that they won't be delivered after the exec, when 
+                * they are definitely not expected.
+                */
+               unblock_signals();
+               disable_timer();
+               err = deactivate_all_fds();
+               if(err)
+                       printf("deactivate_all_fds failed, errno = %d\n", -err);
+
                execvp(new_argv[0], new_argv);
                perror("Failed to exec kernel");
                ret = 1;
@@ -163,10 +178,21 @@ extern void *__real_malloc(int);
 
 void *__wrap_malloc(int size)
 {
-       if(CAN_KMALLOC())
-               return(um_kmalloc(size));
-       else
+       void *ret;
+
+       if(!CAN_KMALLOC())
                return(__real_malloc(size));
+       else if(size <= PAGE_SIZE) /* finding contiguos pages is hard */
+               ret = um_kmalloc(size);
+       else ret = um_vmalloc(size);
+
+       /* glibc people insist that if malloc fails, errno should be
+        * set by malloc as well. So we do.
+        */
+       if(ret == NULL)
+               errno = ENOMEM;
+
+       return(ret);
 }
 
 void *__wrap_calloc(int n, int size)
@@ -180,9 +206,35 @@ void *__wrap_calloc(int n, int size)
 
 extern void __real_free(void *);
 
+extern unsigned long high_physmem;
+
 void __wrap_free(void *ptr)
 {
-       if(CAN_KMALLOC()) kfree(ptr);
+       unsigned long addr = (unsigned long) ptr;
+
+       /* We need to know how the allocation happened, so it can be correctly
+        * freed.  This is done by seeing what region of memory the pointer is
+        * in -
+        *      physical memory - kmalloc/kfree
+        *      kernel virtual memory - vmalloc/vfree
+        *      anywhere else - malloc/free
+        * If kmalloc is not yet possible, then the kernel memory regions
+        * may not be set up yet, and the variables not set up.  So,
+        * free is called.
+        *
+        * CAN_KMALLOC is checked because it would be bad to free a buffer
+        * with kmalloc/vmalloc after they have been turned off during 
+        * shutdown.
+        */
+
+       if((addr >= uml_physmem) && (addr < high_physmem)){
+               if(CAN_KMALLOC())
+                       kfree(ptr);
+       }
+       else if((addr >= start_vm) && (addr < end_vm)){
+               if(CAN_KMALLOC())
+                       vfree(ptr);
+       }
        else __real_free(ptr);
 }
 
index 4fa0313..a6665dd 100644 (file)
@@ -3,9 +3,15 @@
 # Licensed under the GPL
 #
 
-obj-y = file.o process.o tty.o user_syms.o drivers/
+obj-y = aio.o file.o process.o time.o tty.o user_syms.o drivers/
 
-USER_OBJS := $(foreach file,file.o process.o tty.o,$(obj)/$(file))
+USER_OBJS := $(foreach file,aio.o file.o process.o time.o tty.o,$(obj)/$(file))
 
 $(USER_OBJS) : %.o: %.c
        $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+
+HAVE_AIO_ABI = $(shell [ -e /usr/include/linux/aio_abi.h ] && \
+       echo -DHAVE_AIO_ABI)
+HAVE_AIO_LIBC = $(shell objdump -T /lib/libc-*.so | grep io_submit && \
+       echo -DHAVE_AIO_LIBC)
+CFLAGS_aio.o = $(HAVE_AIO_ABI) $(HAVE_AIO_LIBC)
index d4bb214..cd4d654 100644 (file)
@@ -16,6 +16,7 @@
 #include <net/if.h>
 #include "user.h"
 #include "kern_util.h"
+#include "user_util.h"
 #include "net_user.h"
 #include "etap.h"
 #include "helper.h"
@@ -125,7 +126,8 @@ static int etap_tramp(char *dev, char *gate, int control_me,
        if(c != 1){
                printk("etap_tramp : uml_net failed\n");
                err = -EINVAL;
-               if(waitpid(pid, &status, 0) < 0)
+               CATCH_EINTR(n = waitpid(pid, &status, 0));
+               if(n < 0)
                        err = -errno;
                else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
                        printk("uml_net didn't exit with status 1\n");
index 054874d..f40c627 100644 (file)
@@ -18,6 +18,7 @@
 #include "net_user.h"
 #include "tuntap.h"
 #include "kern_util.h"
+#include "user_util.h"
 #include "user.h"
 #include "helper.h"
 #include "os.h"
@@ -108,7 +109,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
                       errno);
                return(-errno);
        }
-       waitpid(pid, NULL, 0);
+       CATCH_EINTR(waitpid(pid, NULL, 0));
 
        cmsg = CMSG_FIRSTHDR(&msg);
        if(cmsg == NULL){
index 4083bf9..bda79c1 100644 (file)
@@ -8,6 +8,9 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <signal.h>
+#include <utime.h>
+#include <dirent.h>
+#include <linux/kdev_t.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/socket.h>
@@ -15,6 +18,8 @@
 #include <sys/ioctl.h>
 #include <sys/mount.h>
 #include <sys/uio.h>
+#include <sys/utsname.h>
+#include <sys/vfs.h>
 #include "os.h"
 #include "user.h"
 #include "kern_util.h"
@@ -22,7 +27,8 @@
 static void copy_stat(struct uml_stat *dst, struct stat64 *src)
 {
        *dst = ((struct uml_stat) {
-               .ust_dev     = src->st_dev,     /* device */
+               .ust_major   = MAJOR(src->st_dev),     /* device */
+               .ust_minor   = MINOR(src->st_dev),
                .ust_ino     = src->st_ino,     /* inode */
                .ust_mode    = src->st_mode,    /* protection */
                .ust_nlink   = src->st_nlink,   /* number of hard links */
@@ -34,6 +40,8 @@ static void copy_stat(struct uml_stat *dst, struct stat64 *src)
                .ust_atime   = src->st_atime,   /* time of last access */
                .ust_mtime   = src->st_mtime,   /* time of last modification */
                .ust_ctime   = src->st_ctime,   /* time of last change */
+               .ust_rmajor  = MAJOR(src->st_rdev),
+               .ust_rminor  = MINOR(src->st_rdev),
        });
 }
 
@@ -71,12 +79,29 @@ int os_stat_file(const char *file_name, struct uml_stat *ubuf)
        return(err);
 }
 
-int os_access(const char* file, int mode)
+int os_lstat_file(const char *file_name, struct uml_stat *ubuf)
+{
+       struct stat64 sbuf;
+       int err;
+
+       do {
+               err = lstat64(file_name, &sbuf);
+       } while((err < 0) && (errno == EINTR)) ;
+
+       if(err < 0) 
+               return(-errno);
+
+       if(ubuf != NULL)
+               copy_stat(ubuf, &sbuf);
+       return(err);
+}
+
+int os_access(const char *file, int mode)
 {
        int amode, err;
 
-       amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
-             (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
+       amode=(mode& OS_ACC_R_OK ? R_OK : 0) | (mode& OS_ACC_W_OK ? W_OK : 0) |
+             (mode& OS_ACC_X_OK ? X_OK : 0) | (mode& OS_ACC_F_OK ? F_OK : 0) ;
 
        err = access(file, amode);
        if(err < 0)
@@ -85,6 +110,41 @@ int os_access(const char* file, int mode)
        return(0);
 }
 
+int os_set_file_time(const char *file, unsigned long access, unsigned long mod)
+{
+       struct utimbuf buf = ((struct utimbuf){ .actime = access, 
+                                               .modtime = mod });
+       int err;
+
+       err = utime(file, &buf);
+       if(err < 0)
+               return(-errno);
+
+       return(0);
+}
+
+int os_set_file_perms(const char *file, int mode)
+{
+       int err;
+
+       err = chmod(file, mode);
+       if(err < 0)
+               return(-errno);
+
+       return(0);
+}
+
+int os_set_file_owner(const char *file, int owner, int group)
+{
+       int err;
+
+       err = chown(file, owner, group);
+       if(err < 0)
+               return(-errno);
+
+       return(0);
+}
+
 void os_print_error(int error, const char* str)
 {
        errno = error < 0 ? -error : error;
@@ -187,7 +247,8 @@ int os_sigio_async(int master, int slave)
 
        if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
           (fcntl(master, F_SETOWN, os_getpid()) < 0)){
-               printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
+               printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", 
+                      errno);
                return(-errno);
        }
 
@@ -218,7 +279,7 @@ int os_file_type(char *file)
        struct uml_stat buf;
        int err;
 
-       err = os_stat_file(file, &buf);
+       err = os_lstat_file(file, &buf);
        if(err < 0)
                return(err);
 
@@ -265,6 +326,7 @@ int os_open_file(char *file, struct openflags flags, int mode)
        if(flags.c) f |= O_CREAT;
        if(flags.t) f |= O_TRUNC;
        if(flags.e) f |= O_EXCL;
+       if(flags.d) f |= O_DIRECT;
 
        fd = open64(file, f, mode);
        if(fd < 0)
@@ -278,6 +340,96 @@ int os_open_file(char *file, struct openflags flags, int mode)
        return(fd);
 }
 
+void *os_open_dir(char *path, int *err_out)
+{
+       void *dir;
+
+       dir = opendir(path);
+       *err_out = -errno;
+       return(dir);
+}
+
+int os_seek_dir(void *stream, unsigned long long pos)
+{
+       seekdir(stream, pos);
+       return(0);
+}
+
+int os_read_dir(void *stream, unsigned long long *ino_out, char **name_out)
+{
+       struct dirent *ent;
+
+       errno = 0;
+       ent = readdir(stream);
+       if(ent == NULL){
+               if(errno != 0)
+                       return(-errno);
+               *name_out = NULL;
+               return(0);
+       }
+
+       *ino_out = ent->d_ino;
+       *name_out = ent->d_name;
+       return(0);
+}
+
+int os_tell_dir(void *stream)
+{
+       return(telldir(stream));
+}
+
+int os_close_dir(void *stream)
+{
+       int err;
+
+       err = closedir(stream);
+       if(err < 0)
+               return(-errno);
+       return(0);
+}
+
+int os_remove_file(const char *file)
+{
+       int err;
+
+       err = unlink(file);
+       if(err)
+               return(-errno);
+
+       return(0);
+}
+
+int os_move_file(const char *from, const char *to)
+{
+       int err;
+
+       err = rename(from, to);
+       if(err)
+               return(-errno);
+
+       return(0);
+}
+
+int os_truncate_fd(int fd, unsigned long long len)
+{
+       int err;
+
+       err = ftruncate(fd, len);
+       if(err)
+               return(-errno);
+       return(0);
+}
+
+int os_truncate_file(const char *file, unsigned long long len)
+{
+       int err;
+
+       err = truncate(file, len);
+       if(err)
+               return(-errno);
+       return(0);
+}
+
 int os_connect_socket(char *name)
 {
        struct sockaddr_un sock;
@@ -307,7 +459,8 @@ int os_seek_file(int fd, __u64 offset)
        __u64 actual;
 
        actual = lseek64(fd, offset, SEEK_SET);
-       if(actual != offset) return(-errno);
+       if(actual != offset) 
+               return(-errno);
        return(0);
 }
 
@@ -395,6 +548,19 @@ int os_file_size(char *file, long long *size_out)
        return(0);
 }
 
+int os_fd_size(int fd, long long *size_out)
+{
+       struct stat buf;
+       int err;
+
+       err = fstat(fd, &buf);
+       if(err)
+               return(-errno);
+
+       *size_out = buf.st_size;
+       return(0);
+}
+
 int os_file_modtime(char *file, unsigned long *modtime)
 {
        struct uml_stat buf;
@@ -495,6 +661,16 @@ int os_set_fd_async(int fd, int owner)
        return(0);
 }
 
+int os_clear_fd_async(int fd)
+{
+       int flags = fcntl(fd, F_GETFL);
+
+       flags &= ~(O_ASYNC | O_NONBLOCK);
+       if(fcntl(fd, F_SETFL, flags) < 0)
+               return(-errno);
+       return(0);
+}
+
 int os_set_fd_block(int fd, int blocking)
 {
        int flags;
@@ -625,6 +801,72 @@ int os_create_unix_socket(char *file, int len, int close_on_exec)
        return(sock);
 }
 
+int os_make_symlink(const char *to, const char *from)
+{
+       int err;
+
+       err = symlink(to, from);
+       if(err)
+               return(-errno);
+
+       return(0);
+}
+
+int os_read_symlink(const char *file, char *buf, int size)
+{
+       int err;
+
+       err = readlink(file, buf, size);
+       if(err < 0)
+               return(-errno);
+
+       return(err);
+}
+
+int os_link_file(const char *to, const char *from)
+{
+       int err;
+
+       err = link(to, from);
+       if(err)
+               return(-errno);
+
+       return(0);
+}
+
+int os_make_dir(const char *dir, int mode)
+{
+       int err;
+
+       err = mkdir(dir, mode);
+       if(err)
+               return(-errno);
+
+       return(0);
+}
+
+int os_make_dev(const char *name, int mode, int major, int minor)
+{
+       int err;
+
+       err = mknod(name, mode, MKDEV(major, minor));
+       if(err)
+               return(-errno);
+
+       return(0);
+}
+
+int os_remove_dir(const char *dir)
+{
+       int err;
+
+       err = rmdir(dir);
+       if(err)
+               return(-errno);
+
+       return(0);
+}
+
 void os_flush_stdout(void)
 {
        fflush(stdout);
@@ -656,6 +898,38 @@ int os_lock_file(int fd, int excl)
        return(err);
 }
 
+int os_stat_filesystem(char *path, long *bsize_out, long long *blocks_out, 
+                      long long *bfree_out, long long *bavail_out, 
+                      long long *files_out, long long *ffree_out, 
+                      void *fsid_out, int fsid_size, long *namelen_out, 
+                      long *spare_out)
+{
+       struct statfs64 buf;
+       int err;
+
+       err = statfs64(path, &buf);
+       if(err < 0)
+               return(-errno);
+
+       *bsize_out = buf.f_bsize;
+       *blocks_out = buf.f_blocks;
+       *bfree_out = buf.f_bfree;
+       *bavail_out = buf.f_bavail;
+       *files_out = buf.f_files;
+       *ffree_out = buf.f_ffree;
+       memcpy(fsid_out, &buf.f_fsid, 
+              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
+              sizeof(buf.f_fsid));
+       *namelen_out = buf.f_namelen;
+       spare_out[0] = buf.f_spare[0];
+       spare_out[1] = buf.f_spare[1];
+       spare_out[2] = buf.f_spare[2];
+       spare_out[3] = buf.f_spare[3];
+       spare_out[4] = buf.f_spare[4];
+       spare_out[5] = buf.f_spare[5];
+       return(0);
+}
+
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
  * Emacs will notice this stuff at the end of the file and automatically
index f1b178c..ce1b5f1 100644 (file)
 #include <sys/wait.h>
 #include "os.h"
 #include "user.h"
+#include "user_util.h"
 
 #define ARBITRARY_ADDR -1
 #define FAILURE_PID    -1
 
+#define STAT_PATH_LEN sizeof("/proc/#######/stat\0")
+#define COMM_SCANF "%*[^)])"
+
 unsigned long os_process_pc(int pid)
 {
-       char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
+       char proc_stat[STAT_PATH_LEN], buf[256];
        unsigned long pc;
        int fd, err;
 
@@ -38,9 +42,9 @@ unsigned long os_process_pc(int pid)
        }
        os_close_file(fd);
        pc = ARBITRARY_ADDR;
-       if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
+       if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
                  "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
-                 "%*d %*d %*d %*d %ld", &pc) != 1){
+                 "%*d %*d %*d %*d %*d %lu", &pc) != 1){
                printk("os_process_pc - couldn't find pc in '%s'\n", buf);
        }
        return(pc);
@@ -48,7 +52,7 @@ unsigned long os_process_pc(int pid)
 
 int os_process_parent(int pid)
 {
-       char stat[sizeof("/proc/nnnnn/stat\0")];
+       char stat[STAT_PATH_LEN];
        char data[256];
        int parent, n, fd;
 
@@ -70,8 +74,7 @@ int os_process_parent(int pid)
        }
 
        parent = FAILURE_PID;
-       /* XXX This will break if there is a space in the command */
-       n = sscanf(data, "%*d %*s %*c %d", &parent);
+       n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
        if(n != 1) 
                printk("Failed to scan '%s'\n", data);
 
@@ -87,14 +90,13 @@ void os_kill_process(int pid, int reap_child)
 {
        kill(pid, SIGKILL);
        if(reap_child)
-               waitpid(pid, NULL, 0);
+               CATCH_EINTR(waitpid(pid, NULL, 0));
                
 }
 
 void os_usr1_process(int pid)
 {
-       syscall(__NR_tkill, pid, SIGUSR1); 
-       /* kill(pid, SIGUSR1); */
+       kill(pid, SIGUSR1);
 }
 
 int os_getpid(void)
index 47f9044..6e351e4 100644 (file)
@@ -1,5 +1,5 @@
 obj-y = bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o ptrace_user.o \
-       semaphore.o bitops.o sigcontext.o syscalls.o sysrq.o time.o
+       semaphore.o bitops.o sigcontext.o syscalls.o sysrq.o
 
 obj-$(CONFIG_HIGHMEM) += highmem.o
 obj-$(CONFIG_MODULES) += module.o
index b453e2f..d5e0ba9 100644 (file)
@@ -183,15 +183,16 @@ void arch_check_bugs(void)
 
 int arch_handle_signal(int sig, union uml_pt_regs *regs)
 {
-       unsigned long ip;
+       unsigned char tmp[2];
 
        /* This is testing for a cmov (0x0f 0x4x) instruction causing a
         * SIGILL in init.
         */
        if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0);
 
-       ip = UPT_IP(regs);
-       if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
+       if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
+               panic("SIGILL in init, could not read instructions!\n");
+       if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
                return(0);
 
        if(host_has_cmov == 0)
index 33e3021..ba77cca 100644 (file)
@@ -13,6 +13,8 @@
 #ifdef CONFIG_MODE_TT
 extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
 
+/* XXX this needs copy_to_user and copy_from_user */
+
 int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
 {
        if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
index 6b9ba08..4c7d375 100644 (file)
@@ -42,7 +42,8 @@ static void write_debugregs(int pid, unsigned long *regs)
                if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
                          regs[i]) < 0)
                        printk("write_debugregs - ptrace failed on "
-                              "register %d, errno = %d\n", errno);
+                              "register %d, value = 0x%x, errno = %d\n", i, 
+                              regs[i], errno);
        }
 }
 
diff --git a/arch/um/sys-i386/time.c b/arch/um/sys-i386/time.c
deleted file mode 100644 (file)
index a6a5ba7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * sys-i386/time.c 
- * Created             25.9.2002       Sapan Bhatia
- *
- */
-
-unsigned long long time_stamp(void)
-{
-       unsigned long low, high;
-
-       asm("rdtsc" : "=a" (low), "=d" (high));
-       return((((unsigned long long) high) << 32) + low);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index f480f42..2fa9136 100644 (file)
@@ -6,3 +6,6 @@ mk_constants-objs       := mk_constants_user.o mk_constants_kern.o
 
 HOSTCFLAGS_mk_task_kern.o      := $(CFLAGS) $(CPPFLAGS)
 HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS)
+
+clean:
+       $(RM) -f $(host-progs)
diff --git a/arch/um/util/mk_constants b/arch/um/util/mk_constants
deleted file mode 100644 (file)
index 2cc9842..0000000
Binary files a/arch/um/util/mk_constants and /dev/null differ
diff --git a/arch/um/util/mk_task b/arch/um/util/mk_task
deleted file mode 100644 (file)
index 1f4f750..0000000
Binary files a/arch/um/util/mk_task and /dev/null differ
index e39e43f..9911572 100644 (file)
@@ -92,6 +92,5 @@ obj-$(CONFIG_JFS_FS)          += jfs/
 obj-$(CONFIG_XFS_FS)           += xfs/
 obj-$(CONFIG_AFS_FS)           += afs/
 obj-$(CONFIG_BEFS_FS)          += befs/
-obj-$(CONFIG_HOSTFS)           += hostfs/
-obj-$(CONFIG_HPPFS)            += hppfs/
+obj-$(CONFIG_EXTERNFS)         += hostfs/
 obj-$(CONFIG_RCFS_FS)          += rcfs/
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
deleted file mode 100644 (file)
index ef5d5d1..0000000
+++ /dev/null
@@ -1,1008 +0,0 @@
-/* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- *
- * Ported the filesystem routines to 2.5.
- * 2003-02-10 Petr Baudis <pasky@ucw.cz>
- */
-
-#include <linux/stddef.h>
-#include <linux/fs.h>
-#include <linux/version.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/pagemap.h>
-#include <linux/blkdev.h>
-#include <linux/list.h>
-#include <linux/buffer_head.h>
-#include <linux/root_dev.h>
-#include <linux/statfs.h>
-#include <asm/uaccess.h>
-#include "hostfs.h"
-#include "kern_util.h"
-#include "kern.h"
-#include "user_util.h"
-#include "2_5compat.h"
-#include "init.h"
-
-struct hostfs_inode_info {
-       char *host_filename;
-       int fd;
-       int mode;
-       struct inode vfs_inode;
-};
-
-static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
-{
-       return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
-}
-
-#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
-
-int hostfs_d_delete(struct dentry *dentry)
-{
-       return(1);
-}
-
-struct dentry_operations hostfs_dentry_ops = {
-       .d_delete               = hostfs_d_delete,
-};
-
-/* Changed in hostfs_args before the kernel starts running */
-static char *root_ino = "/";
-static int append = 0;
-
-#define HOSTFS_SUPER_MAGIC 0x00c0ffee
-
-static struct inode_operations hostfs_iops;
-static struct inode_operations hostfs_dir_iops;
-static struct address_space_operations hostfs_link_aops;
-
-static int __init hostfs_args(char *options, int *add)
-{
-       char *ptr;
-
-       ptr = strchr(options, ',');
-       if(ptr != NULL)
-               *ptr++ = '\0';
-       if(*options != '\0')
-               root_ino = options;
-
-       options = ptr;
-       while(options){
-               ptr = strchr(options, ',');
-               if(ptr != NULL)
-                       *ptr++ = '\0';
-               if(*options != '\0'){
-                       if(!strcmp(options, "append"))
-                               append = 1;
-                       else printf("hostfs_args - unsupported option - %s\n",
-                                   options);
-               }
-               options = ptr;
-       }
-       return(0);
-}
-
-__uml_setup("hostfs=", hostfs_args,
-"hostfs=<root dir>,<flags>,...\n"
-"    This is used to set hostfs parameters.  The root directory argument\n"
-"    is used to confine all hostfs mounts to within the specified directory\n"
-"    tree on the host.  If this isn't specified, then a user inside UML can\n"
-"    mount anything on the host that's accessible to the user that's running\n"
-"    it.\n"
-"    The only flag currently supported is 'append', which specifies that all\n"
-"    files opened by hostfs will be opened in append mode.\n\n"
-);
-
-static char *dentry_name(struct dentry *dentry, int extra)
-{
-       struct dentry *parent;
-       char *root, *name;
-       int len;
-
-       len = 0;
-       parent = dentry;
-       while(parent->d_parent != parent){
-               len += parent->d_name.len + 1;
-               parent = parent->d_parent;
-       }
-       
-       root = HOSTFS_I(parent->d_inode)->host_filename;
-       len += strlen(root);
-       name = kmalloc(len + extra + 1, GFP_KERNEL);
-       if(name == NULL) return(NULL);
-
-       name[len] = '\0';
-       parent = dentry;
-       while(parent->d_parent != parent){
-               len -= parent->d_name.len + 1;
-               name[len] = '/';
-               strncpy(&name[len + 1], parent->d_name.name, 
-                       parent->d_name.len);
-               parent = parent->d_parent;
-       }
-       strncpy(name, root, strlen(root));
-       return(name);
-}
-
-static char *inode_name(struct inode *ino, int extra)
-{
-       struct dentry *dentry;
-
-       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
-       return(dentry_name(dentry, extra));
-}
-
-static int read_name(struct inode *ino, char *name)
-{
-       /* The non-int inode fields are copied into ints by stat_file and
-        * then copied into the inode because passing the actual pointers
-        * in and having them treated as int * breaks on big-endian machines
-        */
-       int err;
-       int i_mode, i_nlink, i_blksize;
-       unsigned long long i_size;
-       unsigned long long i_ino;
-       unsigned long long i_blocks;
-
-       err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, 
-                       &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, 
-                       &ino->i_ctime, &i_blksize, &i_blocks);
-       if(err) 
-               return(err);
-
-       ino->i_ino = i_ino;
-       ino->i_mode = i_mode;
-       ino->i_nlink = i_nlink;
-       ino->i_size = i_size;
-       ino->i_blksize = i_blksize;
-       ino->i_blocks = i_blocks;
-       if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
-               ino->i_uid = 0;
-       return(0);
-}
-
-static char *follow_link(char *link)
-{
-       int len, n;
-       char *name, *resolved, *end;
-
-       len = 64;
-       while(1){
-               n = -ENOMEM;
-               name = kmalloc(len, GFP_KERNEL);
-               if(name == NULL)
-                       goto out;
-
-               n = do_readlink(link, name, len);
-               if(n < len)
-                       break;
-               len *= 2;
-               kfree(name);
-       }
-       if(n < 0)
-               goto out_free;
-
-       if(*name == '/')
-               return(name);
-
-       end = strrchr(link, '/');
-       if(end == NULL)
-               return(name);
-
-       *(end + 1) = '\0';
-       len = strlen(link) + strlen(name) + 1;
-
-       resolved = kmalloc(len, GFP_KERNEL);
-       if(resolved == NULL){
-               n = -ENOMEM;
-               goto out_free;
-       }
-
-       sprintf(resolved, "%s%s", link, name);
-       kfree(name);
-       kfree(link);
-       return(resolved);
-
- out_free:
-       kfree(name);
- out:
-       return(ERR_PTR(n));
-}
-
-static int read_inode(struct inode *ino)
-{
-       char *name;
-       int err = 0;
-
-       /* Unfortunately, we are called from iget() when we don't have a dentry
-        * allocated yet.
-        */
-       if(list_empty(&ino->i_dentry))
-               goto out;
-       err = -ENOMEM;
-       name = inode_name(ino, 0);
-       if(name == NULL) 
-               goto out;
-
-       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
-               name = follow_link(name);
-               if(IS_ERR(name)){
-                       err = PTR_ERR(name);
-                       goto out;
-               }
-       }
-       
-       err = read_name(ino, name);
-       kfree(name);
- out:
-       return(err);
-}
-
-int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
-{
-       /* do_statfs uses struct statfs64 internally, but the linux kernel
-        * struct statfs still has 32-bit versions for most of these fields,
-        * so we convert them here
-        */
-       int err;
-       long long f_blocks;
-       long long f_bfree;
-       long long f_bavail;
-       long long f_files;
-       long long f_ffree;
-
-       err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
-                       &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
-                       &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
-                       &sf->f_namelen, sf->f_spare);
-       if(err) return(err);
-       sf->f_blocks = f_blocks;
-       sf->f_bfree = f_bfree;
-       sf->f_bavail = f_bavail;
-       sf->f_files = f_files;
-       sf->f_ffree = f_ffree;
-       sf->f_type = HOSTFS_SUPER_MAGIC;
-       return(0);
-}
-
-static struct inode *hostfs_alloc_inode(struct super_block *sb)
-{
-       struct hostfs_inode_info *hi;
-
-       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
-       if(hi == NULL) 
-               return(NULL);
-
-       *hi = ((struct hostfs_inode_info) { .host_filename      = NULL,
-                                           .fd                 = -1,
-                                           .mode               = 0 });
-       inode_init_once(&hi->vfs_inode);
-       return(&hi->vfs_inode);
-}
-
-static void hostfs_destroy_inode(struct inode *inode)
-{
-       if(HOSTFS_I(inode)->host_filename) 
-               kfree(HOSTFS_I(inode)->host_filename);
-
-       if(HOSTFS_I(inode)->fd != -1) 
-               close_file(&HOSTFS_I(inode)->fd);
-
-       kfree(HOSTFS_I(inode));
-}
-
-static void hostfs_read_inode(struct inode *inode)
-{
-       read_inode(inode);
-}
-
-static struct super_operations hostfs_sbops = { 
-       .alloc_inode    = hostfs_alloc_inode,
-       .destroy_inode  = hostfs_destroy_inode,
-       .read_inode     = hostfs_read_inode,
-       .statfs         = hostfs_statfs,
-};
-
-int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
-{
-       void *dir;
-       char *name;
-       unsigned long long next, ino;
-       int error, len;
-
-       name = dentry_name(file->f_dentry, 0);
-       if(name == NULL) return(-ENOMEM);
-       dir = open_dir(name, &error);
-       kfree(name);
-       if(dir == NULL) return(-error);
-       next = file->f_pos;
-       while((name = read_dir(dir, &next, &ino, &len)) != NULL){
-               error = (*filldir)(ent, name, len, file->f_pos, 
-                                  ino, DT_UNKNOWN);
-               if(error) break;
-               file->f_pos = next;
-       }
-       close_dir(dir);
-       return(0);
-}
-
-int hostfs_file_open(struct inode *ino, struct file *file)
-{
-       char *name;
-       int mode = 0, r = 0, w = 0, fd;
-
-       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
-       if((mode & HOSTFS_I(ino)->mode) == mode)
-               return(0);
-
-       /* The file may already have been opened, but with the wrong access,
-        * so this resets things and reopens the file with the new access.
-        */
-       if(HOSTFS_I(ino)->fd != -1){
-               close_file(&HOSTFS_I(ino)->fd);
-               HOSTFS_I(ino)->fd = -1;
-       }
-
-       HOSTFS_I(ino)->mode |= mode;
-       if(HOSTFS_I(ino)->mode & FMODE_READ) 
-               r = 1;
-       if(HOSTFS_I(ino)->mode & FMODE_WRITE) 
-               w = 1;
-       if(w) 
-               r = 1;
-
-       name = dentry_name(file->f_dentry, 0);
-       if(name == NULL) 
-               return(-ENOMEM);
-
-       fd = open_file(name, r, w, append);
-       kfree(name);
-       if(fd < 0) return(fd);
-       FILE_HOSTFS_I(file)->fd = fd;
-
-       return(0);
-}
-
-int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
-{
-       return(0);
-}
-
-static struct file_operations hostfs_file_fops = {
-       .llseek         = generic_file_llseek,
-       .read           = generic_file_read,
-       .write          = generic_file_write,
-       .mmap           = generic_file_mmap,
-       .open           = hostfs_file_open,
-       .release        = NULL,
-       .fsync          = hostfs_fsync,
-};
-
-static struct file_operations hostfs_dir_fops = {
-       .readdir        = hostfs_readdir,
-       .read           = generic_read_dir,
-};
-
-int hostfs_writepage(struct page *page, struct writeback_control *wbc)
-{
-       struct address_space *mapping = page->mapping;
-       struct inode *inode = mapping->host;
-       char *buffer;
-       unsigned long long base;
-       int count = PAGE_CACHE_SIZE;
-       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
-       int err;
-
-       if (page->index >= end_index)
-               count = inode->i_size & (PAGE_CACHE_SIZE-1);
-
-       buffer = kmap(page);
-       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
-
-       err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
-       if(err != count){
-               ClearPageUptodate(page);
-               goto out;
-       }
-
-       if (base > inode->i_size)
-               inode->i_size = base;
-
-       if (PageError(page))
-               ClearPageError(page);   
-       err = 0;
-
- out:  
-       kunmap(page);
-
-       unlock_page(page);
-       return err; 
-}
-
-int hostfs_readpage(struct file *file, struct page *page)
-{
-       char *buffer;
-       long long start;
-       int err = 0;
-
-       start = (long long) page->index << PAGE_CACHE_SHIFT;
-       buffer = kmap(page);
-       err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
-                       PAGE_CACHE_SIZE);
-       if(err < 0) goto out;
-
-       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
-
-       flush_dcache_page(page);
-       SetPageUptodate(page);
-       if (PageError(page)) ClearPageError(page);
-       err = 0;
- out:
-       kunmap(page);
-       unlock_page(page);
-       return(err);
-}
-
-int hostfs_prepare_write(struct file *file, struct page *page, 
-                        unsigned int from, unsigned int to)
-{
-       char *buffer;
-       long long start, tmp;
-       int err;
-
-       start = (long long) page->index << PAGE_CACHE_SHIFT;
-       buffer = kmap(page);
-       if(from != 0){
-               tmp = start;
-               err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
-                               from);
-               if(err < 0) goto out;
-       }
-       if(to != PAGE_CACHE_SIZE){
-               start += to;
-               err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
-                               PAGE_CACHE_SIZE - to);
-               if(err < 0) goto out;           
-       }
-       err = 0;
- out:
-       kunmap(page);
-       return(err);
-}
-
-int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
-                unsigned to)
-{
-       struct address_space *mapping = page->mapping;
-       struct inode *inode = mapping->host;
-       char *buffer;
-       long long start;
-       int err = 0;
-
-       start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
-       buffer = kmap(page);
-       err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, 
-                        to - from);
-       if(err > 0) err = 0;
-       if(!err && (start > inode->i_size))
-               inode->i_size = start;
-
-       kunmap(page);
-       return(err);
-}
-
-static struct address_space_operations hostfs_aops = {
-       .writepage      = hostfs_writepage,
-       .readpage       = hostfs_readpage,
-/*     .set_page_dirty = __set_page_dirty_nobuffers, */
-       .prepare_write  = hostfs_prepare_write,
-       .commit_write   = hostfs_commit_write
-};
-
-static int init_inode(struct inode *inode, struct dentry *dentry)
-{
-       char *name;
-       int type, err = -ENOMEM, rdev;
-
-       if(dentry){
-               name = dentry_name(dentry, 0);
-               if(name == NULL)
-                       goto out;
-               type = file_type(name, &rdev);
-               kfree(name);
-       }
-       else type = OS_TYPE_DIR;
-
-       err = 0;
-       if(type == OS_TYPE_SYMLINK)
-               inode->i_op = &page_symlink_inode_operations;
-       else if(type == OS_TYPE_DIR)
-               inode->i_op = &hostfs_dir_iops;
-       else inode->i_op = &hostfs_iops;
-
-       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
-       else inode->i_fop = &hostfs_file_fops;
-
-       if(type == OS_TYPE_SYMLINK) 
-               inode->i_mapping->a_ops = &hostfs_link_aops;
-       else inode->i_mapping->a_ops = &hostfs_aops;
-
-       switch (type) {
-       case OS_TYPE_CHARDEV:
-               init_special_inode(inode, S_IFCHR, rdev);
-               break;
-       case OS_TYPE_BLOCKDEV:
-               init_special_inode(inode, S_IFBLK, rdev);
-               break;
-       case OS_TYPE_FIFO:
-               init_special_inode(inode, S_IFIFO, 0);
-               break;
-       case OS_TYPE_SOCK:
-               init_special_inode(inode, S_IFSOCK, 0);
-               break;
-       }
- out:
-       return(err);
-}
-
-int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 
-                 struct nameidata *nd)
-{
-       struct inode *inode;
-       char *name;
-       int error, fd;
-
-       error = -ENOMEM;
-       inode = iget(dir->i_sb, 0);
-       if(inode == NULL) goto out;
-
-       error = init_inode(inode, dentry);
-       if(error) 
-               goto out_put;
-       
-       error = -ENOMEM;
-       name = dentry_name(dentry, 0);
-       if(name == NULL)
-               goto out_put;
-
-       fd = file_create(name, 
-                        mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
-                        mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
-                        mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
-       if(fd < 0) 
-               error = fd;
-       else error = read_name(inode, name);
-
-       kfree(name);
-       if(error)
-               goto out_put;
-
-       HOSTFS_I(inode)->fd = fd;
-       HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
-       d_instantiate(dentry, inode);
-       return(0);
-
- out_put:
-       iput(inode);
- out:
-       return(error);
-}
-
-struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 
-                            struct nameidata *nd)
-{
-       struct inode *inode;
-       char *name;
-       int err;
-
-       err = -ENOMEM;
-       inode = iget(ino->i_sb, 0);
-       if(inode == NULL) 
-               goto out;
-       err = init_inode(inode, dentry);
-       if(err) 
-               goto out_put;
-
-       err = -ENOMEM;
-       name = dentry_name(dentry, 0);
-       if(name == NULL)
-               goto out_put;
-
-       err = read_name(inode, name);
-       kfree(name);
-       if(err == -ENOENT){
-               iput(inode);
-               inode = NULL;
-       }
-       else if(err)
-               goto out_put;
-
-       d_add(dentry, inode);
-       dentry->d_op = &hostfs_dentry_ops;
-       return(NULL);
-
- out_put:
-       iput(inode);
- out:
-       return(ERR_PTR(err));
-}
-
-static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
-{
-        char *file;
-       int len;
-
-       file = inode_name(ino, dentry->d_name.len + 1);
-       if(file == NULL) return(NULL);
-        strcat(file, "/");
-       len = strlen(file);
-        strncat(file, dentry->d_name.name, dentry->d_name.len);
-       file[len + dentry->d_name.len] = '\0';
-        return(file);
-}
-
-int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
-{
-        char *from_name, *to_name;
-        int err;
-
-        if((from_name = inode_dentry_name(ino, from)) == NULL) 
-                return(-ENOMEM);
-        to_name = dentry_name(to, 0);
-       if(to_name == NULL){
-               kfree(from_name);
-               return(-ENOMEM);
-       }
-        err = link_file(to_name, from_name);
-        kfree(from_name);
-        kfree(to_name);
-        return(err);
-}
-
-int hostfs_unlink(struct inode *ino, struct dentry *dentry)
-{
-       char *file;
-       int err;
-
-       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-       if(append)
-               return(-EPERM);
-
-       err = unlink_file(file);
-       kfree(file);
-       return(err);
-}
-
-int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
-{
-       char *file;
-       int err;
-
-       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-       err = make_symlink(file, to);
-       kfree(file);
-       return(err);
-}
-
-int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
-{
-       char *file;
-       int err;
-
-       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-       err = do_mkdir(file, mode);
-       kfree(file);
-       return(err);
-}
-
-int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
-{
-       char *file;
-       int err;
-
-       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
-       err = do_rmdir(file);
-       kfree(file);
-       return(err);
-}
-
-int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
-{
-       struct inode *inode;
-       char *name;
-       int err = -ENOMEM;
-       inode = iget(dir->i_sb, 0);
-       if(inode == NULL) 
-               goto out;
-
-       err = init_inode(inode, dentry);
-       if(err) 
-               goto out_put;
-
-       err = -ENOMEM;
-       name = dentry_name(dentry, 0);
-       if(name == NULL)
-               goto out_put;
-
-       init_special_inode(inode, mode, dev);
-       err = do_mknod(name, mode, dev);
-       if(err)
-               goto out_free;
-
-       err = read_name(inode, name);
-       kfree(name);
-       if(err)
-               goto out_put;
-
-       d_instantiate(dentry, inode);
-       return(0);
-
- out_free:
-       kfree(name);
- out_put:
-       iput(inode);
- out:
-       return(err);
-}
-
-int hostfs_rename(struct inode *from_ino, struct dentry *from,
-                 struct inode *to_ino, struct dentry *to)
-{
-       char *from_name, *to_name;
-       int err;
-
-       if((from_name = inode_dentry_name(from_ino, from)) == NULL)
-               return(-ENOMEM);
-       if((to_name = inode_dentry_name(to_ino, to)) == NULL){
-               kfree(from_name);
-               return(-ENOMEM);
-       }
-       err = rename_file(from_name, to_name);
-       kfree(from_name);
-       kfree(to_name);
-       return(err);
-}
-
-void hostfs_truncate(struct inode *ino)
-{
-       not_implemented();
-}
-
-int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
-{
-       char *name;
-       int r = 0, w = 0, x = 0, err;
-
-       if(desired & MAY_READ) r = 1;
-       if(desired & MAY_WRITE) w = 1;
-       if(desired & MAY_EXEC) x = 1;
-       name = inode_name(ino, 0);
-       if(name == NULL) return(-ENOMEM);
-       err = access_file(name, r, w, x);
-       kfree(name);
-       if(!err) err = vfs_permission(ino, desired);
-       return(err);
-}
-
-int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
-{
-       struct hostfs_iattr attrs;
-       char *name;
-       int err;
-       
-       if(append) 
-               attr->ia_valid &= ~ATTR_SIZE;
-
-       attrs.ia_valid = 0;
-       if(attr->ia_valid & ATTR_MODE){
-               attrs.ia_valid |= HOSTFS_ATTR_MODE;
-               attrs.ia_mode = attr->ia_mode;
-       }
-       if(attr->ia_valid & ATTR_UID){
-               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
-                  (attr->ia_uid == 0))
-                       attr->ia_uid = getuid();
-               attrs.ia_valid |= HOSTFS_ATTR_UID;
-               attrs.ia_uid = attr->ia_uid;
-       }
-       if(attr->ia_valid & ATTR_GID){
-               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
-                  (attr->ia_gid == 0))
-                       attr->ia_gid = getuid();
-               attrs.ia_valid |= HOSTFS_ATTR_GID;
-               attrs.ia_gid = attr->ia_gid;
-       }
-       if(attr->ia_valid & ATTR_SIZE){
-               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
-               attrs.ia_size = attr->ia_size;
-       }
-       if(attr->ia_valid & ATTR_ATIME){
-               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
-               attrs.ia_atime = attr->ia_atime;
-       }
-       if(attr->ia_valid & ATTR_MTIME){
-               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
-               attrs.ia_mtime = attr->ia_mtime;
-       }
-       if(attr->ia_valid & ATTR_CTIME){
-               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
-               attrs.ia_ctime = attr->ia_ctime;
-       }
-       if(attr->ia_valid & ATTR_ATIME_SET){
-               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
-       }
-       if(attr->ia_valid & ATTR_MTIME_SET){
-               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
-       }
-       name = dentry_name(dentry, 0);
-       if(name == NULL) return(-ENOMEM);
-       err = set_attr(name, &attrs);
-       kfree(name);
-       if(err)
-               return(err);
-
-       return(inode_setattr(dentry->d_inode, attr));
-}
-
-int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 
-          struct kstat *stat)
-{
-       generic_fillattr(dentry->d_inode, stat);
-       return(0);
-}
-
-static struct inode_operations hostfs_iops = {
-       .create         = hostfs_create,
-       .link           = hostfs_link,
-       .unlink         = hostfs_unlink,
-       .symlink        = hostfs_symlink,
-       .mkdir          = hostfs_mkdir,
-       .rmdir          = hostfs_rmdir,
-       .mknod          = hostfs_mknod,
-       .rename         = hostfs_rename,
-       .truncate       = hostfs_truncate,
-       .permission     = hostfs_permission,
-       .setattr        = hostfs_setattr,
-       .getattr        = hostfs_getattr,
-};
-
-static struct inode_operations hostfs_dir_iops = {
-       .create         = hostfs_create,
-       .lookup         = hostfs_lookup,
-       .link           = hostfs_link,
-       .unlink         = hostfs_unlink,
-       .symlink        = hostfs_symlink,
-       .mkdir          = hostfs_mkdir,
-       .rmdir          = hostfs_rmdir,
-       .mknod          = hostfs_mknod,
-       .rename         = hostfs_rename,
-       .truncate       = hostfs_truncate,
-       .permission     = hostfs_permission,
-       .setattr        = hostfs_setattr,
-       .getattr        = hostfs_getattr,
-};
-
-int hostfs_link_readpage(struct file *file, struct page *page)
-{
-       char *buffer, *name;
-       long long start;
-       int err;
-
-       start = page->index << PAGE_CACHE_SHIFT;
-       buffer = kmap(page);
-       name = inode_name(page->mapping->host, 0);
-       if(name == NULL) return(-ENOMEM);
-       err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
-       kfree(name);
-       if(err == PAGE_CACHE_SIZE)
-               err = -E2BIG;
-       else if(err > 0){
-               flush_dcache_page(page);
-               SetPageUptodate(page);
-               if (PageError(page)) ClearPageError(page);
-               err = 0;
-       }
-       kunmap(page);
-       unlock_page(page);
-       return(err);
-}
-
-static struct address_space_operations hostfs_link_aops = {
-       .readpage       = hostfs_link_readpage,
-};
-
-static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
-{
-       struct inode *root_inode;
-       char *name, *data = d;
-       int err;
-
-       sb->s_blocksize = 1024;
-       sb->s_blocksize_bits = 10;
-       sb->s_magic = HOSTFS_SUPER_MAGIC;
-       sb->s_op = &hostfs_sbops;
-
-       if((data == NULL) || (*data == '\0')) 
-               data = root_ino;
-
-       err = -ENOMEM;
-       name = kmalloc(strlen(data) + 1, GFP_KERNEL);
-       if(name == NULL) 
-               goto out;
-
-       strcpy(name, data);
-
-       root_inode = iget(sb, 0);
-       if(root_inode == NULL)
-               goto out_free;
-
-       err = init_inode(root_inode, NULL);
-       if(err)
-               goto out_put;
-
-       HOSTFS_I(root_inode)->host_filename = name;
-
-       err = -ENOMEM;
-       sb->s_root = d_alloc_root(root_inode);
-       if(sb->s_root == NULL)
-               goto out_put;
-
-       err = read_inode(root_inode);
-       if(err)
-               goto out_put;
-
-       return(0);
-
- out_put:
-       iput(root_inode);
- out_free:
-       kfree(name);
- out:
-       return(err);
-}
-
-static struct super_block *hostfs_read_sb(struct file_system_type *type,
-                                            int flags, const char *dev_name,
-                                            void *data)
-{
-       return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
-}
-
-static struct file_system_type hostfs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "hostfs",
-       .get_sb         = hostfs_read_sb,
-       .kill_sb        = kill_anon_super,
-       .fs_flags       = 0,
-};
-
-static int __init init_hostfs(void)
-{
-       return(register_filesystem(&hostfs_type));
-}
-
-static void __exit exit_hostfs(void)
-{
-       unregister_filesystem(&hostfs_type);
-}
-
-module_init(init_hostfs)
-module_exit(exit_hostfs)
-MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
deleted file mode 100644 (file)
index c406266..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/* 
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#include <unistd.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <errno.h>
-#include <utime.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/vfs.h>
-#include "hostfs.h"
-#include "kern_util.h"
-#include "user.h"
-
-int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
-             int *nlink_out, int *uid_out, int *gid_out, 
-             unsigned long long *size_out, struct timespec *atime_out,
-             struct timespec *mtime_out, struct timespec *ctime_out,
-             int *blksize_out, unsigned long long *blocks_out)
-{
-       struct stat64 buf;
-
-       if(lstat64(path, &buf) < 0) 
-               return(-errno);
-
-       /* See the Makefile for why STAT64_INO_FIELD is passed in
-        * by the build
-        */
-       if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
-       if(mode_out != NULL) *mode_out = buf.st_mode;
-       if(nlink_out != NULL) *nlink_out = buf.st_nlink;
-       if(uid_out != NULL) *uid_out = buf.st_uid;
-       if(gid_out != NULL) *gid_out = buf.st_gid;
-       if(size_out != NULL) *size_out = buf.st_size;
-       if(atime_out != NULL) {
-               atime_out->tv_sec = buf.st_atime;
-               atime_out->tv_nsec = 0;
-       }
-       if(mtime_out != NULL) {
-               mtime_out->tv_sec = buf.st_mtime;
-               mtime_out->tv_nsec = 0;
-       }
-       if(ctime_out != NULL) {
-               ctime_out->tv_sec = buf.st_ctime;
-               ctime_out->tv_nsec = 0;
-       }
-       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
-       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
-       return(0);
-}
-
-int file_type(const char *path, int *rdev)
-{
-       struct stat64 buf;
-
-       if(lstat64(path, &buf) < 0) 
-               return(-errno);
-       if(rdev != NULL) 
-               *rdev = buf.st_rdev;
-
-       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
-       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
-       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
-       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
-       else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
-       else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
-       else return(OS_TYPE_FILE);
-}
-
-int access_file(char *path, int r, int w, int x)
-{
-       int mode = 0;
-
-       if(r) mode = R_OK;
-       if(w) mode |= W_OK;
-       if(x) mode |= X_OK;
-       if(access(path, mode) != 0) return(-errno);
-       else return(0);
-}
-
-int open_file(char *path, int r, int w, int append)
-{
-       int mode = 0, fd;
-
-       if(r && !w) 
-               mode = O_RDONLY;
-       else if(!r && w) 
-               mode = O_WRONLY;
-       else if(r && w) 
-               mode = O_RDWR;
-       else panic("Impossible mode in open_file");
-
-       if(append)
-               mode |= O_APPEND;
-       fd = open64(path, mode);
-       if(fd < 0) return(-errno);
-       else return(fd);
-}
-
-void *open_dir(char *path, int *err_out)
-{
-       DIR *dir;
-
-       dir = opendir(path);
-       *err_out = errno;
-       if(dir == NULL) return(NULL);
-       return(dir);
-}
-
-char *read_dir(void *stream, unsigned long long *pos, 
-              unsigned long long *ino_out, int *len_out)
-{
-       DIR *dir = stream;
-       struct dirent *ent;
-
-       seekdir(dir, *pos);
-       ent = readdir(dir);
-       if(ent == NULL) return(NULL);
-       *len_out = strlen(ent->d_name);
-       *ino_out = ent->d_ino;
-       *pos = telldir(dir);
-       return(ent->d_name);
-}
-
-int read_file(int fd, unsigned long long *offset, char *buf, int len)
-{
-       int n;
-
-       n = pread64(fd, buf, len, *offset);
-       if(n < 0) return(-errno);
-       *offset += n;
-       return(n);
-}
-
-int write_file(int fd, unsigned long long *offset, const char *buf, int len)
-{
-       int n;
-
-       n = pwrite64(fd, buf, len, *offset);
-       if(n < 0) return(-errno);
-       *offset += n;
-       return(n);
-}
-
-int lseek_file(int fd, long long offset, int whence)
-{
-       int ret;
-
-       ret = lseek64(fd, offset, whence);
-       if(ret < 0) return(-errno);
-       return(0);
-}
-
-void close_file(void *stream)
-{
-       close(*((int *) stream));
-}
-
-void close_dir(void *stream)
-{
-       closedir(stream);
-}
-
-int file_create(char *name, int ur, int uw, int ux, int gr, 
-               int gw, int gx, int or, int ow, int ox)
-{
-       int mode, fd;
-
-       mode = 0;
-       mode |= ur ? S_IRUSR : 0;
-       mode |= uw ? S_IWUSR : 0;
-       mode |= ux ? S_IXUSR : 0;
-       mode |= gr ? S_IRGRP : 0;
-       mode |= gw ? S_IWGRP : 0;
-       mode |= gx ? S_IXGRP : 0;
-       mode |= or ? S_IROTH : 0;
-       mode |= ow ? S_IWOTH : 0;
-       mode |= ox ? S_IXOTH : 0;
-       fd = open64(name, O_CREAT | O_RDWR, mode);
-       if(fd < 0) 
-               return(-errno);
-       return(fd);
-}
-
-int set_attr(const char *file, struct hostfs_iattr *attrs)
-{
-       struct utimbuf buf;
-       int err, ma;
-
-       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
-               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
-       }
-       if(attrs->ia_valid & HOSTFS_ATTR_UID){
-               if(chown(file, attrs->ia_uid, -1)) return(-errno);
-       }
-       if(attrs->ia_valid & HOSTFS_ATTR_GID){
-               if(chown(file, -1, attrs->ia_gid)) return(-errno);
-       }
-       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
-               if(truncate(file, attrs->ia_size)) return(-errno);
-       }
-       ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
-       if((attrs->ia_valid & ma) == ma){
-               buf.actime = attrs->ia_atime.tv_sec;
-               buf.modtime = attrs->ia_mtime.tv_sec;
-               if(utime(file, &buf) != 0) return(-errno);
-       }
-       else {
-               struct timespec ts;
-
-               if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
-                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
-                                       NULL, NULL, &ts, NULL, NULL, NULL);
-                       if(err != 0) 
-                               return(err);
-                       buf.actime = attrs->ia_atime.tv_sec;
-                       buf.modtime = ts.tv_sec;
-                       if(utime(file, &buf) != 0) 
-                               return(-errno);
-               }
-               if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
-                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
-                                       NULL, &ts, NULL, NULL, NULL, NULL);
-                       if(err != 0) 
-                               return(err);
-                       buf.actime = ts.tv_sec;
-                       buf.modtime = attrs->ia_mtime.tv_sec;
-                       if(utime(file, &buf) != 0) 
-                               return(-errno);
-               }
-       }
-       if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
-       if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
-               err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 
-                               &attrs->ia_atime, &attrs->ia_mtime, NULL, 
-                               NULL, NULL);
-               if(err != 0) return(err);
-       }
-       return(0);
-}
-
-int make_symlink(const char *from, const char *to)
-{
-       int err;
-
-       err = symlink(to, from);
-       if(err) return(-errno);
-       return(0);
-}
-
-int unlink_file(const char *file)
-{
-       int err;
-
-       err = unlink(file);
-       if(err) return(-errno);
-       return(0);
-}
-
-int do_mkdir(const char *file, int mode)
-{
-       int err;
-
-       err = mkdir(file, mode);
-       if(err) return(-errno);
-       return(0);
-}
-
-int do_rmdir(const char *file)
-{
-       int err;
-
-       err = rmdir(file);
-       if(err) return(-errno);
-       return(0);
-}
-
-int do_mknod(const char *file, int mode, int dev)
-{
-       int err;
-
-       err = mknod(file, mode, dev);
-       if(err) return(-errno);
-       return(0);
-}
-
-int link_file(const char *to, const char *from)
-{
-       int err;
-
-       err = link(to, from);
-       if(err) return(-errno);
-       return(0);
-}
-
-int do_readlink(char *file, char *buf, int size)
-{
-       int n;
-
-       n = readlink(file, buf, size);
-       if(n < 0) 
-               return(-errno);
-       if(n < size) 
-               buf[n] = '\0';
-       return(n);
-}
-
-int rename_file(char *from, char *to)
-{
-       int err;
-
-       err = rename(from, to);
-       if(err < 0) return(-errno);
-       return(0);      
-}
-
-int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
-             long long *bfree_out, long long *bavail_out, 
-             long long *files_out, long long *ffree_out,
-             void *fsid_out, int fsid_size, long *namelen_out, 
-             long *spare_out)
-{
-       struct statfs64 buf;
-       int err;
-
-       err = statfs64(root, &buf);
-       if(err < 0) return(-errno);
-       *bsize_out = buf.f_bsize;
-       *blocks_out = buf.f_blocks;
-       *bfree_out = buf.f_bfree;
-       *bavail_out = buf.f_bavail;
-       *files_out = buf.f_files;
-       *ffree_out = buf.f_ffree;
-       memcpy(fsid_out, &buf.f_fsid, 
-              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
-              sizeof(buf.f_fsid));
-       *namelen_out = buf.f_namelen;
-       spare_out[0] = buf.f_spare[0];
-       spare_out[1] = buf.f_spare[1];
-       spare_out[2] = buf.f_spare[2];
-       spare_out[3] = buf.f_spare[3];
-       spare_out[4] = buf.f_spare[4];
-       spare_out[5] = buf.f_spare[5];
-       return(0);
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index f5836c5..9a244ca 100644 (file)
@@ -23,8 +23,6 @@
        } \
 } while (0)
 
-extern int foo;
-
 #endif
 
 #endif
index de389a4..bccf537 100644 (file)
@@ -15,8 +15,9 @@
 #define SIGIO_WRITE_IRQ        11
 #define TELNETD_IRQ            12
 #define XTERM_IRQ              13
-
-#define LAST_IRQ XTERM_IRQ
+#define HUMFS_IRQ              14
+#define LAST_IRQ HUMFS_IRQ
 #define NR_IRQS (LAST_IRQ + 1)
 
 #endif
index b2a2bd4..2f06a7b 100644 (file)
@@ -1,5 +1,5 @@
 /* 
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2004 Jeff Dike (jdike@addtoit.com)
  * Licensed under the GPL
  */
 
@@ -24,7 +24,6 @@ struct mm_struct;
 
 struct thread_struct {
        int forking;
-       unsigned long kernel_stack;
        int nsyscalls;
        struct pt_regs regs;
        unsigned long cr2;
@@ -75,7 +74,6 @@ struct thread_struct {
 #define INIT_THREAD \
 { \
        .forking                = 0, \
-       .kernel_stack           = 0, \
        .nsyscalls              = 0, \
         .regs                  = EMPTY_REGS, \
        .cr2                    = 0, \