Explorar o código

Merge branch 'for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML updates from Richard Weinberger:

 - remove hppfs ("HonePot ProcFS")

 - initial support for musl libc

 - uaccess cleanup

 - random cleanups and bug fixes all over the place

* 'for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: (21 commits)
  um: Don't pollute kernel namespace with uapi
  um: Include sys/types.h for makedev(), major(), minor()
  um: Do not use stdin and stdout identifiers for struct members
  um: Do not use __ptr_t type for stack_t's .ss pointer
  um: Fix mconsole dependency
  um: Handle tracehook_report_syscall_entry() result
  um: Remove copy&paste code from init.h
  um: Stop abusing __KERNEL__
  um: Catch unprotected user memory access
  um: Fix warning in setup_signal_stack_si()
  um: Rework uaccess code
  um: Add uaccess.h to ldt.c
  um: Add uaccess.h to syscalls_64.c
  um: Add asm/elf.h to vma.c
  um: Cleanup mem_32/64.c headers
  um: Remove hppfs
  um: Move syscall() declaration into os.h
  um: kernel: ksyms: Export symbol syscall() for fixing modpost issue
  um/os-Linux: Use char[] for syscall_stub declarations
  um: Use char[] for linker script address declarations
  ...
Linus Torvalds %!s(int64=10) %!d(string=hai) anos
pai
achega
21dc2e6c6d
Modificáronse 46 ficheiros con 155 adicións e 1064 borrados
  1. 1 15
      arch/um/Kconfig.um
  2. 4 3
      arch/um/Makefile
  3. 9 9
      arch/um/drivers/harddog_user.c
  4. 1 1
      arch/um/drivers/mconsole.h
  5. 3 3
      arch/um/drivers/net_user.c
  6. 7 7
      arch/um/drivers/slip_user.c
  7. 8 8
      arch/um/drivers/slirp_user.c
  8. 0 1
      arch/um/include/asm/Kbuild
  9. 1 2
      arch/um/include/asm/ptrace-generic.h
  10. 9 0
      arch/um/include/asm/sections.h
  11. 1 1
      arch/um/include/asm/thread_info.h
  12. 25 151
      arch/um/include/asm/uaccess.h
  13. 2 22
      arch/um/include/shared/init.h
  14. 2 0
      arch/um/include/shared/os.h
  15. 1 1
      arch/um/include/shared/user.h
  16. 2 0
      arch/um/kernel/ksyms.c
  17. 3 4
      arch/um/kernel/physmem.c
  18. 4 3
      arch/um/kernel/ptrace.c
  19. 3 4
      arch/um/kernel/skas/mmu.c
  20. 5 1
      arch/um/kernel/skas/syscall.c
  21. 17 30
      arch/um/kernel/skas/uaccess.c
  22. 5 0
      arch/um/kernel/trap.c
  23. 1 3
      arch/um/kernel/um_arch.c
  24. 3 3
      arch/um/os-Linux/drivers/tuntap_user.c
  25. 1 0
      arch/um/os-Linux/file.c
  26. 5 3
      arch/um/os-Linux/signal.c
  27. 3 3
      arch/um/os-Linux/skas/mem.c
  28. 4 4
      arch/um/os-Linux/skas/process.c
  29. 1 0
      arch/x86/um/asm/checksum.h
  30. 0 2
      arch/x86/um/asm/elf.h
  31. 2 0
      arch/x86/um/asm/processor.h
  32. 8 0
      arch/x86/um/asm/segment.h
  33. 1 0
      arch/x86/um/ldt.c
  34. 1 2
      arch/x86/um/mem_32.c
  35. 1 2
      arch/x86/um/mem_64.c
  36. 1 0
      arch/x86/um/ptrace_32.c
  37. 1 0
      arch/x86/um/ptrace_64.c
  38. 3 3
      arch/x86/um/shared/sysdep/tls.h
  39. 2 1
      arch/x86/um/signal.c
  40. 1 0
      arch/x86/um/syscalls_64.c
  41. 1 0
      arch/x86/um/tls_32.c
  42. 1 0
      arch/x86/um/tls_64.c
  43. 1 0
      arch/x86/um/vdso/vma.c
  44. 0 1
      fs/Makefile
  45. 0 6
      fs/hppfs/Makefile
  46. 0 765
      fs/hppfs/hppfs.c

+ 1 - 15
arch/um/Kconfig.um

@@ -44,23 +44,9 @@ 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 HPPFS
-	tristate "HoneyPot ProcFS"
-	depends on PROC_FS
-	help
-	  hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
-	  entries to be overridden, removed, or fabricated from the host.
-	  Its purpose is to allow a UML to appear to be a physical machine
-	  by removing or changing anything in /proc which gives away the
-	  identity of a UML.
-
-	  See <http://user-mode-linux.sf.net/old/hppfs.html> for more information.
-
-	  You only need this if you are setting up a UML honeypot.  Otherwise,
-	  it is safe to say 'N' here.
-
 config MCONSOLE
 	bool "Management console"
+	depends on PROC_FS
 	default y
 	help
           The user mode linux management console is a low-level interface to

+ 4 - 3
arch/um/Makefile

@@ -68,9 +68,10 @@ KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \
 
 KBUILD_AFLAGS += $(ARCH_INCLUDE)
 
-USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
-	$(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
-	$(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 -idirafter include
+USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
+		$(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \
+		-D_FILE_OFFSET_BITS=64 -idirafter include \
+		-D__KERNEL__ -D__UM_HOST__
 
 #This will adjust *FLAGS accordingly to the platform.
 include $(ARCH_DIR)/Makefile-os-$(OS)

+ 9 - 9
arch/um/drivers/harddog_user.c

@@ -9,8 +9,8 @@
 #include <os.h>
 
 struct dog_data {
-	int stdin;
-	int stdout;
+	int stdin_fd;
+	int stdout_fd;
 	int close_me[2];
 };
 
@@ -18,11 +18,11 @@ static void pre_exec(void *d)
 {
 	struct dog_data *data = d;
 
-	dup2(data->stdin, 0);
-	dup2(data->stdout, 1);
-	dup2(data->stdout, 2);
-	close(data->stdin);
-	close(data->stdout);
+	dup2(data->stdin_fd, 0);
+	dup2(data->stdout_fd, 1);
+	dup2(data->stdout_fd, 2);
+	close(data->stdin_fd);
+	close(data->stdout_fd);
 	close(data->close_me[0]);
 	close(data->close_me[1]);
 }
@@ -49,8 +49,8 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
 		goto out_close_in;
 	}
 
-	data.stdin = out_fds[0];
-	data.stdout = in_fds[1];
+	data.stdin_fd = out_fds[0];
+	data.stdout_fd = in_fds[1];
 	data.close_me[0] = out_fds[1];
 	data.close_me[1] = in_fds[0];
 

+ 1 - 1
arch/um/drivers/mconsole.h

@@ -7,7 +7,7 @@
 #ifndef __MCONSOLE_H__
 #define __MCONSOLE_H__
 
-#ifndef __KERNEL__
+#ifdef __UM_HOST__
 #include <stdint.h>
 #define u32 uint32_t
 #endif

+ 3 - 3
arch/um/drivers/net_user.c

@@ -166,7 +166,7 @@ int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
 
 struct change_pre_exec_data {
 	int close_me;
-	int stdout;
+	int stdout_fd;
 };
 
 static void change_pre_exec(void *arg)
@@ -174,7 +174,7 @@ static void change_pre_exec(void *arg)
 	struct change_pre_exec_data *data = arg;
 
 	close(data->close_me);
-	dup2(data->stdout, 1);
+	dup2(data->stdout_fd, 1);
 }
 
 static int change_tramp(char **argv, char *output, int output_len)
@@ -189,7 +189,7 @@ static int change_tramp(char **argv, char *output, int output_len)
 		return err;
 	}
 	pe_data.close_me = fds[0];
-	pe_data.stdout = fds[1];
+	pe_data.stdout_fd = fds[1];
 	pid = run_helper(change_pre_exec, &pe_data, argv);
 
 	if (pid > 0)	/* Avoid hang as we won't get data in failure case. */

+ 7 - 7
arch/um/drivers/slip_user.c

@@ -55,8 +55,8 @@ static int set_up_tty(int fd)
 }
 
 struct slip_pre_exec_data {
-	int stdin;
-	int stdout;
+	int stdin_fd;
+	int stdout_fd;
 	int close_me;
 };
 
@@ -64,9 +64,9 @@ static void slip_pre_exec(void *arg)
 {
 	struct slip_pre_exec_data *data = arg;
 
-	if (data->stdin >= 0)
-		dup2(data->stdin, 0);
-	dup2(data->stdout, 1);
+	if (data->stdin_fd >= 0)
+		dup2(data->stdin_fd, 0);
+	dup2(data->stdout_fd, 1);
 	if (data->close_me >= 0)
 		close(data->close_me);
 }
@@ -85,8 +85,8 @@ static int slip_tramp(char **argv, int fd)
 	}
 
 	err = 0;
-	pe_data.stdin = fd;
-	pe_data.stdout = fds[1];
+	pe_data.stdin_fd = fd;
+	pe_data.stdout_fd = fds[1];
 	pe_data.close_me = fds[0];
 	err = run_helper(slip_pre_exec, &pe_data, argv);
 	if (err < 0)

+ 8 - 8
arch/um/drivers/slirp_user.c

@@ -20,18 +20,18 @@ static int slirp_user_init(void *data, void *dev)
 }
 
 struct slirp_pre_exec_data {
-	int stdin;
-	int stdout;
+	int stdin_fd;
+	int stdout_fd;
 };
 
 static void slirp_pre_exec(void *arg)
 {
 	struct slirp_pre_exec_data *data = arg;
 
-	if (data->stdin != -1)
-		dup2(data->stdin, 0);
-	if (data->stdout != -1)
-		dup2(data->stdout, 1);
+	if (data->stdin_fd != -1)
+		dup2(data->stdin_fd, 0);
+	if (data->stdout_fd != -1)
+		dup2(data->stdout_fd, 1);
 }
 
 static int slirp_tramp(char **argv, int fd)
@@ -39,8 +39,8 @@ static int slirp_tramp(char **argv, int fd)
 	struct slirp_pre_exec_data pe_data;
 	int pid;
 
-	pe_data.stdin = fd;
-	pe_data.stdout = fd;
+	pe_data.stdin_fd = fd;
+	pe_data.stdout_fd = fd;
 	pid = run_helper(slirp_pre_exec, &pe_data, argv);
 
 	return pid;

+ 0 - 1
arch/um/include/asm/Kbuild

@@ -21,7 +21,6 @@ generic-y += param.h
 generic-y += pci.h
 generic-y += percpu.h
 generic-y += preempt.h
-generic-y += sections.h
 generic-y += switch_to.h
 generic-y += topology.h
 generic-y += trace_clock.h

+ 1 - 2
arch/um/include/asm/ptrace-generic.h

@@ -8,7 +8,6 @@
 
 #ifndef __ASSEMBLY__
 
-#include <asm/ptrace-abi.h>
 #include <sysdep/ptrace.h>
 
 struct pt_regs {
@@ -37,7 +36,7 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value);
 
 extern int arch_copy_tls(struct task_struct *new);
 extern void clear_flushed_tls(struct task_struct *task);
-extern void syscall_trace_enter(struct pt_regs *regs);
+extern int syscall_trace_enter(struct pt_regs *regs);
 extern void syscall_trace_leave(struct pt_regs *regs);
 
 #endif

+ 9 - 0
arch/um/include/asm/sections.h

@@ -0,0 +1,9 @@
+#ifndef __UM_SECTIONS_H
+#define __UM_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char __binary_start[];
+extern char __syscall_stub_start[], __syscall_stub_end[];
+
+#endif

+ 1 - 1
arch/um/include/asm/thread_info.h

@@ -10,7 +10,7 @@
 
 #include <asm/types.h>
 #include <asm/page.h>
-#include <asm/uaccess.h>
+#include <asm/segment.h>
 
 struct thread_info {
 	struct task_struct	*task;		/* main task structure */

+ 25 - 151
arch/um/include/asm/uaccess.h

@@ -1,178 +1,52 @@
 /* 
  * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2015 Richard Weinberger (richard@nod.at)
  * Licensed under the GPL
  */
 
 #ifndef __UM_UACCESS_H
 #define __UM_UACCESS_H
 
-/* thread_info has a mm_segment_t in it, so put the definition up here */
-typedef struct {
-	unsigned long seg;
-} mm_segment_t;
-
-#include <linux/thread_info.h>
-#include <linux/errno.h>
-#include <asm/processor.h>
+#include <asm/thread_info.h>
 #include <asm/elf.h>
 
-#define VERIFY_READ 0
-#define VERIFY_WRITE 1
-
-/*
- * The fs value determines whether argument validity checking should be
- * performed or not.  If get_fs() == USER_DS, checking is performed, with
- * get_fs() == KERNEL_DS, checking is bypassed.
- *
- * For historical reasons, these macros are grossly misnamed.
- */
-
-#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
-
-#define KERNEL_DS	MAKE_MM_SEG(0xFFFFFFFF)
-#define USER_DS		MAKE_MM_SEG(TASK_SIZE)
-
-#define get_ds()	(KERNEL_DS)
-#define get_fs()	(current_thread_info()->addr_limit)
-#define set_fs(x)	(current_thread_info()->addr_limit = (x))
-
-#define segment_eq(a, b) ((a).seg == (b).seg)
-
 #define __under_task_size(addr, size) \
 	(((unsigned long) (addr) < TASK_SIZE) && \
 	 (((unsigned long) (addr) + (size)) < TASK_SIZE))
 
-#define __access_ok_vsyscall(type, addr, size) \
-	 ((type == VERIFY_READ) && \
-	  ((unsigned long) (addr) >= FIXADDR_USER_START) && \
+#define __access_ok_vsyscall(addr, size) \
+	  (((unsigned long) (addr) >= FIXADDR_USER_START) && \
 	  ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
 	  ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))
 
 #define __addr_range_nowrap(addr, size) \
 	((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
 
-#define access_ok(type, addr, size) \
-	(__addr_range_nowrap(addr, size) && \
-	 (__under_task_size(addr, size) || \
-	  __access_ok_vsyscall(type, addr, size) || \
-	  segment_eq(get_fs(), KERNEL_DS)))
-
-extern int copy_from_user(void *to, const void __user *from, int n);
-extern int copy_to_user(void __user *to, const void *from, int n);
-
-/*
- * strncpy_from_user: - Copy a NUL terminated string from userspace.
- * @dst:   Destination address, in kernel space.  This buffer must be at
- *         least @count bytes long.
- * @src:   Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * If @count is smaller than the length of the string, copies @count bytes
- * and returns @count.
- */
-
-extern int strncpy_from_user(char *dst, const char __user *src, int count);
-
-/*
- * __clear_user: - Zero a block of memory in user space, with less checking.
- * @to:   Destination address, in user space.
- * @n:    Number of bytes to zero.
- *
- * Zero a block of memory in user space.  Caller must check
- * the specified block with access_ok() before calling this function.
- *
- * Returns number of bytes that could not be cleared.
- * On success, this will be zero.
- */
-extern int __clear_user(void __user *mem, int len);
-
-/*
- * clear_user: - Zero a block of memory in user space.
- * @to:   Destination address, in user space.
- * @n:    Number of bytes to zero.
- *
- * Zero a block of memory in user space.
- *
- * Returns number of bytes that could not be cleared.
- * On success, this will be zero.
- */
-extern int clear_user(void __user *mem, int len);
-
-/*
- * strlen_user: - Get the size of a string in user space.
- * @str: The string to measure.
- * @n:   The maximum valid length
- *
- * Get the size of a NUL-terminated string in user space.
- *
- * Returns the size of the string INCLUDING the terminating NUL.
- * On exception, returns 0.
- * If the string is too long, returns a value greater than @n.
- */
-extern int strnlen_user(const void __user *str, int len);
-
-#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
-
-#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
-
+extern long __copy_from_user(void *to, const void __user *from, unsigned long n);
+extern long __copy_to_user(void __user *to, const void *from, unsigned long n);
+extern long __strncpy_from_user(char *dst, const char __user *src, long count);
+extern long __strnlen_user(const void __user *str, long len);
+extern unsigned long __clear_user(void __user *mem, unsigned long len);
+static inline int __access_ok(unsigned long addr, unsigned long size);
+
+/* Teach asm-generic/uaccess.h that we have C functions for these. */
+#define __access_ok __access_ok
+#define __clear_user __clear_user
+#define __copy_to_user __copy_to_user
+#define __copy_from_user __copy_from_user
+#define __strnlen_user __strnlen_user
+#define __strncpy_from_user __strncpy_from_user
 #define __copy_to_user_inatomic __copy_to_user
 #define __copy_from_user_inatomic __copy_from_user
 
-#define __get_user(x, ptr) \
-({ \
-	const __typeof__(*(ptr)) __user *__private_ptr = (ptr);	\
-	__typeof__(x) __private_val;			\
-	int __private_ret = -EFAULT;			\
-	(x) = (__typeof__(*(__private_ptr)))0;				\
-	if (__copy_from_user((__force void *)&__private_val, (__private_ptr),\
-			     sizeof(*(__private_ptr))) == 0) {		\
-		(x) = (__typeof__(*(__private_ptr))) __private_val;	\
-		__private_ret = 0;					\
-	}								\
-	__private_ret;							\
-}) 
-
-#define get_user(x, ptr) \
-({ \
-        const __typeof__((*(ptr))) __user *private_ptr = (ptr); \
-        (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
-	 __get_user(x, private_ptr) : ((x) = (__typeof__(*ptr))0, -EFAULT)); \
-})
-
-#define __put_user(x, ptr) \
-({ \
-        __typeof__(*(ptr)) __user *__private_ptr = ptr; \
-        __typeof__(*(__private_ptr)) __private_val; \
-        int __private_ret = -EFAULT; \
-        __private_val = (__typeof__(*(__private_ptr))) (x); \
-        if (__copy_to_user((__private_ptr), &__private_val, \
-			   sizeof(*(__private_ptr))) == 0) { \
-		__private_ret = 0; \
-	} \
-        __private_ret; \
-})
-
-#define put_user(x, ptr) \
-({ \
-        __typeof__(*(ptr)) __user *private_ptr = (ptr); \
-        (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
-	 __put_user(x, private_ptr) : -EFAULT); \
-})
-
-#define strlen_user(str) strnlen_user(str, ~0U >> 1)
+#include <asm-generic/uaccess.h>
 
-struct exception_table_entry
+static inline int __access_ok(unsigned long addr, unsigned long size)
 {
-        unsigned long insn;
-	unsigned long fixup;
-};
+	return __addr_range_nowrap(addr, size) &&
+		(__under_task_size(addr, size) ||
+		__access_ok_vsyscall(addr, size) ||
+		segment_eq(get_fs(), KERNEL_DS));
+}
 
 #endif

+ 2 - 22
arch/um/include/shared/init.h

@@ -40,28 +40,8 @@
 typedef int (*initcall_t)(void);
 typedef void (*exitcall_t)(void);
 
-#ifndef __KERNEL__
-#ifndef __section
-# define __section(S) __attribute__ ((__section__(#S)))
-#endif
-
-#if __GNUC__ == 3
-
-#if __GNUC_MINOR__ >= 3
-# define __used			__attribute__((__used__))
-#else
-# define __used			__attribute__((__unused__))
-#endif
-
-#else
-#if __GNUC__ == 4
-# define __used			__attribute__((__used__))
-#endif
-#endif
-
-#else
 #include <linux/compiler.h>
-#endif
+
 /* These are for everybody (although not all archs will actually
    discard it in modules) */
 #define __init		__section(.init.text)
@@ -131,7 +111,7 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
 #define __uml_postsetup_call	__used __section(.uml.postsetup.init)
 #define __uml_exit_call		__used __section(.uml.exitcall.exit)
 
-#ifndef __KERNEL__
+#ifdef __UM_HOST__
 
 #define __define_initcall(level,fn) \
 	static initcall_t __initcall_##fn __used \

+ 2 - 0
arch/um/include/shared/os.h

@@ -301,4 +301,6 @@ extern int get_pty(void);
 /* sys-$ARCH/task_size.c */
 extern unsigned long os_get_top_address(void);
 
+long syscall(long number, ...);
+
 #endif

+ 1 - 1
arch/um/include/shared/user.h

@@ -17,7 +17,7 @@
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
 
 /* This is to get size_t */
-#ifdef __KERNEL__
+#ifndef __UM_HOST__
 #include <linux/types.h>
 #else
 #include <stddef.h>

+ 2 - 0
arch/um/kernel/ksyms.c

@@ -42,3 +42,5 @@ EXPORT_SYMBOL(os_makedev);
 EXPORT_SYMBOL(add_sigio_fd);
 EXPORT_SYMBOL(ignore_sigio_fd);
 EXPORT_SYMBOL(sigio_broken);
+
+EXPORT_SYMBOL(syscall);

+ 3 - 4
arch/um/kernel/physmem.c

@@ -8,6 +8,7 @@
 #include <linux/mm.h>
 #include <linux/pfn.h>
 #include <asm/page.h>
+#include <asm/sections.h>
 #include <as-layout.h>
 #include <init.h>
 #include <kern.h>
@@ -55,8 +56,6 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
 	}
 }
 
-extern int __syscall_stub_start;
-
 /**
  * setup_physmem() - Setup physical memory for UML
  * @start:	Start address of the physical kernel memory,
@@ -110,8 +109,8 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
 	 * Special kludge - This page will be mapped in to userspace processes
 	 * from physmem_fd, so it needs to be written out there.
 	 */
-	os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
-	os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
+	os_seek_file(physmem_fd, __pa(__syscall_stub_start));
+	os_write_file(physmem_fd, __syscall_stub_start, PAGE_SIZE);
 	os_fsync_file(physmem_fd);
 
 	bootmap_size = init_bootmem(pfn, pfn + delta);

+ 4 - 3
arch/um/kernel/ptrace.c

@@ -8,6 +8,7 @@
 #include <linux/sched.h>
 #include <linux/tracehook.h>
 #include <asm/uaccess.h>
+#include <asm/ptrace-abi.h>
 
 void user_enable_single_step(struct task_struct *child)
 {
@@ -131,7 +132,7 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
  * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
  * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
  */
-void syscall_trace_enter(struct pt_regs *regs)
+int syscall_trace_enter(struct pt_regs *regs)
 {
 	audit_syscall_entry(UPT_SYSCALL_NR(&regs->regs),
 			    UPT_SYSCALL_ARG1(&regs->regs),
@@ -140,9 +141,9 @@ void syscall_trace_enter(struct pt_regs *regs)
 			    UPT_SYSCALL_ARG4(&regs->regs));
 
 	if (!test_thread_flag(TIF_SYSCALL_TRACE))
-		return;
+		return 0;
 
-	tracehook_report_syscall_entry(regs);
+	return tracehook_report_syscall_entry(regs);
 }
 
 void syscall_trace_leave(struct pt_regs *regs)

+ 3 - 4
arch/um/kernel/skas/mmu.c

@@ -8,12 +8,11 @@
 #include <linux/slab.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
+#include <asm/sections.h>
 #include <as-layout.h>
 #include <os.h>
 #include <skas.h>
 
-extern int __syscall_stub_start;
-
 static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
 			 unsigned long kernel)
 {
@@ -93,7 +92,7 @@ void uml_setup_stubs(struct mm_struct *mm)
 	int err, ret;
 
 	ret = init_stub_pte(mm, STUB_CODE,
-			    (unsigned long) &__syscall_stub_start);
+			    (unsigned long) __syscall_stub_start);
 	if (ret)
 		goto out;
 
@@ -101,7 +100,7 @@ void uml_setup_stubs(struct mm_struct *mm)
 	if (ret)
 		goto out;
 
-	mm->context.stub_pages[0] = virt_to_page(&__syscall_stub_start);
+	mm->context.stub_pages[0] = virt_to_page(__syscall_stub_start);
 	mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack);
 
 	/* dup_mmap already holds mmap_sem */

+ 5 - 1
arch/um/kernel/skas/syscall.c

@@ -18,7 +18,10 @@ void handle_syscall(struct uml_pt_regs *r)
 	long result;
 	int syscall;
 
-	syscall_trace_enter(regs);
+	if (syscall_trace_enter(regs)) {
+		result = -ENOSYS;
+		goto out;
+	}
 
 	/*
 	 * This should go in the declaration of syscall, but when I do that,
@@ -34,6 +37,7 @@ void handle_syscall(struct uml_pt_regs *r)
 		result = -ENOSYS;
 	else result = EXECUTE_SYSCALL(syscall, regs);
 
+out:
 	PT_REGS_SET_SYSCALL_RETURN(regs, result);
 
 	syscall_trace_leave(regs);

+ 17 - 30
arch/um/kernel/skas/uaccess.c

@@ -87,10 +87,10 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
 	return n;
 }
 
-static int buffer_op(unsigned long addr, int len, int is_write,
-		     int (*op)(unsigned long, int, void *), void *arg)
+static long buffer_op(unsigned long addr, int len, int is_write,
+		      int (*op)(unsigned long, int, void *), void *arg)
 {
-	int size, remain, n;
+	long size, remain, n;
 
 	size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
 	remain = len;
@@ -139,18 +139,16 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
 	return 0;
 }
 
-int copy_from_user(void *to, const void __user *from, int n)
+long __copy_from_user(void *to, const void __user *from, unsigned long n)
 {
 	if (segment_eq(get_fs(), KERNEL_DS)) {
 		memcpy(to, (__force void*)from, n);
 		return 0;
 	}
 
-	return access_ok(VERIFY_READ, from, n) ?
-	       buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
-	       n;
+	return buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to);
 }
-EXPORT_SYMBOL(copy_from_user);
+EXPORT_SYMBOL(__copy_from_user);
 
 static int copy_chunk_to_user(unsigned long to, int len, void *arg)
 {
@@ -161,18 +159,16 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
 	return 0;
 }
 
-int copy_to_user(void __user *to, const void *from, int n)
+long __copy_to_user(void __user *to, const void *from, unsigned long n)
 {
 	if (segment_eq(get_fs(), KERNEL_DS)) {
 		memcpy((__force void *) to, from, n);
 		return 0;
 	}
 
-	return access_ok(VERIFY_WRITE, to, n) ?
-	       buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
-	       n;
+	return buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from);
 }
-EXPORT_SYMBOL(copy_to_user);
+EXPORT_SYMBOL(__copy_to_user);
 
 static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
 {
@@ -188,9 +184,9 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
 	return 0;
 }
 
-int strncpy_from_user(char *dst, const char __user *src, int count)
+long __strncpy_from_user(char *dst, const char __user *src, long count)
 {
-	int n;
+	long n;
 	char *ptr = dst;
 
 	if (segment_eq(get_fs(), KERNEL_DS)) {
@@ -198,16 +194,13 @@ int strncpy_from_user(char *dst, const char __user *src, int count)
 		return strnlen(dst, count);
 	}
 
-	if (!access_ok(VERIFY_READ, src, 1))
-		return -EFAULT;
-
 	n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
 		      &ptr);
 	if (n != 0)
 		return -EFAULT;
 	return strnlen(dst, count);
 }
-EXPORT_SYMBOL(strncpy_from_user);
+EXPORT_SYMBOL(__strncpy_from_user);
 
 static int clear_chunk(unsigned long addr, int len, void *unused)
 {
@@ -215,22 +208,16 @@ static int clear_chunk(unsigned long addr, int len, void *unused)
 	return 0;
 }
 
-int __clear_user(void __user *mem, int len)
-{
-	return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
-}
-
-int clear_user(void __user *mem, int len)
+unsigned long __clear_user(void __user *mem, unsigned long len)
 {
 	if (segment_eq(get_fs(), KERNEL_DS)) {
 		memset((__force void*)mem, 0, len);
 		return 0;
 	}
 
-	return access_ok(VERIFY_WRITE, mem, len) ?
-	       buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len;
+	return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
 }
-EXPORT_SYMBOL(clear_user);
+EXPORT_SYMBOL(__clear_user);
 
 static int strnlen_chunk(unsigned long str, int len, void *arg)
 {
@@ -244,7 +231,7 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
 	return 0;
 }
 
-int strnlen_user(const void __user *str, int len)
+long __strnlen_user(const void __user *str, long len)
 {
 	int count = 0, n;
 
@@ -256,4 +243,4 @@ int strnlen_user(const void __user *str, int len)
 		return count + 1;
 	return 0;
 }
-EXPORT_SYMBOL(strnlen_user);
+EXPORT_SYMBOL(__strnlen_user);

+ 5 - 0
arch/um/kernel/trap.c

@@ -220,6 +220,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
 		show_regs(container_of(regs, struct pt_regs, regs));
 		panic("Segfault with no mm");
 	}
+	else if (!is_user && address < TASK_SIZE) {
+		show_regs(container_of(regs, struct pt_regs, regs));
+		panic("Kernel tried to access user memory at addr 0x%lx, ip 0x%lx",
+		       address, ip);
+	}
 
 	if (SEGV_IS_FIXABLE(&fi))
 		err = handle_page_fault(address, ip, is_write, is_user,

+ 1 - 3
arch/um/kernel/um_arch.c

@@ -248,8 +248,6 @@ EXPORT_SYMBOL(end_iomem);
 
 #define MIN_VMALLOC (32 * 1024 * 1024)
 
-extern char __binary_start;
-
 int __init linux_main(int argc, char **argv)
 {
 	unsigned long avail, diff;
@@ -294,7 +292,7 @@ int __init linux_main(int argc, char **argv)
 		physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
 	}
 
-	uml_physmem = (unsigned long) &__binary_start & PAGE_MASK;
+	uml_physmem = (unsigned long) __binary_start & PAGE_MASK;
 
 	/* Reserve up to 4M after the current brk */
 	uml_reserved = ROUND_4M(brk_start) + (1 << 22);

+ 3 - 3
arch/um/os-Linux/drivers/tuntap_user.c

@@ -47,7 +47,7 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
 }
 
 struct tuntap_pre_exec_data {
-	int stdout;
+	int stdout_fd;
 	int close_me;
 };
 
@@ -55,7 +55,7 @@ static void tuntap_pre_exec(void *arg)
 {
 	struct tuntap_pre_exec_data *data = arg;
 
-	dup2(data->stdout, 1);
+	dup2(data->stdout_fd, 1);
 	close(data->close_me);
 }
 
@@ -74,7 +74,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
 
 	sprintf(version_buf, "%d", UML_NET_VERSION);
 
-	data.stdout = remote;
+	data.stdout_fd = remote;
 	data.close_me = me;
 
 	pid = run_helper(tuntap_pre_exec, &data, argv);

+ 1 - 0
arch/um/os-Linux/file.c

@@ -13,6 +13,7 @@
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/un.h>
+#include <sys/types.h>
 #include <os.h>
 
 static void copy_stat(struct uml_stat *dst, const struct stat64 *src)

+ 5 - 3
arch/um/os-Linux/signal.c

@@ -112,9 +112,11 @@ void timer_init(void)
 
 void set_sigstack(void *sig_stack, int size)
 {
-	stack_t stack = ((stack_t) { .ss_flags	= 0,
-				     .ss_sp	= (__ptr_t) sig_stack,
-				     .ss_size 	= size - sizeof(void *) });
+	stack_t stack = {
+		.ss_flags = 0,
+		.ss_sp = sig_stack,
+		.ss_size = size - sizeof(void *)
+	};
 
 	if (sigaltstack(&stack, NULL) != 0)
 		panic("enabling signal stack failed, errno = %d\n", errno);

+ 3 - 3
arch/um/os-Linux/skas/mem.c

@@ -18,7 +18,7 @@
 #include <sysdep/ptrace.h>
 #include <sysdep/stub.h>
 
-extern unsigned long batch_syscall_stub, __syscall_stub_start;
+extern char batch_syscall_stub[], __syscall_stub_start[];
 
 extern void wait_stub_done(int pid);
 
@@ -38,8 +38,8 @@ static int __init init_syscall_regs(void)
 {
 	get_safe_registers(syscall_regs, NULL);
 	syscall_regs[REGS_IP_INDEX] = STUB_CODE +
-		((unsigned long) &batch_syscall_stub -
-		 (unsigned long) &__syscall_stub_start);
+		((unsigned long) batch_syscall_stub -
+		 (unsigned long) __syscall_stub_start);
 	return 0;
 }
 

+ 4 - 4
arch/um/os-Linux/skas/process.c

@@ -174,7 +174,7 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
 	handle_syscall(regs);
 }
 
-extern int __syscall_stub_start;
+extern char __syscall_stub_start[];
 
 static int userspace_tramp(void *stack)
 {
@@ -197,7 +197,7 @@ static int userspace_tramp(void *stack)
 	 * This has a pte, but it can't be mapped in with the usual
 	 * tlb_flush mechanism because this is part of that mechanism
 	 */
-	fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
+	fd = phys_mapping(to_phys(__syscall_stub_start), &offset);
 	addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
 		      PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
 	if (addr == MAP_FAILED) {
@@ -223,7 +223,7 @@ static int userspace_tramp(void *stack)
 
 		unsigned long v = STUB_CODE +
 				  (unsigned long) stub_segv_handler -
-				  (unsigned long) &__syscall_stub_start;
+				  (unsigned long) __syscall_stub_start;
 
 		set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
 		sigemptyset(&sa.sa_mask);
@@ -447,7 +447,7 @@ static int __init init_thread_regs(void)
 	/* Set parent's instruction pointer to start of clone-stub */
 	thread_regs[REGS_IP_INDEX] = STUB_CODE +
 				(unsigned long) stub_clone_handler -
-				(unsigned long) &__syscall_stub_start;
+				(unsigned long) __syscall_stub_start;
 	thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
 		sizeof(void *);
 #ifdef __SIGNAL_FRAMESIZE

+ 1 - 0
arch/x86/um/asm/checksum.h

@@ -3,6 +3,7 @@
 
 #include <linux/string.h>
 #include <linux/in6.h>
+#include <linux/uaccess.h>
 
 /*
  * computes the checksum of a memory block at buff, length len,

+ 0 - 2
arch/x86/um/asm/elf.h

@@ -200,8 +200,6 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
 
 typedef struct user_i387_struct elf_fpregset_t;
 
-#define task_pt_regs(t) (&(t)->thread.regs)
-
 struct task_struct;
 
 extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);

+ 2 - 0
arch/x86/um/asm/processor.h

@@ -28,6 +28,8 @@ static inline void rep_nop(void)
 #define cpu_relax()		rep_nop()
 #define cpu_relax_lowlatency()	cpu_relax()
 
+#define task_pt_regs(t) (&(t)->thread.regs)
+
 #include <asm/processor-generic.h>
 
 #endif

+ 8 - 0
arch/x86/um/asm/segment.h

@@ -7,4 +7,12 @@ extern int host_gdt_entry_tls_min;
 #define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min
 #define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
 
+typedef struct {
+	unsigned long seg;
+} mm_segment_t;
+
+#define MAKE_MM_SEG(s)	((mm_segment_t) { (s) })
+#define KERNEL_DS	MAKE_MM_SEG(~0UL)
+#define USER_DS		MAKE_MM_SEG(TASK_SIZE)
+
 #endif

+ 1 - 0
arch/x86/um/ldt.c

@@ -6,6 +6,7 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/uaccess.h>
 #include <asm/unistd.h>
 #include <os.h>
 #include <skas.h>

+ 1 - 2
arch/x86/um/mem_32.c

@@ -7,8 +7,7 @@
  */
 
 #include <linux/mm.h>
-#include <asm/page.h>
-#include <asm/mman.h>
+#include <asm/elf.h>
 
 static struct vm_area_struct gate_vma;
 

+ 1 - 2
arch/x86/um/mem_64.c

@@ -1,6 +1,5 @@
 #include <linux/mm.h>
-#include <asm/page.h>
-#include <asm/mman.h>
+#include <asm/elf.h>
 
 const char *arch_vma_name(struct vm_area_struct *vma)
 {

+ 1 - 0
arch/x86/um/ptrace_32.c

@@ -6,6 +6,7 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <asm/uaccess.h>
+#include <asm/ptrace-abi.h>
 #include <skas.h>
 
 extern int arch_switch_tls(struct task_struct *to);

+ 1 - 0
arch/x86/um/ptrace_64.c

@@ -11,6 +11,7 @@
 #define __FRAME_OFFSETS
 #include <asm/ptrace.h>
 #include <asm/uaccess.h>
+#include <asm/ptrace-abi.h>
 
 /*
  * determines which flags the user has access to.

+ 3 - 3
arch/x86/um/shared/sysdep/tls.h

@@ -1,7 +1,7 @@
 #ifndef _SYSDEP_TLS_H
 #define _SYSDEP_TLS_H
 
-# ifndef __KERNEL__
+#ifdef __UM_HOST__
 
 /* Change name to avoid conflicts with the original one from <asm/ldt.h>, which
  * may be named user_desc (but in 2.4 and in header matching its API was named
@@ -22,11 +22,11 @@ typedef struct um_dup_user_desc {
 #endif
 } user_desc_t;
 
-# else /* __KERNEL__ */
+#else /* __UM_HOST__ */
 
 typedef struct user_desc user_desc_t;
 
-# endif /* __KERNEL__ */
+#endif /* __UM_HOST__ */
 
 extern int os_set_thread_area(user_desc_t *info, int pid);
 extern int os_get_thread_area(user_desc_t *info, int pid);

+ 2 - 1
arch/x86/um/signal.c

@@ -541,7 +541,8 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
 	 */
 	/* x86-64 should always use SA_RESTORER. */
 	if (ksig->ka.sa.sa_flags & SA_RESTORER)
-		err |= __put_user(ksig->ka.sa.sa_restorer, &frame->pretcode);
+		err |= __put_user((void *)ksig->ka.sa.sa_restorer,
+				  &frame->pretcode);
 	else
 		/* could use a vstub here */
 		return err;

+ 1 - 0
arch/x86/um/syscalls_64.c

@@ -6,6 +6,7 @@
  */
 
 #include <linux/sched.h>
+#include <linux/uaccess.h>
 #include <asm/prctl.h> /* XXX This should get the constants from libc */
 #include <os.h>
 

+ 1 - 0
arch/x86/um/tls_32.c

@@ -7,6 +7,7 @@
 #include <linux/sched.h>
 #include <linux/syscalls.h>
 #include <asm/uaccess.h>
+#include <asm/ptrace-abi.h>
 #include <os.h>
 #include <skas.h>
 #include <sysdep/tls.h>

+ 1 - 0
arch/x86/um/tls_64.c

@@ -1,4 +1,5 @@
 #include <linux/sched.h>
+#include <asm/ptrace-abi.h>
 
 void clear_flushed_tls(struct task_struct *task)
 {

+ 1 - 0
arch/x86/um/vdso/vma.c

@@ -10,6 +10,7 @@
 #include <linux/sched.h>
 #include <linux/mm.h>
 #include <asm/page.h>
+#include <asm/elf.h>
 #include <linux/init.h>
 
 static unsigned int __read_mostly vdso_enabled = 1;

+ 0 - 1
fs/Makefile

@@ -115,7 +115,6 @@ obj-$(CONFIG_AFS_FS)		+= afs/
 obj-$(CONFIG_NILFS2_FS)		+= nilfs2/
 obj-$(CONFIG_BEFS_FS)		+= befs/
 obj-$(CONFIG_HOSTFS)		+= hostfs/
-obj-$(CONFIG_HPPFS)		+= hppfs/
 obj-$(CONFIG_CACHEFILES)	+= cachefiles/
 obj-$(CONFIG_DEBUG_FS)		+= debugfs/
 obj-$(CONFIG_TRACING)		+= tracefs/

+ 0 - 6
fs/hppfs/Makefile

@@ -1,6 +0,0 @@
-#
-# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
-# Licensed under the GPL
-#
-
-obj-$(CONFIG_HPPFS) += hppfs.o

+ 0 - 765
fs/hppfs/hppfs.c

@@ -1,765 +0,0 @@
-/*
- * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
- * Licensed under the GPL
- */
-
-#include <linux/ctype.h>
-#include <linux/dcache.h>
-#include <linux/file.h>
-#include <linux/fs.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/list.h>
-#include <linux/module.h>
-#include <linux/mount.h>
-#include <linux/slab.h>
-#include <linux/statfs.h>
-#include <linux/types.h>
-#include <linux/pid_namespace.h>
-#include <linux/namei.h>
-#include <asm/uaccess.h>
-#include <os.h>
-
-static struct inode *get_inode(struct super_block *, struct dentry *);
-
-struct hppfs_data {
-	struct list_head list;
-	char contents[PAGE_SIZE - sizeof(struct list_head)];
-};
-
-struct hppfs_private {
-	struct file *proc_file;
-	int host_fd;
-	loff_t len;
-	struct hppfs_data *contents;
-};
-
-struct hppfs_inode_info {
-	struct dentry *proc_dentry;
-	struct inode vfs_inode;
-};
-
-static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
-{
-	return container_of(inode, struct hppfs_inode_info, vfs_inode);
-}
-
-#define HPPFS_SUPER_MAGIC 0xb00000ee
-
-static const struct super_operations hppfs_sbops;
-
-static int is_pid(struct dentry *dentry)
-{
-	struct super_block *sb;
-	int i;
-
-	sb = dentry->d_sb;
-	if (dentry->d_parent != sb->s_root)
-		return 0;
-
-	for (i = 0; i < dentry->d_name.len; i++) {
-		if (!isdigit(dentry->d_name.name[i]))
-			return 0;
-	}
-	return 1;
-}
-
-static char *dentry_name(struct dentry *dentry, int extra)
-{
-	struct dentry *parent;
-	char *root, *name;
-	const char *seg_name;
-	int len, seg_len, root_len;
-
-	len = 0;
-	parent = dentry;
-	while (parent->d_parent != parent) {
-		if (is_pid(parent))
-			len += strlen("pid") + 1;
-		else len += parent->d_name.len + 1;
-		parent = parent->d_parent;
-	}
-
-	root = "proc";
-	root_len = strlen(root);
-	len += root_len;
-	name = kmalloc(len + extra + 1, GFP_KERNEL);
-	if (name == NULL)
-		return NULL;
-
-	name[len] = '\0';
-	parent = dentry;
-	while (parent->d_parent != parent) {
-		if (is_pid(parent)) {
-			seg_name = "pid";
-			seg_len = strlen(seg_name);
-		}
-		else {
-			seg_name = parent->d_name.name;
-			seg_len = parent->d_name.len;
-		}
-
-		len -= seg_len + 1;
-		name[len] = '/';
-		memcpy(&name[len + 1], seg_name, seg_len);
-		parent = parent->d_parent;
-	}
-	memcpy(name, root, root_len);
-	return name;
-}
-
-static int file_removed(struct dentry *dentry, const char *file)
-{
-	char *host_file;
-	int extra, fd;
-
-	extra = 0;
-	if (file != NULL)
-		extra += strlen(file) + 1;
-
-	host_file = dentry_name(dentry, extra + strlen("/remove"));
-	if (host_file == NULL) {
-		printk(KERN_ERR "file_removed : allocation failed\n");
-		return -ENOMEM;
-	}
-
-	if (file != NULL) {
-		strcat(host_file, "/");
-		strcat(host_file, file);
-	}
-	strcat(host_file, "/remove");
-
-	fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
-	kfree(host_file);
-	if (fd > 0) {
-		os_close_file(fd);
-		return 1;
-	}
-	return 0;
-}
-
-static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
-				   unsigned int flags)
-{
-	struct dentry *proc_dentry, *parent;
-	struct qstr *name = &dentry->d_name;
-	struct inode *inode;
-	int err, deleted;
-
-	deleted = file_removed(dentry, NULL);
-	if (deleted < 0)
-		return ERR_PTR(deleted);
-	else if (deleted)
-		return ERR_PTR(-ENOENT);
-
-	parent = HPPFS_I(ino)->proc_dentry;
-	mutex_lock(&d_inode(parent)->i_mutex);
-	proc_dentry = lookup_one_len(name->name, parent, name->len);
-	mutex_unlock(&d_inode(parent)->i_mutex);
-
-	if (IS_ERR(proc_dentry))
-		return proc_dentry;
-
-	err = -ENOMEM;
-	inode = get_inode(ino->i_sb, proc_dentry);
-	if (!inode)
-		goto out;
-
- 	d_add(dentry, inode);
-	return NULL;
-
- out:
-	return ERR_PTR(err);
-}
-
-static const struct inode_operations hppfs_file_iops = {
-};
-
-static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
-			 loff_t *ppos, int is_user)
-{
-	ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
-	ssize_t n;
-
-	read = file_inode(file)->i_fop->read;
-
-	if (!is_user)
-		set_fs(KERNEL_DS);
-
-	n = (*read)(file, buf, count, &file->f_pos);
-
-	if (!is_user)
-		set_fs(USER_DS);
-
-	if (ppos)
-		*ppos = file->f_pos;
-	return n;
-}
-
-static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
-{
-	ssize_t n;
-	int cur, err;
-	char *new_buf;
-
-	n = -ENOMEM;
-	new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-	if (new_buf == NULL) {
-		printk(KERN_ERR "hppfs_read_file : kmalloc failed\n");
-		goto out;
-	}
-	n = 0;
-	while (count > 0) {
-		cur = min_t(ssize_t, count, PAGE_SIZE);
-		err = os_read_file(fd, new_buf, cur);
-		if (err < 0) {
-			printk(KERN_ERR "hppfs_read : read failed, "
-			       "errno = %d\n", err);
-			n = err;
-			goto out_free;
-		} else if (err == 0)
-			break;
-
-		if (copy_to_user(buf, new_buf, err)) {
-			n = -EFAULT;
-			goto out_free;
-		}
-		n += err;
-		count -= err;
-	}
- out_free:
-	kfree(new_buf);
- out:
-	return n;
-}
-
-static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
-			  loff_t *ppos)
-{
-	struct hppfs_private *hppfs = file->private_data;
-	struct hppfs_data *data;
-	loff_t off;
-	int err;
-
-	if (hppfs->contents != NULL) {
-		int rem;
-
-		if (*ppos >= hppfs->len)
-			return 0;
-
-		data = hppfs->contents;
-		off = *ppos;
-		while (off >= sizeof(data->contents)) {
-			data = list_entry(data->list.next, struct hppfs_data,
-					  list);
-			off -= sizeof(data->contents);
-		}
-
-		if (off + count > hppfs->len)
-			count = hppfs->len - off;
-		rem = copy_to_user(buf, &data->contents[off], count);
-		*ppos += count - rem;
-		if (rem > 0)
-			return -EFAULT;
-	} else if (hppfs->host_fd != -1) {
-		err = os_seek_file(hppfs->host_fd, *ppos);
-		if (err) {
-			printk(KERN_ERR "hppfs_read : seek failed, "
-			       "errno = %d\n", err);
-			return err;
-		}
-		err = hppfs_read_file(hppfs->host_fd, buf, count);
-		if (err < 0) {
-			printk(KERN_ERR "hppfs_read: read failed: %d\n", err);
-			return err;
-		}
-		count = err;
-		if (count > 0)
-			*ppos += count;
-	}
-	else count = read_proc(hppfs->proc_file, buf, count, ppos, 1);
-
-	return count;
-}
-
-static ssize_t hppfs_write(struct file *file, const char __user *buf,
-			   size_t len, loff_t *ppos)
-{
-	struct hppfs_private *data = file->private_data;
-	struct file *proc_file = data->proc_file;
-	ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
-
-	write = file_inode(proc_file)->i_fop->write;
-	return (*write)(proc_file, buf, len, ppos);
-}
-
-static int open_host_sock(char *host_file, int *filter_out)
-{
-	char *end;
-	int fd;
-
-	end = &host_file[strlen(host_file)];
-	strcpy(end, "/rw");
-	*filter_out = 1;
-	fd = os_connect_socket(host_file);
-	if (fd > 0)
-		return fd;
-
-	strcpy(end, "/r");
-	*filter_out = 0;
-	fd = os_connect_socket(host_file);
-	return fd;
-}
-
-static void free_contents(struct hppfs_data *head)
-{
-	struct hppfs_data *data;
-	struct list_head *ele, *next;
-
-	if (head == NULL)
-		return;
-
-	list_for_each_safe(ele, next, &head->list) {
-		data = list_entry(ele, struct hppfs_data, list);
-		kfree(data);
-	}
-	kfree(head);
-}
-
-static struct hppfs_data *hppfs_get_data(int fd, int filter,
-					 struct file *proc_file,
-					 struct file *hppfs_file,
-					 loff_t *size_out)
-{
-	struct hppfs_data *data, *new, *head;
-	int n, err;
-
-	err = -ENOMEM;
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
-	if (data == NULL) {
-		printk(KERN_ERR "hppfs_get_data : head allocation failed\n");
-		goto failed;
-	}
-
-	INIT_LIST_HEAD(&data->list);
-
-	head = data;
-	*size_out = 0;
-
-	if (filter) {
-		while ((n = read_proc(proc_file, data->contents,
-				      sizeof(data->contents), NULL, 0)) > 0)
-			os_write_file(fd, data->contents, n);
-		err = os_shutdown_socket(fd, 0, 1);
-		if (err) {
-			printk(KERN_ERR "hppfs_get_data : failed to shut down "
-			       "socket\n");
-			goto failed_free;
-		}
-	}
-	while (1) {
-		n = os_read_file(fd, data->contents, sizeof(data->contents));
-		if (n < 0) {
-			err = n;
-			printk(KERN_ERR "hppfs_get_data : read failed, "
-			       "errno = %d\n", err);
-			goto failed_free;
-		} else if (n == 0)
-			break;
-
-		*size_out += n;
-
-		if (n < sizeof(data->contents))
-			break;
-
-		new = kmalloc(sizeof(*data), GFP_KERNEL);
-		if (new == 0) {
-			printk(KERN_ERR "hppfs_get_data : data allocation "
-			       "failed\n");
-			err = -ENOMEM;
-			goto failed_free;
-		}
-
-		INIT_LIST_HEAD(&new->list);
-		list_add(&new->list, &data->list);
-		data = new;
-	}
-	return head;
-
- failed_free:
-	free_contents(head);
- failed:
-	return ERR_PTR(err);
-}
-
-static struct hppfs_private *hppfs_data(void)
-{
-	struct hppfs_private *data;
-
-	data = kmalloc(sizeof(*data), GFP_KERNEL);
-	if (data == NULL)
-		return data;
-
-	*data = ((struct hppfs_private ) { .host_fd  		= -1,
-					   .len  		= -1,
-					   .contents 		= NULL } );
-	return data;
-}
-
-static int file_mode(int fmode)
-{
-	if (fmode == (FMODE_READ | FMODE_WRITE))
-		return O_RDWR;
-	if (fmode == FMODE_READ)
-		return O_RDONLY;
-	if (fmode == FMODE_WRITE)
-		return O_WRONLY;
-	return 0;
-}
-
-static int hppfs_open(struct inode *inode, struct file *file)
-{
-	const struct cred *cred = file->f_cred;
-	struct hppfs_private *data;
-	struct path path;
-	char *host_file;
-	int err, fd, type, filter;
-
-	err = -ENOMEM;
-	data = hppfs_data();
-	if (data == NULL)
-		goto out;
-
-	host_file = dentry_name(file->f_path.dentry, strlen("/rw"));
-	if (host_file == NULL)
-		goto out_free2;
-
-	path.mnt = inode->i_sb->s_fs_info;
-	path.dentry = HPPFS_I(inode)->proc_dentry;
-
-	data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred);
-	err = PTR_ERR(data->proc_file);
-	if (IS_ERR(data->proc_file))
-		goto out_free1;
-
-	type = os_file_type(host_file);
-	if (type == OS_TYPE_FILE) {
-		fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
-		if (fd >= 0)
-			data->host_fd = fd;
-		else
-			printk(KERN_ERR "hppfs_open : failed to open '%s', "
-			       "errno = %d\n", host_file, -fd);
-
-		data->contents = NULL;
-	} else if (type == OS_TYPE_DIR) {
-		fd = open_host_sock(host_file, &filter);
-		if (fd > 0) {
-			data->contents = hppfs_get_data(fd, filter,
-							data->proc_file,
-							file, &data->len);
-			if (!IS_ERR(data->contents))
-				data->host_fd = fd;
-		} else
-			printk(KERN_ERR "hppfs_open : failed to open a socket "
-			       "in '%s', errno = %d\n", host_file, -fd);
-	}
-	kfree(host_file);
-
-	file->private_data = data;
-	return 0;
-
- out_free1:
-	kfree(host_file);
- out_free2:
-	free_contents(data->contents);
-	kfree(data);
- out:
-	return err;
-}
-
-static int hppfs_dir_open(struct inode *inode, struct file *file)
-{
-	const struct cred *cred = file->f_cred;
-	struct hppfs_private *data;
-	struct path path;
-	int err;
-
-	err = -ENOMEM;
-	data = hppfs_data();
-	if (data == NULL)
-		goto out;
-
-	path.mnt = inode->i_sb->s_fs_info;
-	path.dentry = HPPFS_I(inode)->proc_dentry;
-	data->proc_file = dentry_open(&path, file_mode(file->f_mode), cred);
-	err = PTR_ERR(data->proc_file);
-	if (IS_ERR(data->proc_file))
-		goto out_free;
-
-	file->private_data = data;
-	return 0;
-
- out_free:
-	kfree(data);
- out:
-	return err;
-}
-
-static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
-{
-	struct hppfs_private *data = file->private_data;
-	struct file *proc_file = data->proc_file;
-	loff_t (*llseek)(struct file *, loff_t, int);
-	loff_t ret;
-
-	llseek = file_inode(proc_file)->i_fop->llseek;
-	if (llseek != NULL) {
-		ret = (*llseek)(proc_file, off, where);
-		if (ret < 0)
-			return ret;
-	}
-
-	return default_llseek(file, off, where);
-}
-
-static int hppfs_release(struct inode *inode, struct file *file)
-{
-	struct hppfs_private *data = file->private_data;
-	struct file *proc_file = data->proc_file;
-	if (proc_file)
-		fput(proc_file);
-	kfree(data);
-	return 0;
-}
-
-static const struct file_operations hppfs_file_fops = {
-	.owner		= NULL,
-	.llseek		= hppfs_llseek,
-	.read		= hppfs_read,
-	.write		= hppfs_write,
-	.open		= hppfs_open,
-	.release	= hppfs_release,
-};
-
-struct hppfs_dirent {
-	struct dir_context ctx;
-	struct dir_context *caller;
-	struct dentry *dentry;
-};
-
-static int hppfs_filldir(struct dir_context *ctx, const char *name, int size,
-			 loff_t offset, u64 inode, unsigned int type)
-{
-	struct hppfs_dirent *dirent =
-		container_of(ctx, struct hppfs_dirent, ctx);
-
-	if (file_removed(dirent->dentry, name))
-		return 0;
-
-	dirent->caller->pos = dirent->ctx.pos;
-	return !dir_emit(dirent->caller, name, size, inode, type);
-}
-
-static int hppfs_readdir(struct file *file, struct dir_context *ctx)
-{
-	struct hppfs_private *data = file->private_data;
-	struct file *proc_file = data->proc_file;
-	struct hppfs_dirent d = {
-		.ctx.actor	= hppfs_filldir,
-		.caller		= ctx,
-		.dentry  	= file->f_path.dentry
-	};
-	int err;
-	proc_file->f_pos = ctx->pos;
-	err = iterate_dir(proc_file, &d.ctx);
-	ctx->pos = d.ctx.pos;
-	return err;
-}
-
-static const struct file_operations hppfs_dir_fops = {
-	.owner		= NULL,
-	.iterate	= hppfs_readdir,
-	.open		= hppfs_dir_open,
-	.llseek		= default_llseek,
-	.release	= hppfs_release,
-};
-
-static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
-{
-	sf->f_blocks = 0;
-	sf->f_bfree = 0;
-	sf->f_bavail = 0;
-	sf->f_files = 0;
-	sf->f_ffree = 0;
-	sf->f_type = HPPFS_SUPER_MAGIC;
-	return 0;
-}
-
-static struct inode *hppfs_alloc_inode(struct super_block *sb)
-{
-	struct hppfs_inode_info *hi;
-
-	hi = kmalloc(sizeof(*hi), GFP_KERNEL);
-	if (!hi)
-		return NULL;
-
-	hi->proc_dentry = NULL;
-	inode_init_once(&hi->vfs_inode);
-	return &hi->vfs_inode;
-}
-
-void hppfs_evict_inode(struct inode *ino)
-{
-	clear_inode(ino);
-	dput(HPPFS_I(ino)->proc_dentry);
-	mntput(ino->i_sb->s_fs_info);
-}
-
-static void hppfs_i_callback(struct rcu_head *head)
-{
-	struct inode *inode = container_of(head, struct inode, i_rcu);
-	kfree(HPPFS_I(inode));
-}
-
-static void hppfs_destroy_inode(struct inode *inode)
-{
-	call_rcu(&inode->i_rcu, hppfs_i_callback);
-}
-
-static const struct super_operations hppfs_sbops = {
-	.alloc_inode	= hppfs_alloc_inode,
-	.destroy_inode	= hppfs_destroy_inode,
-	.evict_inode	= hppfs_evict_inode,
-	.statfs		= hppfs_statfs,
-};
-
-static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
-			  int buflen)
-{
-	struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;
-	return d_inode(proc_dentry)->i_op->readlink(proc_dentry, buffer,
-						    buflen);
-}
-
-static const char *hppfs_follow_link(struct dentry *dentry, void **cookie)
-{
-	struct dentry *proc_dentry = HPPFS_I(d_inode(dentry))->proc_dentry;
-
-	return d_inode(proc_dentry)->i_op->follow_link(proc_dentry, cookie);
-}
-
-static void hppfs_put_link(struct inode *inode, void *cookie)
-{
-	struct inode *proc_inode = d_inode(HPPFS_I(inode)->proc_dentry);
-
-	if (proc_inode->i_op->put_link)
-		proc_inode->i_op->put_link(proc_inode, cookie);
-}
-
-static const struct inode_operations hppfs_dir_iops = {
-	.lookup		= hppfs_lookup,
-};
-
-static const struct inode_operations hppfs_link_iops = {
-	.readlink	= hppfs_readlink,
-	.follow_link	= hppfs_follow_link,
-	.put_link	= hppfs_put_link,
-};
-
-static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
-{
-	struct inode *proc_ino = d_inode(dentry);
-	struct inode *inode = new_inode(sb);
-
-	if (!inode) {
-		dput(dentry);
-		return NULL;
-	}
-
-	if (d_is_dir(dentry)) {
-		inode->i_op = &hppfs_dir_iops;
-		inode->i_fop = &hppfs_dir_fops;
-	} else if (d_is_symlink(dentry)) {
-		inode->i_op = &hppfs_link_iops;
-		inode->i_fop = &hppfs_file_fops;
-	} else {
-		inode->i_op = &hppfs_file_iops;
-		inode->i_fop = &hppfs_file_fops;
-	}
-
-	HPPFS_I(inode)->proc_dentry = dentry;
-
-	inode->i_uid = proc_ino->i_uid;
-	inode->i_gid = proc_ino->i_gid;
-	inode->i_atime = proc_ino->i_atime;
-	inode->i_mtime = proc_ino->i_mtime;
-	inode->i_ctime = proc_ino->i_ctime;
-	inode->i_ino = proc_ino->i_ino;
-	inode->i_mode = proc_ino->i_mode;
-	set_nlink(inode, proc_ino->i_nlink);
-	inode->i_size = proc_ino->i_size;
-	inode->i_blocks = proc_ino->i_blocks;
-
-	return inode;
-}
-
-static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
-{
-	struct inode *root_inode;
-	struct vfsmount *proc_mnt;
-	int err = -ENOENT;
-
-	proc_mnt = mntget(task_active_pid_ns(current)->proc_mnt);
-	if (IS_ERR(proc_mnt))
-		goto out;
-
-	sb->s_blocksize = 1024;
-	sb->s_blocksize_bits = 10;
-	sb->s_magic = HPPFS_SUPER_MAGIC;
-	sb->s_op = &hppfs_sbops;
-	sb->s_fs_info = proc_mnt;
-
-	err = -ENOMEM;
-	root_inode = get_inode(sb, dget(proc_mnt->mnt_root));
-	sb->s_root = d_make_root(root_inode);
-	if (!sb->s_root)
-		goto out_mntput;
-
-	return 0;
-
- out_mntput:
-	mntput(proc_mnt);
- out:
-	return(err);
-}
-
-static struct dentry *hppfs_read_super(struct file_system_type *type,
-			    int flags, const char *dev_name,
-			    void *data)
-{
-	return mount_nodev(type, flags, data, hppfs_fill_super);
-}
-
-static struct file_system_type hppfs_type = {
-	.owner 		= THIS_MODULE,
-	.name 		= "hppfs",
-	.mount 		= hppfs_read_super,
-	.kill_sb	= kill_anon_super,
-	.fs_flags 	= 0,
-};
-MODULE_ALIAS_FS("hppfs");
-
-static int __init init_hppfs(void)
-{
-	return register_filesystem(&hppfs_type);
-}
-
-static void __exit exit_hppfs(void)
-{
-	unregister_filesystem(&hppfs_type);
-}
-
-module_init(init_hppfs)
-module_exit(exit_hppfs)
-MODULE_LICENSE("GPL");