summaryrefslogtreecommitdiffstats
path: root/arch/um/include
diff options
context:
space:
mode:
Diffstat (limited to 'arch/um/include')
-rw-r--r--arch/um/include/asm/a.out-core.h27
-rw-r--r--arch/um/include/asm/apic.h4
-rw-r--r--arch/um/include/asm/auxvec.h4
-rw-r--r--arch/um/include/asm/bugs.h6
-rw-r--r--arch/um/include/asm/cache.h17
-rw-r--r--arch/um/include/asm/checksum.h6
-rw-r--r--arch/um/include/asm/common.lds.S130
-rw-r--r--arch/um/include/asm/cputime.h6
-rw-r--r--arch/um/include/asm/current.h13
-rw-r--r--arch/um/include/asm/delay.h20
-rw-r--r--arch/um/include/asm/desc.h16
-rw-r--r--arch/um/include/asm/device.h7
-rw-r--r--arch/um/include/asm/dma-mapping.h128
-rw-r--r--arch/um/include/asm/dma.h10
-rw-r--r--arch/um/include/asm/emergency-restart.h6
-rw-r--r--arch/um/include/asm/fixmap.h99
-rw-r--r--arch/um/include/asm/futex.h6
-rw-r--r--arch/um/include/asm/hardirq.h25
-rw-r--r--arch/um/include/asm/hw_irq.h7
-rw-r--r--arch/um/include/asm/io.h57
-rw-r--r--arch/um/include/asm/irq.h23
-rw-r--r--arch/um/include/asm/irq_regs.h1
-rw-r--r--arch/um/include/asm/irq_vectors.h20
-rw-r--r--arch/um/include/asm/irqflags.h6
-rw-r--r--arch/um/include/asm/kdebug.h1
-rw-r--r--arch/um/include/asm/kmap_types.h29
-rw-r--r--arch/um/include/asm/mmu.h22
-rw-r--r--arch/um/include/asm/mmu_context.h54
-rw-r--r--arch/um/include/asm/mutex.h9
-rw-r--r--arch/um/include/asm/page.h122
-rw-r--r--arch/um/include/asm/page_offset.h1
-rw-r--r--arch/um/include/asm/param.h20
-rw-r--r--arch/um/include/asm/pci.h7
-rw-r--r--arch/um/include/asm/pda.h31
-rw-r--r--arch/um/include/asm/pgalloc.h72
-rw-r--r--arch/um/include/asm/pgtable-2level.h53
-rw-r--r--arch/um/include/asm/pgtable-3level.h146
-rw-r--r--arch/um/include/asm/pgtable.h366
-rw-r--r--arch/um/include/asm/processor-generic.h136
-rw-r--r--arch/um/include/asm/ptrace-generic.h55
-rw-r--r--arch/um/include/asm/required-features.h9
-rw-r--r--arch/um/include/asm/sections.h7
-rw-r--r--arch/um/include/asm/segment.h10
-rw-r--r--arch/um/include/asm/setup.h10
-rw-r--r--arch/um/include/asm/smp.h33
-rw-r--r--arch/um/include/asm/suspend.h4
-rw-r--r--arch/um/include/asm/system.h35
-rw-r--r--arch/um/include/asm/thread_info.h83
-rw-r--r--arch/um/include/asm/timex.h13
-rw-r--r--arch/um/include/asm/tlb.h127
-rw-r--r--arch/um/include/asm/tlbflush.h31
-rw-r--r--arch/um/include/asm/topology.h6
-rw-r--r--arch/um/include/asm/uaccess.h99
-rw-r--r--arch/um/include/asm/xor.h6
-rw-r--r--arch/um/include/shared/aio.h28
-rw-r--r--arch/um/include/shared/arch.h15
-rw-r--r--arch/um/include/shared/as-layout.h67
-rw-r--r--arch/um/include/shared/chan_kern.h50
-rw-r--r--arch/um/include/shared/chan_user.h55
-rw-r--r--arch/um/include/shared/common-offsets.h54
-rw-r--r--arch/um/include/shared/elf_user.h19
-rw-r--r--arch/um/include/shared/frame_kern.h32
-rw-r--r--arch/um/include/shared/init.h151
-rw-r--r--arch/um/include/shared/initrd.h22
-rw-r--r--arch/um/include/shared/irq_kern.h28
-rw-r--r--arch/um/include/shared/irq_user.h30
-rw-r--r--arch/um/include/shared/kern.h40
-rw-r--r--arch/um/include/shared/kern_util.h69
-rw-r--r--arch/um/include/shared/ldt.h37
-rw-r--r--arch/um/include/shared/line.h105
-rw-r--r--arch/um/include/shared/longjmp.h23
-rw-r--r--arch/um/include/shared/mconsole.h98
-rw-r--r--arch/um/include/shared/mconsole_kern.h52
-rw-r--r--arch/um/include/shared/mem.h22
-rw-r--r--arch/um/include/shared/mem_kern.h30
-rw-r--r--arch/um/include/shared/mem_user.h62
-rw-r--r--arch/um/include/shared/net_kern.h70
-rw-r--r--arch/um/include/shared/net_user.h53
-rw-r--r--arch/um/include/shared/os.h303
-rw-r--r--arch/um/include/shared/process.h17
-rw-r--r--arch/um/include/shared/ptrace_user.h55
-rw-r--r--arch/um/include/shared/registers.h24
-rw-r--r--arch/um/include/shared/sigio.h14
-rw-r--r--arch/um/include/shared/skas/mm_id.h17
-rw-r--r--arch/um/include/shared/skas/proc_mm.h44
-rw-r--r--arch/um/include/shared/skas/skas.h22
-rw-r--r--arch/um/include/shared/skas/stub-data.h18
-rw-r--r--arch/um/include/shared/skas_ptrace.h14
-rw-r--r--arch/um/include/shared/skas_ptregs.h6
-rw-r--r--arch/um/include/shared/syscall.h12
-rw-r--r--arch/um/include/shared/sysrq.h7
-rw-r--r--arch/um/include/shared/task.h9
-rw-r--r--arch/um/include/shared/tlb.h15
-rw-r--r--arch/um/include/shared/ubd_user.h26
-rw-r--r--arch/um/include/shared/um_malloc.h19
-rw-r--r--arch/um/include/shared/um_mmu.h24
-rw-r--r--arch/um/include/shared/um_uaccess.h97
-rw-r--r--arch/um/include/shared/user.h45
98 files changed, 4241 insertions, 0 deletions
diff --git a/arch/um/include/asm/a.out-core.h b/arch/um/include/asm/a.out-core.h
new file mode 100644
index 0000000..995643b
--- /dev/null
+++ b/arch/um/include/asm/a.out-core.h
@@ -0,0 +1,27 @@
+/* a.out coredump register dumper
+ *
+ * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef __UM_A_OUT_CORE_H
+#define __UM_A_OUT_CORE_H
+
+#ifdef __KERNEL__
+
+#include <linux/user.h>
+
+/*
+ * fill in the user structure for an a.out core dump
+ */
+static inline void aout_dump_thread(struct pt_regs *regs, struct user *u)
+{
+}
+
+#endif /* __KERNEL__ */
+#endif /* __UM_A_OUT_CORE_H */
diff --git a/arch/um/include/asm/apic.h b/arch/um/include/asm/apic.h
new file mode 100644
index 0000000..876dee8
--- /dev/null
+++ b/arch/um/include/asm/apic.h
@@ -0,0 +1,4 @@
+#ifndef __UM_APIC_H
+#define __UM_APIC_H
+
+#endif
diff --git a/arch/um/include/asm/auxvec.h b/arch/um/include/asm/auxvec.h
new file mode 100644
index 0000000..1e5e1c2
--- /dev/null
+++ b/arch/um/include/asm/auxvec.h
@@ -0,0 +1,4 @@
+#ifndef __UM_AUXVEC_H
+#define __UM_AUXVEC_H
+
+#endif
diff --git a/arch/um/include/asm/bugs.h b/arch/um/include/asm/bugs.h
new file mode 100644
index 0000000..6a72e24
--- /dev/null
+++ b/arch/um/include/asm/bugs.h
@@ -0,0 +1,6 @@
+#ifndef __UM_BUGS_H
+#define __UM_BUGS_H
+
+void check_bugs(void);
+
+#endif
diff --git a/arch/um/include/asm/cache.h b/arch/um/include/asm/cache.h
new file mode 100644
index 0000000..19e1bdd
--- /dev/null
+++ b/arch/um/include/asm/cache.h
@@ -0,0 +1,17 @@
+#ifndef __UM_CACHE_H
+#define __UM_CACHE_H
+
+
+#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT)
+# define L1_CACHE_SHIFT (CONFIG_X86_L1_CACHE_SHIFT)
+#elif defined(CONFIG_UML_X86) /* 64-bit */
+# define L1_CACHE_SHIFT 6 /* Should be 7 on Intel */
+#else
+/* XXX: this was taken from x86, now it's completely random. Luckily only
+ * affects SMP padding. */
+# define L1_CACHE_SHIFT 5
+#endif
+
+#define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT)
+
+#endif
diff --git a/arch/um/include/asm/checksum.h b/arch/um/include/asm/checksum.h
new file mode 100644
index 0000000..5b50136
--- /dev/null
+++ b/arch/um/include/asm/checksum.h
@@ -0,0 +1,6 @@
+#ifndef __UM_CHECKSUM_H
+#define __UM_CHECKSUM_H
+
+#include "sysdep/checksum.h"
+
+#endif
diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S
new file mode 100644
index 0000000..cb02486
--- /dev/null
+++ b/arch/um/include/asm/common.lds.S
@@ -0,0 +1,130 @@
+#include <asm-generic/vmlinux.lds.h>
+
+ .fini : { *(.fini) } =0x9090
+ _etext = .;
+ PROVIDE (etext = .);
+
+ . = ALIGN(4096);
+ _sdata = .;
+ PROVIDE (sdata = .);
+
+ RODATA
+
+ .unprotected : { *(.unprotected) }
+ . = ALIGN(4096);
+ PROVIDE (_unprotected_end = .);
+
+ . = ALIGN(4096);
+ .note : { *(.note.*) }
+ __ex_table : {
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
+ }
+
+ BUG_TABLE
+
+ .uml.setup.init : {
+ __uml_setup_start = .;
+ *(.uml.setup.init)
+ __uml_setup_end = .;
+ }
+
+ .uml.help.init : {
+ __uml_help_start = .;
+ *(.uml.help.init)
+ __uml_help_end = .;
+ }
+
+ .uml.postsetup.init : {
+ __uml_postsetup_start = .;
+ *(.uml.postsetup.init)
+ __uml_postsetup_end = .;
+ }
+
+ .init.setup : {
+ __setup_start = .;
+ *(.init.setup)
+ __setup_end = .;
+ }
+
+ . = ALIGN(32);
+ .data.percpu : {
+ __per_cpu_start = . ;
+ *(.data.percpu)
+ __per_cpu_end = . ;
+ }
+
+ .initcall.init : {
+ __initcall_start = .;
+ INITCALLS
+ __initcall_end = .;
+ }
+
+ .con_initcall.init : {
+ __con_initcall_start = .;
+ *(.con_initcall.init)
+ __con_initcall_end = .;
+ }
+
+ .uml.initcall.init : {
+ __uml_initcall_start = .;
+ *(.uml.initcall.init)
+ __uml_initcall_end = .;
+ }
+ __init_end = .;
+
+ SECURITY_INIT
+
+ .exitcall : {
+ __exitcall_begin = .;
+ *(.exitcall.exit)
+ __exitcall_end = .;
+ }
+
+ .uml.exitcall : {
+ __uml_exitcall_begin = .;
+ *(.uml.exitcall.exit)
+ __uml_exitcall_end = .;
+ }
+
+ . = ALIGN(4);
+ .altinstructions : {
+ __alt_instructions = .;
+ *(.altinstructions)
+ __alt_instructions_end = .;
+ }
+ .altinstr_replacement : { *(.altinstr_replacement) }
+ /* .exit.text is discard at runtime, not link time, to deal with references
+ from .altinstructions and .eh_frame */
+ .exit.text : { *(.exit.text) }
+ .exit.data : { *(.exit.data) }
+
+ .preinit_array : {
+ __preinit_array_start = .;
+ *(.preinit_array)
+ __preinit_array_end = .;
+ }
+ .init_array : {
+ __init_array_start = .;
+ *(.init_array)
+ __init_array_end = .;
+ }
+ .fini_array : {
+ __fini_array_start = .;
+ *(.fini_array)
+ __fini_array_end = .;
+ }
+
+ . = ALIGN(4096);
+ .init.ramfs : {
+ __initramfs_start = .;
+ *(.init.ramfs)
+ __initramfs_end = .;
+ }
+
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.exitcall.exit)
+ }
+
diff --git a/arch/um/include/asm/cputime.h b/arch/um/include/asm/cputime.h
new file mode 100644
index 0000000..c84acba
--- /dev/null
+++ b/arch/um/include/asm/cputime.h
@@ -0,0 +1,6 @@
+#ifndef __UM_CPUTIME_H
+#define __UM_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* __UM_CPUTIME_H */
diff --git a/arch/um/include/asm/current.h b/arch/um/include/asm/current.h
new file mode 100644
index 0000000..c2191d9
--- /dev/null
+++ b/arch/um/include/asm/current.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_CURRENT_H
+#define __UM_CURRENT_H
+
+#include "linux/thread_info.h"
+
+#define current (current_thread_info()->task)
+
+#endif
diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h
new file mode 100644
index 0000000..c71e32b
--- /dev/null
+++ b/arch/um/include/asm/delay.h
@@ -0,0 +1,20 @@
+#ifndef __UM_DELAY_H
+#define __UM_DELAY_H
+
+#define MILLION 1000000
+
+/* Undefined on purpose */
+extern void __bad_udelay(void);
+
+extern void __udelay(unsigned long usecs);
+extern void __delay(unsigned long loops);
+
+#define udelay(n) ((__builtin_constant_p(n) && (n) > 20000) ? \
+ __bad_udelay() : __udelay(n))
+
+/* It appears that ndelay is not used at all for UML, and has never been
+ * implemented. */
+extern void __unimplemented_ndelay(void);
+#define ndelay(n) __unimplemented_ndelay()
+
+#endif
diff --git a/arch/um/include/asm/desc.h b/arch/um/include/asm/desc.h
new file mode 100644
index 0000000..4ec34a5
--- /dev/null
+++ b/arch/um/include/asm/desc.h
@@ -0,0 +1,16 @@
+#ifndef __UM_DESC_H
+#define __UM_DESC_H
+
+/* Taken from asm-i386/desc.h, it's the only thing we need. The rest wouldn't
+ * compile, and has never been used. */
+#define LDT_empty(info) (\
+ (info)->base_addr == 0 && \
+ (info)->limit == 0 && \
+ (info)->contents == 0 && \
+ (info)->read_exec_only == 1 && \
+ (info)->seg_32bit == 0 && \
+ (info)->limit_in_pages == 0 && \
+ (info)->seg_not_present == 1 && \
+ (info)->useable == 0 )
+
+#endif
diff --git a/arch/um/include/asm/device.h b/arch/um/include/asm/device.h
new file mode 100644
index 0000000..d8f9872
--- /dev/null
+++ b/arch/um/include/asm/device.h
@@ -0,0 +1,7 @@
+/*
+ * Arch specific extensions to struct device
+ *
+ * This file is released under the GPLv2
+ */
+#include <asm-generic/device.h>
+
diff --git a/arch/um/include/asm/dma-mapping.h b/arch/um/include/asm/dma-mapping.h
new file mode 100644
index 0000000..90fc708
--- /dev/null
+++ b/arch/um/include/asm/dma-mapping.h
@@ -0,0 +1,128 @@
+#ifndef _ASM_DMA_MAPPING_H
+#define _ASM_DMA_MAPPING_H
+
+#include <asm/scatterlist.h>
+
+static inline int
+dma_supported(struct device *dev, u64 mask)
+{
+ BUG();
+ return(0);
+}
+
+static inline int
+dma_set_mask(struct device *dev, u64 dma_mask)
+{
+ BUG();
+ return(0);
+}
+
+static inline void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+ gfp_t flag)
+{
+ BUG();
+ return((void *) 0);
+}
+
+static inline void
+dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+ dma_addr_t dma_handle)
+{
+ BUG();
+}
+
+static inline dma_addr_t
+dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return(0);
+}
+
+static inline void
+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline dma_addr_t
+dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return(0);
+}
+
+static inline void
+dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int
+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction direction)
+{
+ BUG();
+ return(0);
+}
+
+static inline void
+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+#define dma_is_consistent(d, h) (1)
+
+static inline int
+dma_get_cache_alignment(void)
+{
+ BUG();
+ return(0);
+}
+
+static inline void
+dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline void
+dma_cache_sync(struct device *dev, void *vaddr, size_t size,
+ enum dma_data_direction direction)
+{
+ BUG();
+}
+
+static inline int
+dma_mapping_error(struct device *dev, dma_addr_t dma_handle)
+{
+ BUG();
+ return 0;
+}
+
+#endif
diff --git a/arch/um/include/asm/dma.h b/arch/um/include/asm/dma.h
new file mode 100644
index 0000000..9f6139a
--- /dev/null
+++ b/arch/um/include/asm/dma.h
@@ -0,0 +1,10 @@
+#ifndef __UM_DMA_H
+#define __UM_DMA_H
+
+#include "asm/io.h"
+
+extern unsigned long uml_physmem;
+
+#define MAX_DMA_ADDRESS (uml_physmem)
+
+#endif
diff --git a/arch/um/include/asm/emergency-restart.h b/arch/um/include/asm/emergency-restart.h
new file mode 100644
index 0000000..108d8c4
--- /dev/null
+++ b/arch/um/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_EMERGENCY_RESTART_H
+#define _ASM_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_EMERGENCY_RESTART_H */
diff --git a/arch/um/include/asm/fixmap.h b/arch/um/include/asm/fixmap.h
new file mode 100644
index 0000000..69c0252
--- /dev/null
+++ b/arch/um/include/asm/fixmap.h
@@ -0,0 +1,99 @@
+#ifndef __UM_FIXMAP_H
+#define __UM_FIXMAP_H
+
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/kmap_types.h>
+#include <asm/archparam.h>
+#include <asm/page.h>
+#include <linux/threads.h>
+
+/*
+ * Here we define all the compile-time 'special' virtual
+ * addresses. The point is to have a constant address at
+ * compile time, but to set the physical address only
+ * in the boot process. We allocate these special addresses
+ * from the end of virtual memory (0xfffff000) backwards.
+ * Also this lets us do fail-safe vmalloc(), we
+ * can guarantee that these special addresses and
+ * vmalloc()-ed addresses never overlap.
+ *
+ * these 'compile-time allocated' memory buffers are
+ * fixed-size 4k pages. (or larger if used with an increment
+ * highger than 1) use fixmap_set(idx,phys) to associate
+ * physical memory with fixmap indices.
+ *
+ * TLB entries of such buffers will not be flushed across
+ * task switches.
+ */
+
+/*
+ * on UP currently we will have no trace of the fixmap mechanizm,
+ * no page table allocations, etc. This might change in the
+ * future, say framebuffers for the console driver(s) could be
+ * fix-mapped?
+ */
+enum fixed_addresses {
+#ifdef CONFIG_HIGHMEM
+ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
+ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
+#endif
+ __end_of_fixed_addresses
+};
+
+extern void __set_fixmap (enum fixed_addresses idx,
+ unsigned long phys, pgprot_t flags);
+
+#define set_fixmap(idx, phys) \
+ __set_fixmap(idx, phys, PAGE_KERNEL)
+/*
+ * Some hardware wants to get fixmapped without caching.
+ */
+#define set_fixmap_nocache(idx, phys) \
+ __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE)
+/*
+ * used by vmalloc.c.
+ *
+ * Leave one empty page between vmalloc'ed areas and
+ * the start of the fixmap, and leave one page empty
+ * at the top of mem..
+ */
+
+#define FIXADDR_TOP (TASK_SIZE - 2 * PAGE_SIZE)
+#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT)
+#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
+
+#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
+#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
+
+extern void __this_fixmap_does_not_exist(void);
+
+/*
+ * 'index to address' translation. If anyone tries to use the idx
+ * directly without tranlation, we catch the bug with a NULL-deference
+ * kernel oops. Illegal ranges of incoming indices are caught too.
+ */
+static inline unsigned long fix_to_virt(const unsigned int idx)
+{
+ /*
+ * this branch gets completely eliminated after inlining,
+ * except when someone tries to use fixaddr indices in an
+ * illegal way. (such as mixing up address types or using
+ * out-of-range indices).
+ *
+ * If it doesn't get removed, the linker will complain
+ * loudly with a reasonably clear error message..
+ */
+ if (idx >= __end_of_fixed_addresses)
+ __this_fixmap_does_not_exist();
+
+ return __fix_to_virt(idx);
+}
+
+static inline unsigned long virt_to_fix(const unsigned long vaddr)
+{
+ BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START);
+ return __virt_to_fix(vaddr);
+}
+
+#endif
diff --git a/arch/um/include/asm/futex.h b/arch/um/include/asm/futex.h
new file mode 100644
index 0000000..6a332a9
--- /dev/null
+++ b/arch/um/include/asm/futex.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_FUTEX_H
+#define _ASM_FUTEX_H
+
+#include <asm-generic/futex.h>
+
+#endif
diff --git a/arch/um/include/asm/hardirq.h b/arch/um/include/asm/hardirq.h
new file mode 100644
index 0000000..313ebb8
--- /dev/null
+++ b/arch/um/include/asm/hardirq.h
@@ -0,0 +1,25 @@
+/* (c) 2004 cw@f00f.org, GPLv2 blah blah */
+
+#ifndef __ASM_UM_HARDIRQ_H
+#define __ASM_UM_HARDIRQ_H
+
+#include <linux/threads.h>
+#include <linux/irq.h>
+
+/* NOTE: When SMP works again we might want to make this
+ * ____cacheline_aligned or maybe use per_cpu state? --cw */
+typedef struct {
+ unsigned int __softirq_pending;
+} irq_cpustat_t;
+
+#include <linux/irq_cpustat.h>
+
+/* As this would be very strange for UML to get we BUG() after the
+ * printk. */
+static inline void ack_bad_irq(unsigned int irq)
+{
+ printk(KERN_ERR "unexpected IRQ %02x\n", irq);
+ BUG();
+}
+
+#endif /* __ASM_UM_HARDIRQ_H */
diff --git a/arch/um/include/asm/hw_irq.h b/arch/um/include/asm/hw_irq.h
new file mode 100644
index 0000000..1cf84cf
--- /dev/null
+++ b/arch/um/include/asm/hw_irq.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_UM_HW_IRQ_H
+#define _ASM_UM_HW_IRQ_H
+
+#include "asm/irq.h"
+#include "asm/archparam.h"
+
+#endif
diff --git a/arch/um/include/asm/io.h b/arch/um/include/asm/io.h
new file mode 100644
index 0000000..44e8b8c
--- /dev/null
+++ b/arch/um/include/asm/io.h
@@ -0,0 +1,57 @@
+#ifndef __UM_IO_H
+#define __UM_IO_H
+
+#include "asm/page.h"
+
+#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */
+
+static inline int inb(unsigned long i) { return(0); }
+static inline void outb(char c, unsigned long i) { }
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are pretty trivial
+ */
+static inline unsigned long virt_to_phys(volatile void * address)
+{
+ return __pa((void *) address);
+}
+
+static inline void * phys_to_virt(unsigned long address)
+{
+ return __va(address);
+}
+
+/*
+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem
+ * access
+ */
+#define xlate_dev_mem_ptr(p) __va(p)
+
+/*
+ * Convert a virtual cached pointer to an uncached pointer
+ */
+#define xlate_dev_kmem_ptr(p) p
+
+static inline void writeb(unsigned char b, volatile void __iomem *addr)
+{
+ *(volatile unsigned char __force *) addr = b;
+}
+static inline void writew(unsigned short b, volatile void __iomem *addr)
+{
+ *(volatile unsigned short __force *) addr = b;
+}
+static inline void writel(unsigned int b, volatile void __iomem *addr)
+{
+ *(volatile unsigned int __force *) addr = b;
+}
+static inline void writeq(unsigned int b, volatile void __iomem *addr)
+{
+ *(volatile unsigned long long __force *) addr = b;
+}
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
+#define __raw_writeq writeq
+
+#endif
diff --git a/arch/um/include/asm/irq.h b/arch/um/include/asm/irq.h
new file mode 100644
index 0000000..4a2037f
--- /dev/null
+++ b/arch/um/include/asm/irq.h
@@ -0,0 +1,23 @@
+#ifndef __UM_IRQ_H
+#define __UM_IRQ_H
+
+#define TIMER_IRQ 0
+#define UMN_IRQ 1
+#define CONSOLE_IRQ 2
+#define CONSOLE_WRITE_IRQ 3
+#define UBD_IRQ 4
+#define UM_ETH_IRQ 5
+#define SSL_IRQ 6
+#define SSL_WRITE_IRQ 7
+#define ACCEPT_IRQ 8
+#define MCONSOLE_IRQ 9
+#define WINCH_IRQ 10
+#define SIGIO_WRITE_IRQ 11
+#define TELNETD_IRQ 12
+#define XTERM_IRQ 13
+#define RANDOM_IRQ 14
+
+#define LAST_IRQ RANDOM_IRQ
+#define NR_IRQS (LAST_IRQ + 1)
+
+#endif
diff --git a/arch/um/include/asm/irq_regs.h b/arch/um/include/asm/irq_regs.h
new file mode 100644
index 0000000..3dd9c0b
--- /dev/null
+++ b/arch/um/include/asm/irq_regs.h
@@ -0,0 +1 @@
+#include <asm-generic/irq_regs.h>
diff --git a/arch/um/include/asm/irq_vectors.h b/arch/um/include/asm/irq_vectors.h
new file mode 100644
index 0000000..62ddba6
--- /dev/null
+++ b/arch/um/include/asm/irq_vectors.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_IRQ_VECTORS_H
+#define __UM_IRQ_VECTORS_H
+
+#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
+ * 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/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h
new file mode 100644
index 0000000..659b9ab
--- /dev/null
+++ b/arch/um/include/asm/irqflags.h
@@ -0,0 +1,6 @@
+#ifndef __UM_IRQFLAGS_H
+#define __UM_IRQFLAGS_H
+
+/* Empty for now */
+
+#endif
diff --git a/arch/um/include/asm/kdebug.h b/arch/um/include/asm/kdebug.h
new file mode 100644
index 0000000..6ece1b0
--- /dev/null
+++ b/arch/um/include/asm/kdebug.h
@@ -0,0 +1 @@
+#include <asm-generic/kdebug.h>
diff --git a/arch/um/include/asm/kmap_types.h b/arch/um/include/asm/kmap_types.h
new file mode 100644
index 0000000..6c03acd
--- /dev/null
+++ b/arch/um/include/asm/kmap_types.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_KMAP_TYPES_H
+#define __UM_KMAP_TYPES_H
+
+/* No more #include "asm/arch/kmap_types.h" ! */
+
+enum km_type {
+ KM_BOUNCE_READ,
+ KM_SKB_SUNRPC_DATA,
+ KM_SKB_DATA_SOFTIRQ,
+ KM_USER0,
+ KM_USER1,
+ KM_UML_USERCOPY, /* UML specific, for copy_*_user - used in do_op_one_page */
+ KM_BIO_SRC_IRQ,
+ KM_BIO_DST_IRQ,
+ KM_PTE0,
+ KM_PTE1,
+ KM_IRQ0,
+ KM_IRQ1,
+ KM_SOFTIRQ0,
+ KM_SOFTIRQ1,
+ KM_TYPE_NR
+};
+
+#endif
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h
new file mode 100644
index 0000000..2cf35c2
--- /dev/null
+++ b/arch/um/include/asm/mmu.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MMU_H
+#define __MMU_H
+
+#include "um_mmu.h"
+
+#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
+ * 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/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h
new file mode 100644
index 0000000..54f42e8
--- /dev/null
+++ b/arch/um/include/asm/mmu_context.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_MMU_CONTEXT_H
+#define __UM_MMU_CONTEXT_H
+
+#include "linux/sched.h"
+#include "um_mmu.h"
+
+extern void arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm);
+extern void arch_exit_mmap(struct mm_struct *mm);
+
+#define get_mmu_context(task) do ; while(0)
+#define activate_context(tsk) do ; while(0)
+
+#define deactivate_mm(tsk,mm) do { } while (0)
+
+extern void force_flush_all(void);
+
+static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
+{
+ /*
+ * This is called by fs/exec.c and sys_unshare()
+ * when the new ->mm is used for the first time.
+ */
+ __switch_mm(&new->context.id);
+ arch_dup_mmap(old, new);
+}
+
+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
+ struct task_struct *tsk)
+{
+ unsigned cpu = smp_processor_id();
+
+ if(prev != next){
+ cpu_clear(cpu, prev->cpu_vm_mask);
+ cpu_set(cpu, next->cpu_vm_mask);
+ if(next != &init_mm)
+ __switch_mm(&next->context.id);
+ }
+}
+
+static inline void enter_lazy_tlb(struct mm_struct *mm,
+ struct task_struct *tsk)
+{
+}
+
+extern int init_new_context(struct task_struct *task, struct mm_struct *mm);
+
+extern void destroy_context(struct mm_struct *mm);
+
+#endif
diff --git a/arch/um/include/asm/mutex.h b/arch/um/include/asm/mutex.h
new file mode 100644
index 0000000..458c1f7
--- /dev/null
+++ b/arch/um/include/asm/mutex.h
@@ -0,0 +1,9 @@
+/*
+ * Pull in the generic implementation for the mutex fastpath.
+ *
+ * TODO: implement optimized primitives instead, or leave the generic
+ * implementation in place, or pick the atomic_xchg() based generic
+ * implementation. (see asm-generic/mutex-xchg.h for details)
+ */
+
+#include <asm-generic/mutex-dec.h>
diff --git a/arch/um/include/asm/page.h b/arch/um/include/asm/page.h
new file mode 100644
index 0000000..55f28a0
--- /dev/null
+++ b/arch/um/include/asm/page.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
+ * Copyright 2003 PathScale, Inc.
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PAGE_H
+#define __UM_PAGE_H
+
+#include <linux/const.h>
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT 12
+#define PAGE_SIZE (_AC(1, UL) << PAGE_SHIFT)
+#define PAGE_MASK (~(PAGE_SIZE-1))
+
+#ifndef __ASSEMBLY__
+
+struct page;
+
+#include <linux/types.h>
+#include <sysdep/vm-flags.h>
+
+/*
+ * These are used to make use of C type-checking..
+ */
+
+#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
+#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+
+#define clear_user_page(page, vaddr, pg) clear_page(page)
+#define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
+
+#if defined(CONFIG_3_LEVEL_PGTABLES) && !defined(CONFIG_64BIT)
+
+typedef struct { unsigned long pte_low, pte_high; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+#define pte_val(x) ((x).pte_low | ((unsigned long long) (x).pte_high << 32))
+
+#define pte_get_bits(pte, bits) ((pte).pte_low & (bits))
+#define pte_set_bits(pte, bits) ((pte).pte_low |= (bits))
+#define pte_clear_bits(pte, bits) ((pte).pte_low &= ~(bits))
+#define pte_copy(to, from) ({ (to).pte_high = (from).pte_high; \
+ smp_wmb(); \
+ (to).pte_low = (from).pte_low; })
+#define pte_is_zero(pte) (!((pte).pte_low & ~_PAGE_NEWPAGE) && !(pte).pte_high)
+#define pte_set_val(pte, phys, prot) \
+ ({ (pte).pte_high = (phys) >> 32; \
+ (pte).pte_low = (phys) | pgprot_val(prot); })
+
+#define pmd_val(x) ((x).pmd)
+#define __pmd(x) ((pmd_t) { (x) } )
+
+typedef unsigned long long pfn_t;
+typedef unsigned long long phys_t;
+
+#else
+
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pgd; } pgd_t;
+
+#ifdef CONFIG_3_LEVEL_PGTABLES
+typedef struct { unsigned long pmd; } pmd_t;
+#define pmd_val(x) ((x).pmd)
+#define __pmd(x) ((pmd_t) { (x) } )
+#endif
+
+#define pte_val(x) ((x).pte)
+
+
+#define pte_get_bits(p, bits) ((p).pte & (bits))
+#define pte_set_bits(p, bits) ((p).pte |= (bits))
+#define pte_clear_bits(p, bits) ((p).pte &= ~(bits))
+#define pte_copy(to, from) ((to).pte = (from).pte)
+#define pte_is_zero(p) (!((p).pte & ~_PAGE_NEWPAGE))
+#define pte_set_val(p, phys, prot) (p).pte = (phys | pgprot_val(prot))
+
+typedef unsigned long pfn_t;
+typedef unsigned long phys_t;
+
+#endif
+
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+typedef struct page *pgtable_t;
+
+#define pgd_val(x) ((x).pgd)
+#define pgprot_val(x) ((x).pgprot)
+
+#define __pte(x) ((pte_t) { (x) } )
+#define __pgd(x) ((pgd_t) { (x) } )
+#define __pgprot(x) ((pgprot_t) { (x) } )
+
+extern unsigned long uml_physmem;
+
+#define PAGE_OFFSET (uml_physmem)
+#define KERNELBASE PAGE_OFFSET
+
+#define __va_space (8*1024*1024)
+
+#include "mem.h"
+
+/* Cast to unsigned long before casting to void * to avoid a warning from
+ * mmap_kmem about cutting a long long down to a void *. Not sure that
+ * casting is the right thing, but 32-bit UML can't have 64-bit virtual
+ * addresses
+ */
+#define __pa(virt) to_phys((void *) (unsigned long) (virt))
+#define __va(phys) to_virt((unsigned long) (phys))
+
+#define phys_to_pfn(p) ((pfn_t) ((p) >> PAGE_SHIFT))
+#define pfn_to_phys(pfn) ((phys_t) ((pfn) << PAGE_SHIFT))
+
+#define pfn_valid(pfn) ((pfn) < max_mapnr)
+#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
+
+#include <asm-generic/memory_model.h>
+#include <asm-generic/page.h>
+
+#endif /* __ASSEMBLY__ */
+#endif /* __UM_PAGE_H */
diff --git a/arch/um/include/asm/page_offset.h b/arch/um/include/asm/page_offset.h
new file mode 100644
index 0000000..1c168df
--- /dev/null
+++ b/arch/um/include/asm/page_offset.h
@@ -0,0 +1 @@
+#define PAGE_OFFSET_RAW (uml_physmem)
diff --git a/arch/um/include/asm/param.h b/arch/um/include/asm/param.h
new file mode 100644
index 0000000..e44f4e6
--- /dev/null
+++ b/arch/um/include/asm/param.h
@@ -0,0 +1,20 @@
+#ifndef _UM_PARAM_H
+#define _UM_PARAM_H
+
+#define EXEC_PAGESIZE 4096
+
+#ifndef NOGROUP
+#define NOGROUP (-1)
+#endif
+
+#define MAXHOSTNAMELEN 64 /* max length of hostname */
+
+#ifdef __KERNEL__
+#define HZ CONFIG_HZ
+#define USER_HZ 100 /* .. some user interfaces are in "ticks" */
+#define CLOCKS_PER_SEC (USER_HZ) /* frequency at which times() counts */
+#else
+#define HZ 100
+#endif
+
+#endif
diff --git a/arch/um/include/asm/pci.h b/arch/um/include/asm/pci.h
new file mode 100644
index 0000000..5992319
--- /dev/null
+++ b/arch/um/include/asm/pci.h
@@ -0,0 +1,7 @@
+#ifndef __UM_PCI_H
+#define __UM_PCI_H
+
+#define PCI_DMA_BUS_IS_PHYS (1)
+#define pcibios_scan_all_fns(a, b) 0
+
+#endif
diff --git a/arch/um/include/asm/pda.h b/arch/um/include/asm/pda.h
new file mode 100644
index 0000000..0d8bf33
--- /dev/null
+++ b/arch/um/include/asm/pda.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PDA_X86_64_H
+#define __UM_PDA_X86_64_H
+
+/* XXX */
+struct foo {
+ unsigned int __softirq_pending;
+ unsigned int __nmi_count;
+};
+
+extern struct foo me;
+
+#define read_pda(me) (&me)
+
+#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
+ * 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/arch/um/include/asm/pgalloc.h b/arch/um/include/asm/pgalloc.h
new file mode 100644
index 0000000..9062a6e
--- /dev/null
+++ b/arch/um/include/asm/pgalloc.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
+ * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PGALLOC_H
+#define __UM_PGALLOC_H
+
+#include "linux/mm.h"
+#include "asm/fixmap.h"
+
+#define pmd_populate_kernel(mm, pmd, pte) \
+ set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) __pa(pte)))
+
+#define pmd_populate(mm, pmd, pte) \
+ set_pmd(pmd, __pmd(_PAGE_TABLE + \
+ ((unsigned long long)page_to_pfn(pte) << \
+ (unsigned long long) PAGE_SHIFT)))
+#define pmd_pgtable(pmd) pmd_page(pmd)
+
+/*
+ * Allocate and free page tables.
+ */
+extern pgd_t *pgd_alloc(struct mm_struct *);
+extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
+
+extern pte_t *pte_alloc_one_kernel(struct mm_struct *, unsigned long);
+extern pgtable_t pte_alloc_one(struct mm_struct *, unsigned long);
+
+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
+{
+ free_page((unsigned long) pte);
+}
+
+static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
+{
+ pgtable_page_dtor(pte);
+ __free_page(pte);
+}
+
+#define __pte_free_tlb(tlb,pte) \
+do { \
+ pgtable_page_dtor(pte); \
+ tlb_remove_page((tlb),(pte)); \
+} while (0)
+
+#ifdef CONFIG_3_LEVEL_PGTABLES
+
+static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
+{
+ free_page((unsigned long)pmd);
+}
+
+#define __pmd_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x))
+#endif
+
+#define check_pgt_cache() do { } while (0)
+
+#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
+ * 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/arch/um/include/asm/pgtable-2level.h b/arch/um/include/asm/pgtable-2level.h
new file mode 100644
index 0000000..f534b73
--- /dev/null
+++ b/arch/um/include/asm/pgtable-2level.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
+ * Derived from include/asm-i386/pgtable.h
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PGTABLE_2LEVEL_H
+#define __UM_PGTABLE_2LEVEL_H
+
+#include <asm-generic/pgtable-nopmd.h>
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+
+#define PGDIR_SHIFT 22
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: the i386 is two-level, so
+ * we don't really have any PMD directory physically.
+ */
+#define PTRS_PER_PTE 1024
+#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
+#define PTRS_PER_PGD 1024
+#define FIRST_USER_ADDRESS 0
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %p(%08lx).\n", __FILE__, __LINE__, &(e), \
+ pte_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %p(%08lx).\n", __FILE__, __LINE__, &(e), \
+ pgd_val(e))
+
+static inline int pgd_newpage(pgd_t pgd) { return 0; }
+static inline void pgd_mkuptodate(pgd_t pgd) { }
+
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
+
+#define pte_pfn(x) phys_to_pfn(pte_val(x))
+#define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
+#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
+
+/*
+ * Bits 0 through 4 are taken
+ */
+#define PTE_FILE_MAX_BITS 27
+
+#define pte_to_pgoff(pte) (pte_val(pte) >> 5)
+
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 5) + _PAGE_FILE })
+
+#endif
diff --git a/arch/um/include/asm/pgtable-3level.h b/arch/um/include/asm/pgtable-3level.h
new file mode 100644
index 0000000..0446f45
--- /dev/null
+++ b/arch/um/include/asm/pgtable-3level.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2003 PathScale Inc
+ * Derived from include/asm-i386/pgtable.h
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PGTABLE_3LEVEL_H
+#define __UM_PGTABLE_3LEVEL_H
+
+#include <asm-generic/pgtable-nopud.h>
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+
+#ifdef CONFIG_64BIT
+#define PGDIR_SHIFT 30
+#else
+#define PGDIR_SHIFT 31
+#endif
+#define PGDIR_SIZE (1UL << PGDIR_SHIFT)
+#define PGDIR_MASK (~(PGDIR_SIZE-1))
+
+/* PMD_SHIFT determines the size of the area a second-level page table can
+ * map
+ */
+
+#define PMD_SHIFT 21
+#define PMD_SIZE (1UL << PMD_SHIFT)
+#define PMD_MASK (~(PMD_SIZE-1))
+
+/*
+ * entries per page directory level
+ */
+
+#define PTRS_PER_PTE 512
+#ifdef CONFIG_64BIT
+#define PTRS_PER_PMD 512
+#define PTRS_PER_PGD 512
+#else
+#define PTRS_PER_PMD 1024
+#define PTRS_PER_PGD 1024
+#endif
+
+#define USER_PTRS_PER_PGD ((TASK_SIZE + (PGDIR_SIZE - 1)) / PGDIR_SIZE)
+#define FIRST_USER_ADDRESS 0
+
+#define pte_ERROR(e) \
+ printk("%s:%d: bad pte %p(%016lx).\n", __FILE__, __LINE__, &(e), \
+ pte_val(e))
+#define pmd_ERROR(e) \
+ printk("%s:%d: bad pmd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
+ pmd_val(e))
+#define pgd_ERROR(e) \
+ printk("%s:%d: bad pgd %p(%016lx).\n", __FILE__, __LINE__, &(e), \
+ pgd_val(e))
+
+#define pud_none(x) (!(pud_val(x) & ~_PAGE_NEWPAGE))
+#define pud_bad(x) ((pud_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+#define pud_present(x) (pud_val(x) & _PAGE_PRESENT)
+#define pud_populate(mm, pud, pmd) \
+ set_pud(pud, __pud(_PAGE_TABLE + __pa(pmd)))
+
+#ifdef CONFIG_64BIT
+#define set_pud(pudptr, pudval) set_64bit((phys_t *) (pudptr), pud_val(pudval))
+#else
+#define set_pud(pudptr, pudval) (*(pudptr) = (pudval))
+#endif
+
+static inline int pgd_newpage(pgd_t pgd)
+{
+ return(pgd_val(pgd) & _PAGE_NEWPAGE);
+}
+
+static inline void pgd_mkuptodate(pgd_t pgd) { pgd_val(pgd) &= ~_PAGE_NEWPAGE; }
+
+#ifdef CONFIG_64BIT
+#define set_pmd(pmdptr, pmdval) set_64bit((phys_t *) (pmdptr), pmd_val(pmdval))
+#else
+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = (pmdval))
+#endif
+
+struct mm_struct;
+extern pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address);
+
+static inline void pud_clear (pud_t *pud)
+{
+ set_pud(pud, __pud(_PAGE_NEWPAGE));
+}
+
+#define pud_page(pud) phys_to_page(pud_val(pud) & PAGE_MASK)
+#define pud_page_vaddr(pud) ((unsigned long) __va(pud_val(pud) & PAGE_MASK))
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(pud, address) ((pmd_t *) pud_page_vaddr(*(pud)) + \
+ pmd_index(address))
+
+static inline unsigned long pte_pfn(pte_t pte)
+{
+ return phys_to_pfn(pte_val(pte));
+}
+
+static inline pte_t pfn_pte(pfn_t page_nr, pgprot_t pgprot)
+{
+ pte_t pte;
+ phys_t phys = pfn_to_phys(page_nr);
+
+ pte_set_val(pte, phys, pgprot);
+ return pte;
+}
+
+static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot)
+{
+ return __pmd((page_nr << PAGE_SHIFT) | pgprot_val(pgprot));
+}
+
+/*
+ * Bits 0 through 3 are taken in the low part of the pte,
+ * put the 32 bits of offset into the high part.
+ */
+#define PTE_FILE_MAX_BITS 32
+
+#ifdef CONFIG_64BIT
+
+#define pte_to_pgoff(p) ((p).pte >> 32)
+
+#define pgoff_to_pte(off) ((pte_t) { ((off) << 32) | _PAGE_FILE })
+
+#else
+
+#define pte_to_pgoff(pte) ((pte).pte_high)
+
+#define pgoff_to_pte(off) ((pte_t) { _PAGE_FILE, (off) })
+
+#endif
+
+#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
+ * 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/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h
new file mode 100644
index 0000000..58da248
--- /dev/null
+++ b/arch/um/include/asm/pgtable.h
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Copyright 2003 PathScale, Inc.
+ * Derived from include/asm-i386/pgtable.h
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PGTABLE_H
+#define __UM_PGTABLE_H
+
+#include <asm/fixmap.h>
+
+#define _PAGE_PRESENT 0x001
+#define _PAGE_NEWPAGE 0x002
+#define _PAGE_NEWPROT 0x004
+#define _PAGE_RW 0x020
+#define _PAGE_USER 0x040
+#define _PAGE_ACCESSED 0x080
+#define _PAGE_DIRTY 0x100
+/* If _PAGE_PRESENT is clear, we use these: */
+#define _PAGE_FILE 0x008 /* nonlinear file mapping, saved PTE; unset:swap */
+#define _PAGE_PROTNONE 0x010 /* if the user mapped it with PROT_NONE;
+ pte_present gives true */
+
+#ifdef CONFIG_3_LEVEL_PGTABLES
+#include "asm/pgtable-3level.h"
+#else
+#include "asm/pgtable-2level.h"
+#endif
+
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/* zero page used for uninitialized stuff */
+extern unsigned long *empty_zero_page;
+
+#define pgtable_cache_init() do ; while (0)
+
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts. That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+
+extern unsigned long end_iomem;
+
+#define VMALLOC_OFFSET (__va_space)
+#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
+#ifdef CONFIG_HIGHMEM
+# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE)
+#else
+# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE)
+#endif
+
+#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
+#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+
+/*
+ * The i386 can't do page protection for execute, and considers that the same
+ * are read.
+ * Also, write permissions imply read permissions. This is the closest we can
+ * get..
+ */
+#define __P000 PAGE_NONE
+#define __P001 PAGE_READONLY
+#define __P010 PAGE_COPY
+#define __P011 PAGE_COPY
+#define __P100 PAGE_READONLY
+#define __P101 PAGE_READONLY
+#define __P110 PAGE_COPY
+#define __P111 PAGE_COPY
+
+#define __S000 PAGE_NONE
+#define __S001 PAGE_READONLY
+#define __S010 PAGE_SHARED
+#define __S011 PAGE_SHARED
+#define __S100 PAGE_READONLY
+#define __S101 PAGE_READONLY
+#define __S110 PAGE_SHARED
+#define __S111 PAGE_SHARED
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
+
+#define pte_clear(mm,addr,xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEWPAGE))
+
+#define pmd_none(x) (!((unsigned long)pmd_val(x) & ~_PAGE_NEWPAGE))
+#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
+
+#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
+#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
+
+#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE)
+#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
+
+#define pud_newpage(x) (pud_val(x) & _PAGE_NEWPAGE)
+#define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEWPAGE)
+
+#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
+
+#define pte_page(x) pfn_to_page(pte_pfn(x))
+
+#define pte_present(x) pte_get_bits(x, (_PAGE_PRESENT | _PAGE_PROTNONE))
+
+/*
+ * =================================
+ * Flags checking section.
+ * =================================
+ */
+
+static inline int pte_none(pte_t pte)
+{
+ return pte_is_zero(pte);
+}
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+static inline int pte_read(pte_t pte)
+{
+ return((pte_get_bits(pte, _PAGE_USER)) &&
+ !(pte_get_bits(pte, _PAGE_PROTNONE)));
+}
+
+static inline int pte_exec(pte_t pte){
+ return((pte_get_bits(pte, _PAGE_USER)) &&
+ !(pte_get_bits(pte, _PAGE_PROTNONE)));
+}
+
+static inline int pte_write(pte_t pte)
+{
+ return((pte_get_bits(pte, _PAGE_RW)) &&
+ !(pte_get_bits(pte, _PAGE_PROTNONE)));
+}
+
+/*
+ * The following only works if pte_present() is not true.
+ */
+static inline int pte_file(pte_t pte)
+{
+ return pte_get_bits(pte, _PAGE_FILE);
+}
+
+static inline int pte_dirty(pte_t pte)
+{
+ return pte_get_bits(pte, _PAGE_DIRTY);
+}
+
+static inline int pte_young(pte_t pte)
+{
+ return pte_get_bits(pte, _PAGE_ACCESSED);
+}
+
+static inline int pte_newpage(pte_t pte)
+{
+ return pte_get_bits(pte, _PAGE_NEWPAGE);
+}
+
+static inline int pte_newprot(pte_t pte)
+{
+ return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT)));
+}
+
+static inline int pte_special(pte_t pte)
+{
+ return 0;
+}
+
+/*
+ * =================================
+ * Flags setting section.
+ * =================================
+ */
+
+static inline pte_t pte_mknewprot(pte_t pte)
+{
+ pte_set_bits(pte, _PAGE_NEWPROT);
+ return(pte);
+}
+
+static inline pte_t pte_mkclean(pte_t pte)
+{
+ pte_clear_bits(pte, _PAGE_DIRTY);
+ return(pte);
+}
+
+static inline pte_t pte_mkold(pte_t pte)
+{
+ pte_clear_bits(pte, _PAGE_ACCESSED);
+ return(pte);
+}
+
+static inline pte_t pte_wrprotect(pte_t pte)
+{
+ pte_clear_bits(pte, _PAGE_RW);
+ return(pte_mknewprot(pte));
+}
+
+static inline pte_t pte_mkread(pte_t pte)
+{
+ pte_set_bits(pte, _PAGE_USER);
+ return(pte_mknewprot(pte));
+}
+
+static inline pte_t pte_mkdirty(pte_t pte)
+{
+ pte_set_bits(pte, _PAGE_DIRTY);
+ return(pte);
+}
+
+static inline pte_t pte_mkyoung(pte_t pte)
+{
+ pte_set_bits(pte, _PAGE_ACCESSED);
+ return(pte);
+}
+
+static inline pte_t pte_mkwrite(pte_t pte)
+{
+ pte_set_bits(pte, _PAGE_RW);
+ return(pte_mknewprot(pte));
+}
+
+static inline pte_t pte_mkuptodate(pte_t pte)
+{
+ pte_clear_bits(pte, _PAGE_NEWPAGE);
+ if(pte_present(pte))
+ pte_clear_bits(pte, _PAGE_NEWPROT);
+ return(pte);
+}
+
+static inline pte_t pte_mknewpage(pte_t pte)
+{
+ pte_set_bits(pte, _PAGE_NEWPAGE);
+ return(pte);
+}
+
+static inline pte_t pte_mkspecial(pte_t pte)
+{
+ return(pte);
+}
+
+static inline void set_pte(pte_t *pteptr, pte_t pteval)
+{
+ pte_copy(*pteptr, pteval);
+
+ /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
+ * fix_range knows to unmap it. _PAGE_NEWPROT is specific to
+ * mapped pages.
+ */
+
+ *pteptr = pte_mknewpage(*pteptr);
+ if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
+}
+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+
+#define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys))
+#define __virt_to_page(virt) phys_to_page(__pa(virt))
+#define page_to_phys(page) pfn_to_phys((pfn_t) page_to_pfn(page))
+#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
+
+#define mk_pte(page, pgprot) \
+ ({ pte_t pte; \
+ \
+ pte_set_val(pte, page_to_phys(page), (pgprot)); \
+ if (pte_present(pte)) \
+ pte_mknewprot(pte_mknewpage(pte)); \
+ pte;})
+
+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+{
+ pte_set_val(pte, (pte_val(pte) & _PAGE_CHG_MASK), newprot);
+ return pte;
+}
+
+/*
+ * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
+ *
+ * this macro returns the index of the entry in the pgd page which would
+ * control the given virtual address
+ */
+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
+
+/*
+ * pgd_offset() returns a (pgd_t *)
+ * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
+ */
+#define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
+
+/*
+ * a shortcut which implies the use of the kernel's pgd, instead
+ * of a process's
+ */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+
+/*
+ * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
+ *
+ * this macro returns the index of the entry in the pmd page which would
+ * control the given virtual address
+ */
+#define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+#define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
+
+#define pmd_page_vaddr(pmd) \
+ ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
+
+/*
+ * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
+ *
+ * this macro returns the index of the entry in the pte page which would
+ * control the given virtual address
+ */
+#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
+#define pte_offset_kernel(dir, address) \
+ ((pte_t *) pmd_page_vaddr(*(dir)) + pte_index(address))
+#define pte_offset_map(dir, address) \
+ ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
+#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
+#define pte_unmap(pte) do { } while (0)
+#define pte_unmap_nested(pte) do { } while (0)
+
+struct mm_struct;
+extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
+
+#define update_mmu_cache(vma,address,pte) do ; while (0)
+
+/* Encode and de-code a swap entry */
+#define __swp_type(x) (((x).val >> 4) & 0x3f)
+#define __swp_offset(x) ((x).val >> 11)
+
+#define __swp_entry(type, offset) \
+ ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
+#define __pte_to_swp_entry(pte) \
+ ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+#define kern_addr_valid(addr) (1)
+
+#include <asm-generic/pgtable.h>
+
+/* Clear a kernel PTE and flush it from the TLB */
+#define kpte_clear_flush(ptep, vaddr) \
+do { \
+ pte_clear(&init_mm, (vaddr), (ptep)); \
+ __flush_tlb_one((vaddr)); \
+} while (0)
+
+#endif
diff --git a/arch/um/include/asm/processor-generic.h b/arch/um/include/asm/processor-generic.h
new file mode 100644
index 0000000..bed6688
--- /dev/null
+++ b/arch/um/include/asm/processor-generic.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PROCESSOR_GENERIC_H
+#define __UM_PROCESSOR_GENERIC_H
+
+struct pt_regs;
+
+struct task_struct;
+
+#include "asm/ptrace.h"
+#include "registers.h"
+#include "sysdep/archsetjmp.h"
+
+struct mm_struct;
+
+struct thread_struct {
+ struct task_struct *saved_task;
+ /*
+ * This flag is set to 1 before calling do_fork (and analyzed in
+ * copy_thread) to mark that we are begin called from userspace (fork /
+ * vfork / clone), and reset to 0 after. It is left to 0 when called
+ * from kernelspace (i.e. kernel_thread() or fork_idle(),
+ * as of 2.6.11).
+ */
+ int forking;
+ struct pt_regs regs;
+ int singlestep_syscall;
+ void *fault_addr;
+ jmp_buf *fault_catcher;
+ struct task_struct *prev_sched;
+ unsigned long temp_stack;
+ jmp_buf *exec_buf;
+ struct arch_thread arch;
+ jmp_buf switch_buf;
+ int mm_count;
+ struct {
+ int op;
+ union {
+ struct {
+ int pid;
+ } fork, exec;
+ struct {
+ int (*proc)(void *);
+ void *arg;
+ } thread;
+ struct {
+ void (*proc)(void *);
+ void *arg;
+ } cb;
+ } u;
+ } request;
+};
+
+#define INIT_THREAD \
+{ \
+ .forking = 0, \
+ .regs = EMPTY_REGS, \
+ .fault_addr = NULL, \
+ .prev_sched = NULL, \
+ .temp_stack = 0, \
+ .exec_buf = NULL, \
+ .arch = INIT_ARCH_THREAD, \
+ .request = { 0 } \
+}
+
+extern struct task_struct *alloc_task_struct(void);
+
+static inline void release_thread(struct task_struct *task)
+{
+}
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+static inline void prepare_to_copy(struct task_struct *tsk)
+{
+}
+
+
+extern unsigned long thread_saved_pc(struct task_struct *t);
+
+static inline void mm_copy_segments(struct mm_struct *from_mm,
+ struct mm_struct *new_mm)
+{
+}
+
+#define init_stack (init_thread_union.stack)
+
+/*
+ * User space process size: 3GB (default).
+ */
+extern unsigned long task_size;
+
+#define TASK_SIZE (task_size)
+
+#undef STACK_TOP
+#undef STACK_TOP_MAX
+
+extern unsigned long stacksizelim;
+
+#define STACK_ROOM (stacksizelim)
+#define STACK_TOP (TASK_SIZE - 2 * PAGE_SIZE)
+#define STACK_TOP_MAX STACK_TOP
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE (0x40000000)
+
+extern void start_thread(struct pt_regs *regs, unsigned long entry,
+ unsigned long stack);
+
+struct cpuinfo_um {
+ unsigned long loops_per_jiffy;
+ int ipi_pipe[2];
+};
+
+extern struct cpuinfo_um boot_cpu_data;
+
+#define my_cpu_data cpu_data[smp_processor_id()]
+
+#ifdef CONFIG_SMP
+extern struct cpuinfo_um cpu_data[];
+#define current_cpu_data cpu_data[smp_processor_id()]
+#else
+#define cpu_data (&boot_cpu_data)
+#define current_cpu_data boot_cpu_data
+#endif
+
+
+#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
+extern unsigned long get_wchan(struct task_struct *p);
+
+#endif
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
new file mode 100644
index 0000000..6c88990
--- /dev/null
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_PTRACE_GENERIC_H
+#define __UM_PTRACE_GENERIC_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/ptrace-abi.h>
+#include <asm/user.h>
+#include "sysdep/ptrace.h"
+
+struct pt_regs {
+ struct uml_pt_regs regs;
+};
+
+#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
+
+#define PT_REGS_IP(r) UPT_IP(&(r)->regs)
+#define PT_REGS_SP(r) UPT_SP(&(r)->regs)
+
+#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg)
+#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val)
+
+#define PT_REGS_SET_SYSCALL_RETURN(r, res) \
+ UPT_SET_SYSCALL_RETURN(&(r)->regs, res)
+#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs)
+
+#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs)
+
+#define PT_REGS_SC(r) UPT_SC(&(r)->regs)
+
+#define instruction_pointer(regs) PT_REGS_IP(regs)
+
+struct task_struct;
+
+extern long subarch_ptrace(struct task_struct *child, long request, long addr,
+ long data);
+extern unsigned long getreg(struct task_struct *child, int regno);
+extern int putreg(struct task_struct *child, int regno, unsigned long value);
+extern int get_fpregs(struct user_i387_struct __user *buf,
+ struct task_struct *child);
+extern int set_fpregs(struct user_i387_struct __user *buf,
+ struct task_struct *child);
+
+extern void show_regs(struct pt_regs *regs);
+
+extern int arch_copy_tls(struct task_struct *new);
+extern void clear_flushed_tls(struct task_struct *task);
+
+#endif
+
+#endif
diff --git a/arch/um/include/asm/required-features.h b/arch/um/include/asm/required-features.h
new file mode 100644
index 0000000..dfb967b
--- /dev/null
+++ b/arch/um/include/asm/required-features.h
@@ -0,0 +1,9 @@
+#ifndef __UM_REQUIRED_FEATURES_H
+#define __UM_REQUIRED_FEATURES_H
+
+/*
+ * Nothing to see, just need something for the i386 and x86_64 asm
+ * headers to include.
+ */
+
+#endif
diff --git a/arch/um/include/asm/sections.h b/arch/um/include/asm/sections.h
new file mode 100644
index 0000000..6b0231e
--- /dev/null
+++ b/arch/um/include/asm/sections.h
@@ -0,0 +1,7 @@
+#ifndef _UM_SECTIONS_H
+#define _UM_SECTIONS_H
+
+/* nothing to see, move along */
+#include <asm-generic/sections.h>
+
+#endif
diff --git a/arch/um/include/asm/segment.h b/arch/um/include/asm/segment.h
new file mode 100644
index 0000000..45183fc
--- /dev/null
+++ b/arch/um/include/asm/segment.h
@@ -0,0 +1,10 @@
+#ifndef __UM_SEGMENT_H
+#define __UM_SEGMENT_H
+
+extern int host_gdt_entry_tls_min;
+
+#define GDT_ENTRY_TLS_ENTRIES 3
+#define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min
+#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
+
+#endif
diff --git a/arch/um/include/asm/setup.h b/arch/um/include/asm/setup.h
new file mode 100644
index 0000000..99f0863
--- /dev/null
+++ b/arch/um/include/asm/setup.h
@@ -0,0 +1,10 @@
+#ifndef SETUP_H_INCLUDED
+#define SETUP_H_INCLUDED
+
+/* POSIX mandated with _POSIX_ARG_MAX that we can rely on 4096 chars in the
+ * command line, so this choice is ok.
+ */
+
+#define COMMAND_LINE_SIZE 4096
+
+#endif /* SETUP_H_INCLUDED */
diff --git a/arch/um/include/asm/smp.h b/arch/um/include/asm/smp.h
new file mode 100644
index 0000000..f27a963
--- /dev/null
+++ b/arch/um/include/asm/smp.h
@@ -0,0 +1,33 @@
+#ifndef __UM_SMP_H
+#define __UM_SMP_H
+
+#ifdef CONFIG_SMP
+
+#include "linux/bitops.h"
+#include "asm/current.h"
+#include "linux/cpumask.h"
+
+#define raw_smp_processor_id() (current_thread->cpu)
+
+#define cpu_logical_map(n) (n)
+#define cpu_number_map(n) (n)
+#define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */
+extern int hard_smp_processor_id(void);
+#define NO_PROC_ID -1
+
+extern int ncpus;
+
+
+static inline void smp_cpus_done(unsigned int maxcpus)
+{
+}
+
+extern struct task_struct *idle_threads[NR_CPUS];
+
+#else
+
+#define hard_smp_processor_id() 0
+
+#endif
+
+#endif
diff --git a/arch/um/include/asm/suspend.h b/arch/um/include/asm/suspend.h
new file mode 100644
index 0000000..f4e8e00
--- /dev/null
+++ b/arch/um/include/asm/suspend.h
@@ -0,0 +1,4 @@
+#ifndef __UM_SUSPEND_H
+#define __UM_SUSPEND_H
+
+#endif
diff --git a/arch/um/include/asm/system.h b/arch/um/include/asm/system.h
new file mode 100644
index 0000000..753346e
--- /dev/null
+++ b/arch/um/include/asm/system.h
@@ -0,0 +1,35 @@
+#ifndef __UM_SYSTEM_GENERIC_H
+#define __UM_SYSTEM_GENERIC_H
+
+#include "sysdep/system.h"
+
+extern void *switch_to(void *prev, void *next, void *last);
+
+extern int get_signals(void);
+extern int set_signals(int enable);
+extern int get_signals(void);
+extern void block_signals(void);
+extern void unblock_signals(void);
+
+#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
+ (flags) = get_signals(); } while(0)
+#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
+ set_signals(flags); } while(0)
+
+#define local_irq_save(flags) do { local_save_flags(flags); \
+ local_irq_disable(); } while(0)
+
+#define local_irq_enable() unblock_signals()
+#define local_irq_disable() block_signals()
+
+#define irqs_disabled() \
+({ \
+ unsigned long flags; \
+ local_save_flags(flags); \
+ (flags == 0); \
+})
+
+extern void *_switch_to(void *prev, void *next, void *last);
+#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
+
+#endif
diff --git a/arch/um/include/asm/thread_info.h b/arch/um/include/asm/thread_info.h
new file mode 100644
index 0000000..62274ab
--- /dev/null
+++ b/arch/um/include/asm/thread_info.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_THREAD_INFO_H
+#define __UM_THREAD_INFO_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/types.h>
+#include <asm/page.h>
+#include <asm/uaccess.h>
+
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ __u32 cpu; /* current CPU */
+ int preempt_count; /* 0 => preemptable,
+ <0 => BUG */
+ mm_segment_t addr_limit; /* thread address space:
+ 0-0xBFFFFFFF for user
+ 0-0xFFFFFFFF for kernel */
+ struct restart_block restart_block;
+ struct thread_info *real_thread; /* Points to non-IRQ stack */
+};
+
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = 1, \
+ .addr_limit = KERNEL_DS, \
+ .restart_block = { \
+ .fn = do_no_restart_syscall, \
+ }, \
+ .real_thread = NULL, \
+}
+
+#define init_thread_info (init_thread_union.thread_info)
+#define init_stack (init_thread_union.stack)
+
+#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
+/* how to get the thread information struct from C */
+static inline struct thread_info *current_thread_info(void)
+{
+ struct thread_info *ti;
+ unsigned long mask = THREAD_SIZE - 1;
+ ti = (struct thread_info *) (((unsigned long) &ti) & ~mask);
+ return ti;
+}
+
+#define THREAD_SIZE_ORDER CONFIG_KERNEL_STACK_ORDER
+
+#endif
+
+#define PREEMPT_ACTIVE 0x10000000
+
+#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_SIGPENDING 1 /* signal pending */
+#define TIF_NEED_RESCHED 2 /* rescheduling necessary */
+#define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
+ * TIF_NEED_RESCHED
+ */
+#define TIF_RESTART_BLOCK 4
+#define TIF_MEMDIE 5
+#define TIF_SYSCALL_AUDIT 6
+#define TIF_RESTORE_SIGMASK 7
+#define TIF_FREEZE 16 /* is freezing for suspend */
+
+#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
+#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
+#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
+#define _TIF_MEMDIE (1 << TIF_MEMDIE)
+#define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT)
+#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK)
+#define _TIF_FREEZE (1 << TIF_FREEZE)
+
+#endif
diff --git a/arch/um/include/asm/timex.h b/arch/um/include/asm/timex.h
new file mode 100644
index 0000000..0f4ada0
--- /dev/null
+++ b/arch/um/include/asm/timex.h
@@ -0,0 +1,13 @@
+#ifndef __UM_TIMEX_H
+#define __UM_TIMEX_H
+
+typedef unsigned long cycles_t;
+
+static inline cycles_t get_cycles (void)
+{
+ return 0;
+}
+
+#define CLOCK_TICK_RATE (HZ)
+
+#endif
diff --git a/arch/um/include/asm/tlb.h b/arch/um/include/asm/tlb.h
new file mode 100644
index 0000000..5240fa1
--- /dev/null
+++ b/arch/um/include/asm/tlb.h
@@ -0,0 +1,127 @@
+#ifndef __UM_TLB_H
+#define __UM_TLB_H
+
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <asm/percpu.h>
+#include <asm/pgalloc.h>
+#include <asm/tlbflush.h>
+
+#define tlb_start_vma(tlb, vma) do { } while (0)
+#define tlb_end_vma(tlb, vma) do { } while (0)
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+/* struct mmu_gather is an opaque type used by the mm code for passing around
+ * any data needed by arch specific code for tlb_remove_page.
+ */
+struct mmu_gather {
+ struct mm_struct *mm;
+ unsigned int need_flush; /* Really unmapped some ptes? */
+ unsigned long start;
+ unsigned long end;
+ unsigned int fullmm; /* non-zero means full mm flush */
+};
+
+/* Users of the generic TLB shootdown code must declare this storage space. */
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
+
+static inline void __tlb_remove_tlb_entry(struct mmu_gather *tlb, pte_t *ptep,
+ unsigned long address)
+{
+ if (tlb->start > address)
+ tlb->start = address;
+ if (tlb->end < address + PAGE_SIZE)
+ tlb->end = address + PAGE_SIZE;
+}
+
+static inline void init_tlb_gather(struct mmu_gather *tlb)
+{
+ tlb->need_flush = 0;
+
+ tlb->start = TASK_SIZE;
+ tlb->end = 0;
+
+ if (tlb->fullmm) {
+ tlb->start = 0;
+ tlb->end = TASK_SIZE;
+ }
+}
+
+/* tlb_gather_mmu
+ * Return a pointer to an initialized struct mmu_gather.
+ */
+static inline struct mmu_gather *
+tlb_gather_mmu(struct mm_struct *mm, unsigned int full_mm_flush)
+{
+ struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
+
+ tlb->mm = mm;
+ tlb->fullmm = full_mm_flush;
+
+ init_tlb_gather(tlb);
+
+ return tlb;
+}
+
+extern void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
+ unsigned long end);
+
+static inline void
+tlb_flush_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+ if (!tlb->need_flush)
+ return;
+
+ flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end);
+ init_tlb_gather(tlb);
+}
+
+/* tlb_finish_mmu
+ * Called at the end of the shootdown operation to free up any resources
+ * that were required.
+ */
+static inline void
+tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
+{
+ tlb_flush_mmu(tlb, start, end);
+
+ /* keep the page table cache within bounds */
+ check_pgt_cache();
+
+ put_cpu_var(mmu_gathers);
+}
+
+/* tlb_remove_page
+ * Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)),
+ * while handling the additional races in SMP caused by other CPUs
+ * caching valid mappings in their TLBs.
+ */
+static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+ tlb->need_flush = 1;
+ free_page_and_swap_cache(page);
+ return;
+}
+
+/**
+ * tlb_remove_tlb_entry - remember a pte unmapping for later tlb invalidation.
+ *
+ * Record the fact that pte's were really umapped in ->need_flush, so we can
+ * later optimise away the tlb invalidate. This helps when userspace is
+ * unmapping already-unmapped pages, which happens quite a lot.
+ */
+#define tlb_remove_tlb_entry(tlb, ptep, address) \
+ do { \
+ tlb->need_flush = 1; \
+ __tlb_remove_tlb_entry(tlb, ptep, address); \
+ } while (0)
+
+#define pte_free_tlb(tlb, ptep) __pte_free_tlb(tlb, ptep)
+
+#define pud_free_tlb(tlb, pudp) __pud_free_tlb(tlb, pudp)
+
+#define pmd_free_tlb(tlb, pmdp) __pmd_free_tlb(tlb, pmdp)
+
+#define tlb_migrate_finish(mm) do {} while (0)
+
+#endif
diff --git a/arch/um/include/asm/tlbflush.h b/arch/um/include/asm/tlbflush.h
new file mode 100644
index 0000000..614f2c0
--- /dev/null
+++ b/arch/um/include/asm/tlbflush.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_TLBFLUSH_H
+#define __UM_TLBFLUSH_H
+
+#include <linux/mm.h>
+
+/*
+ * TLB flushing:
+ *
+ * - flush_tlb() flushes the current mm struct TLBs
+ * - flush_tlb_all() flushes all processes TLBs
+ * - flush_tlb_mm(mm) flushes the specified mm context TLB's
+ * - flush_tlb_page(vma, vmaddr) flushes one page
+ * - flush_tlb_kernel_vm() flushes the kernel vm area
+ * - flush_tlb_range(vma, start, end) flushes a range of pages
+ */
+
+extern void flush_tlb_all(void);
+extern void flush_tlb_mm(struct mm_struct *mm);
+extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
+ unsigned long end);
+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long address);
+extern void flush_tlb_kernel_vm(void);
+extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
+extern void __flush_tlb_one(unsigned long addr);
+
+#endif
diff --git a/arch/um/include/asm/topology.h b/arch/um/include/asm/topology.h
new file mode 100644
index 0000000..0905e4f
--- /dev/null
+++ b/arch/um/include/asm/topology.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_UM_TOPOLOGY_H
+#define _ASM_UM_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif
diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h
new file mode 100644
index 0000000..b9a895d
--- /dev/null
+++ b/arch/um/include/asm/uaccess.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_UACCESS_H
+#define __UM_UACCESS_H
+
+#include <asm/errno.h>
+#include <asm/processor.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"
+
+#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)
+
+#include "um_uaccess.h"
+
+#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)
+
+#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)
+
+struct exception_table_entry
+{
+ unsigned long insn;
+ unsigned long fixup;
+};
+
+#endif
diff --git a/arch/um/include/asm/xor.h b/arch/um/include/asm/xor.h
new file mode 100644
index 0000000..a19db3e
--- /dev/null
+++ b/arch/um/include/asm/xor.h
@@ -0,0 +1,6 @@
+#ifndef __UM_XOR_H
+#define __UM_XOR_H
+
+#include "asm-generic/xor.h"
+
+#endif
diff --git a/arch/um/include/shared/aio.h b/arch/um/include/shared/aio.h
new file mode 100644
index 0000000..423bae9
--- /dev/null
+++ b/arch/um/include/shared/aio.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2004 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef AIO_H__
+#define AIO_H__
+
+enum aio_type { AIO_READ, AIO_WRITE, AIO_MMAP };
+
+struct aio_thread_reply {
+ void *data;
+ int err;
+};
+
+struct aio_context {
+ int reply_fd;
+ struct aio_context *next;
+};
+
+#define INIT_AIO_CONTEXT { .reply_fd = -1, \
+ .next = NULL }
+
+extern int submit_aio(enum aio_type type, int fd, char *buf, int len,
+ unsigned long long offset, int reply_fd,
+ struct aio_context *aio);
+
+#endif
diff --git a/arch/um/include/shared/arch.h b/arch/um/include/shared/arch.h
new file mode 100644
index 0000000..2de92a0
--- /dev/null
+++ b/arch/um/include/shared/arch.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __ARCH_H__
+#define __ARCH_H__
+
+#include "sysdep/ptrace.h"
+
+extern void arch_check_bugs(void);
+extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs);
+extern void arch_examine_signal(int sig, struct uml_pt_regs *regs);
+
+#endif
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
new file mode 100644
index 0000000..a92b678
--- /dev/null
+++ b/arch/um/include/shared/as-layout.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __START_H__
+#define __START_H__
+
+#include "kern_constants.h"
+
+/*
+ * Stolen from linux/const.h, which can't be directly included since
+ * this is used in userspace code, which has no access to the kernel
+ * headers. Changed to be suitable for adding casts to the start,
+ * rather than "UL" to the end.
+ */
+
+/* Some constant macros are used in both assembler and
+ * C code. Therefore we cannot annotate them always with
+ * 'UL' and other type specifiers unilaterally. We
+ * use the following macros to deal with this.
+ */
+
+#ifdef __ASSEMBLY__
+#define _UML_AC(X, Y) (Y)
+#else
+#define __UML_AC(X, Y) (X(Y))
+#define _UML_AC(X, Y) __UML_AC(X, Y)
+#endif
+
+#define STUB_START _UML_AC(, 0x100000)
+#define STUB_CODE _UML_AC((unsigned long), STUB_START)
+#define STUB_DATA _UML_AC((unsigned long), STUB_CODE + UM_KERN_PAGE_SIZE)
+#define STUB_END _UML_AC((unsigned long), STUB_DATA + UM_KERN_PAGE_SIZE)
+
+#ifndef __ASSEMBLY__
+
+#include "sysdep/ptrace.h"
+
+struct cpu_task {
+ int pid;
+ void *task;
+};
+
+extern struct cpu_task cpu_tasks[];
+
+extern unsigned long low_physmem;
+extern unsigned long high_physmem;
+extern unsigned long uml_physmem;
+extern unsigned long uml_reserved;
+extern unsigned long end_vm;
+extern unsigned long start_vm;
+extern unsigned long long highmem;
+
+extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end;
+extern unsigned long _unprotected_end;
+extern unsigned long brk_start;
+
+extern unsigned long host_task_size;
+
+extern int linux_main(int argc, char **argv);
+
+extern void (*sig_info[])(int, struct uml_pt_regs *);
+
+#endif
+
+#endif
diff --git a/arch/um/include/shared/chan_kern.h b/arch/um/include/shared/chan_kern.h
new file mode 100644
index 0000000..1e65145
--- /dev/null
+++ b/arch/um/include/shared/chan_kern.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __CHAN_KERN_H__
+#define __CHAN_KERN_H__
+
+#include "linux/tty.h"
+#include "linux/list.h"
+#include "linux/console.h"
+#include "chan_user.h"
+#include "line.h"
+
+struct chan {
+ struct list_head list;
+ struct list_head free_list;
+ struct line *line;
+ char *dev;
+ unsigned int primary:1;
+ unsigned int input:1;
+ unsigned int output:1;
+ unsigned int opened:1;
+ unsigned int enabled:1;
+ int fd;
+ const struct chan_ops *ops;
+ void *data;
+};
+
+extern void chan_interrupt(struct list_head *chans, struct delayed_work *task,
+ struct tty_struct *tty, int irq);
+extern int parse_chan_pair(char *str, struct line *line, int device,
+ const struct chan_opts *opts, char **error_out);
+extern int write_chan(struct list_head *chans, const char *buf, int len,
+ int write_irq);
+extern int console_write_chan(struct list_head *chans, const char *buf,
+ int len);
+extern int console_open_chan(struct line *line, struct console *co);
+extern void deactivate_chan(struct list_head *chans, int irq);
+extern void reactivate_chan(struct list_head *chans, int irq);
+extern void chan_enable_winch(struct list_head *chans, struct tty_struct *tty);
+extern int enable_chan(struct line *line);
+extern void close_chan(struct list_head *chans, int delay_free_irq);
+extern int chan_window_size(struct list_head *chans,
+ unsigned short *rows_out,
+ unsigned short *cols_out);
+extern int chan_config_string(struct list_head *chans, char *str, int size,
+ char **error_out);
+
+#endif
diff --git a/arch/um/include/shared/chan_user.h b/arch/um/include/shared/chan_user.h
new file mode 100644
index 0000000..9b9ced8
--- /dev/null
+++ b/arch/um/include/shared/chan_user.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __CHAN_USER_H__
+#define __CHAN_USER_H__
+
+#include "init.h"
+
+struct chan_opts {
+ void (*const announce)(char *dev_name, int dev);
+ char *xterm_title;
+ const int raw;
+};
+
+enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE };
+
+struct chan_ops {
+ char *type;
+ void *(*init)(char *, int, const struct chan_opts *);
+ int (*open)(int, int, int, void *, char **);
+ void (*close)(int, void *);
+ int (*read)(int, char *, void *);
+ int (*write)(int, const char *, int, void *);
+ int (*console_write)(int, const char *, int);
+ int (*window_size)(int, void *, unsigned short *, unsigned short *);
+ void (*free)(void *);
+ int winch;
+};
+
+extern const struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops,
+ tty_ops, xterm_ops;
+
+extern void generic_close(int fd, void *unused);
+extern int generic_read(int fd, char *c_out, void *unused);
+extern int generic_write(int fd, const char *buf, int n, void *unused);
+extern int generic_console_write(int fd, const char *buf, int n);
+extern int generic_window_size(int fd, void *unused, unsigned short *rows_out,
+ unsigned short *cols_out);
+extern void generic_free(void *data);
+
+struct tty_struct;
+extern void register_winch(int fd, struct tty_struct *tty);
+extern void register_winch_irq(int fd, int tty_fd, int pid,
+ struct tty_struct *tty, unsigned long stack);
+
+#define __channel_help(fn, prefix) \
+__uml_help(fn, prefix "[0-9]*=<channel description>\n" \
+" Attach a console or serial line to a host channel. See\n" \
+" http://user-mode-linux.sourceforge.net/old/input.html for a complete\n" \
+" description of this switch.\n\n" \
+);
+
+#endif
diff --git a/arch/um/include/shared/common-offsets.h b/arch/um/include/shared/common-offsets.h
new file mode 100644
index 0000000..72009c7
--- /dev/null
+++ b/arch/um/include/shared/common-offsets.h
@@ -0,0 +1,54 @@
+/* for use by sys-$SUBARCH/kernel-offsets.c */
+
+DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
+
+OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
+OFFSET(HOST_TASK_PID, task_struct, pid);
+
+DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
+DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
+DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
+DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
+
+DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
+DEFINE_STR(UM_KERN_ALERT, KERN_ALERT);
+DEFINE_STR(UM_KERN_CRIT, KERN_CRIT);
+DEFINE_STR(UM_KERN_ERR, KERN_ERR);
+DEFINE_STR(UM_KERN_WARNING, KERN_WARNING);
+DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE);
+DEFINE_STR(UM_KERN_INFO, KERN_INFO);
+DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG);
+DEFINE_STR(UM_KERN_CONT, KERN_CONT);
+
+DEFINE(UM_ELF_CLASS, ELF_CLASS);
+DEFINE(UM_ELFCLASS32, ELFCLASS32);
+DEFINE(UM_ELFCLASS64, ELFCLASS64);
+
+DEFINE(UM_NR_CPUS, NR_CPUS);
+
+DEFINE(UM_GFP_KERNEL, GFP_KERNEL);
+DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC);
+
+/* For crypto assembler code. */
+DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
+
+DEFINE(UM_THREAD_SIZE, THREAD_SIZE);
+
+DEFINE(UM_HZ, HZ);
+
+DEFINE(UM_USEC_PER_SEC, USEC_PER_SEC);
+DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
+DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC);
+
+#ifdef CONFIG_PRINTK
+DEFINE(UML_CONFIG_PRINTK, CONFIG_PRINTK);
+#endif
+#ifdef CONFIG_NO_HZ
+DEFINE(UML_CONFIG_NO_HZ, CONFIG_NO_HZ);
+#endif
+#ifdef CONFIG_UML_X86
+DEFINE(UML_CONFIG_UML_X86, CONFIG_UML_X86);
+#endif
+#ifdef CONFIG_64BIT
+DEFINE(UML_CONFIG_64BIT, CONFIG_64BIT);
+#endif
diff --git a/arch/um/include/shared/elf_user.h b/arch/um/include/shared/elf_user.h
new file mode 100644
index 0000000..53516b6
--- /dev/null
+++ b/arch/um/include/shared/elf_user.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ * Licensed under the GPL
+ */
+
+#ifndef __ELF_USER_H__
+#define __ELF_USER_H__
+
+/* For compilation on a host that doesn't support AT_SYSINFO (Linux 2.4) */
+
+#ifndef AT_SYSINFO
+#define AT_SYSINFO 32
+#endif
+#ifndef AT_SYSINFO_EHDR
+#define AT_SYSINFO_EHDR 33
+#endif
+
+#endif
diff --git a/arch/um/include/shared/frame_kern.h b/arch/um/include/shared/frame_kern.h
new file mode 100644
index 0000000..ce9514f
--- /dev/null
+++ b/arch/um/include/shared/frame_kern.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __FRAME_KERN_H_
+#define __FRAME_KERN_H_
+
+#define _S(nr) (1<<((nr)-1))
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+
+extern int setup_signal_stack_sc(unsigned long stack_top, int sig,
+ struct k_sigaction *ka,
+ struct pt_regs *regs,
+ sigset_t *mask);
+extern int setup_signal_stack_si(unsigned long stack_top, int sig,
+ struct k_sigaction *ka,
+ struct pt_regs *regs, siginfo_t *info,
+ sigset_t *mask);
+
+#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
+ * 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/arch/um/include/shared/init.h b/arch/um/include/shared/init.h
new file mode 100644
index 0000000..37dd097
--- /dev/null
+++ b/arch/um/include/shared/init.h
@@ -0,0 +1,151 @@
+#ifndef _LINUX_UML_INIT_H
+#define _LINUX_UML_INIT_H
+
+/* These macros are used to mark some functions or
+ * initialized data (doesn't apply to uninitialized data)
+ * as `initialization' functions. The kernel can take this
+ * as hint that the function is used only during the initialization
+ * phase and free up used memory resources after
+ *
+ * Usage:
+ * For functions:
+ *
+ * You should add __init immediately before the function name, like:
+ *
+ * static void __init initme(int x, int y)
+ * {
+ * extern int z; z = x * y;
+ * }
+ *
+ * If the function has a prototype somewhere, you can also add
+ * __init between closing brace of the prototype and semicolon:
+ *
+ * extern int initialize_foobar_device(int, int, int) __init;
+ *
+ * For initialized data:
+ * You should insert __initdata between the variable name and equal
+ * sign followed by value, e.g.:
+ *
+ * static int init_variable __initdata = 0;
+ * static char linux_logo[] __initdata = { 0x32, 0x36, ... };
+ *
+ * Don't forget to initialize data not at file scope, i.e. within a function,
+ * as gcc otherwise puts the data into the bss section and not into the init
+ * section.
+ *
+ * Also note, that this data cannot be "const".
+ */
+
+#ifndef _LINUX_INIT_H
+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)
+#define __initdata __section(.init.data)
+#define __exitdata __section(.exit.data)
+#define __exit_call __used __section(.exitcall.exit)
+
+#ifdef MODULE
+#define __exit __section(.exit.text)
+#else
+#define __exit __used __section(.exit.text)
+#endif
+
+#endif
+
+#ifndef MODULE
+struct uml_param {
+ const char *str;
+ int (*setup_func)(char *, int *);
+};
+
+extern initcall_t __uml_initcall_start, __uml_initcall_end;
+extern initcall_t __uml_postsetup_start, __uml_postsetup_end;
+extern const char *__uml_help_start, *__uml_help_end;
+#endif
+
+#define __uml_initcall(fn) \
+ static initcall_t __uml_initcall_##fn __uml_init_call = fn
+
+#define __uml_exitcall(fn) \
+ static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn
+
+extern struct uml_param __uml_setup_start, __uml_setup_end;
+
+#define __uml_postsetup(fn) \
+ static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn
+
+#define __non_empty_string(dummyname,string) \
+ struct __uml_non_empty_string_struct_##dummyname \
+ { \
+ char _string[sizeof(string)-2]; \
+ }
+
+#ifndef MODULE
+#define __uml_setup(str, fn, help...) \
+ __non_empty_string(fn ##_setup, str); \
+ __uml_help(fn, help); \
+ static char __uml_setup_str_##fn[] __initdata = str; \
+ static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn }
+#else
+#define __uml_setup(str, fn, help...) \
+
+#endif
+
+#define __uml_help(fn, help...) \
+ __non_empty_string(fn ##__help, help); \
+ static char __uml_help_str_##fn[] __initdata = help; \
+ static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn
+
+/*
+ * Mark functions and data as being only used at initialization
+ * or exit time.
+ */
+#define __uml_init_setup __used __section(.uml.setup.init)
+#define __uml_setup_help __used __section(.uml.help.init)
+#define __uml_init_call __used __section(.uml.initcall.init)
+#define __uml_postsetup_call __used __section(.uml.postsetup.init)
+#define __uml_exit_call __used __section(.uml.exitcall.exit)
+
+#ifndef __KERNEL__
+
+#define __define_initcall(level,fn) \
+ static initcall_t __initcall_##fn __used \
+ __attribute__((__section__(".initcall" level ".init"))) = fn
+
+/* Userspace initcalls shouldn't depend on anything in the kernel, so we'll
+ * make them run first.
+ */
+#define __initcall(fn) __define_initcall("1", fn)
+
+#define __exitcall(fn) static exitcall_t __exitcall_##fn __exit_call = fn
+
+#define __init_call __used __section(.initcall.init)
+
+#endif
+
+#endif /* _LINUX_UML_INIT_H */
diff --git a/arch/um/include/shared/initrd.h b/arch/um/include/shared/initrd.h
new file mode 100644
index 0000000..439b9a8
--- /dev/null
+++ b/arch/um/include/shared/initrd.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __INITRD_USER_H__
+#define __INITRD_USER_H__
+
+extern int load_initrd(char *filename, void *buf, int size);
+
+#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
+ * 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/arch/um/include/shared/irq_kern.h b/arch/um/include/shared/irq_kern.h
new file mode 100644
index 0000000..fba3895
--- /dev/null
+++ b/arch/um/include/shared/irq_kern.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __IRQ_KERN_H__
+#define __IRQ_KERN_H__
+
+#include "linux/interrupt.h"
+#include "asm/ptrace.h"
+
+extern int um_request_irq(unsigned int irq, int fd, int type,
+ irq_handler_t handler,
+ unsigned long irqflags, const char * devname,
+ void *dev_id);
+
+#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
+ * 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/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h
new file mode 100644
index 0000000..c6c784d
--- /dev/null
+++ b/arch/um/include/shared/irq_user.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __IRQ_USER_H__
+#define __IRQ_USER_H__
+
+#include "sysdep/ptrace.h"
+
+struct irq_fd {
+ struct irq_fd *next;
+ void *id;
+ int fd;
+ int type;
+ int irq;
+ int events;
+ int current_events;
+};
+
+enum { IRQ_READ, IRQ_WRITE };
+
+extern void sigio_handler(int sig, struct uml_pt_regs *regs);
+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 int activate_ipi(int fd, int pid);
+
+#endif
diff --git a/arch/um/include/shared/kern.h b/arch/um/include/shared/kern.h
new file mode 100644
index 0000000..4ce3fc6
--- /dev/null
+++ b/arch/um/include/shared/kern.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __KERN_H__
+#define __KERN_H__
+
+/* These are all user-mode things which are convenient to call directly
+ * from kernel code and for which writing a wrapper is too much of a pain.
+ * The regular include files can't be included because this file is included
+ * only into kernel code, and user-space includes conflict with kernel
+ * includes.
+ */
+
+extern int errno;
+
+extern int clone(int (*proc)(void *), void *sp, int flags, void *data);
+extern int sleep(int);
+extern int printf(const char *fmt, ...);
+extern char *strerror(int errnum);
+extern char *ptsname(int __fd);
+extern int munmap(void *, int);
+extern void *sbrk(int increment);
+extern void *malloc(int size);
+extern void perror(char *err);
+extern int kill(int pid, int sig);
+extern int getuid(void);
+extern int getgid(void);
+extern int pause(void);
+extern int write(int, const void *, int);
+extern void exit(int);
+extern int close(int);
+extern int read(unsigned int, char *, int);
+extern int pipe(int *);
+extern int sched_yield(void);
+extern int ptrace(int op, int pid, long addr, long data);
+
+#endif
+
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h
new file mode 100644
index 0000000..3c34122
--- /dev/null
+++ b/arch/um/include/shared/kern_util.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __KERN_UTIL_H__
+#define __KERN_UTIL_H__
+
+#include "sysdep/ptrace.h"
+#include "sysdep/faultinfo.h"
+
+extern int uml_exitcode;
+
+extern int ncpus;
+extern int kmalloc_ok;
+
+#define UML_ROUND_UP(addr) \
+ ((((unsigned long) addr) + PAGE_SIZE - 1) & PAGE_MASK)
+
+extern unsigned long alloc_stack(int order, int atomic);
+extern void free_stack(unsigned long stack, int order);
+
+extern int do_signal(void);
+extern void copy_sc(struct uml_pt_regs *regs, void *from);
+extern void interrupt_end(void);
+extern void relay_signal(int sig, struct uml_pt_regs *regs);
+
+extern unsigned long segv(struct faultinfo fi, unsigned long ip,
+ int is_user, struct uml_pt_regs *regs);
+extern int handle_page_fault(unsigned long address, unsigned long ip,
+ int is_write, int is_user, int *code_out);
+
+extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
+extern int smp_sigio_handler(void);
+extern void initial_thread_cb(void (*proc)(void *), void *arg);
+extern int is_syscall(unsigned long addr);
+extern void timer_handler(int sig, struct uml_pt_regs *regs);
+
+extern void timer_handler(int sig, struct uml_pt_regs *regs);
+
+extern int start_uml(void);
+extern void paging_init(void);
+
+extern void uml_cleanup(void);
+extern void do_uml_exitcalls(void);
+
+/*
+ * Are we disallowed to sleep? Used to choose between GFP_KERNEL and
+ * GFP_ATOMIC.
+ */
+extern int __cant_sleep(void);
+extern void *get_current(void);
+extern int copy_from_user_proc(void *to, void *from, int size);
+extern int cpu(void);
+extern char *uml_strdup(const char *string);
+
+extern unsigned long to_irq_stack(unsigned long *mask_out);
+extern unsigned long from_irq_stack(int nested);
+
+extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
+extern int singlestepping(void *t);
+
+extern void segv_handler(int sig, struct uml_pt_regs *regs);
+extern void bus_handler(int sig, struct uml_pt_regs *regs);
+extern void winch(int sig, struct uml_pt_regs *regs);
+extern void fatal_sigsegv(void) __attribute__ ((noreturn));
+
+
+#endif
diff --git a/arch/um/include/shared/ldt.h b/arch/um/include/shared/ldt.h
new file mode 100644
index 0000000..a7f999a
--- /dev/null
+++ b/arch/um/include/shared/ldt.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
+ * Licensed under the GPL
+ *
+ * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com>
+ */
+
+#ifndef __ASM_LDT_H
+#define __ASM_LDT_H
+
+#include <linux/mutex.h>
+#include <sysdep/host_ldt.h>
+
+extern void ldt_host_info(void);
+
+#define LDT_PAGES_MAX \
+ ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
+#define LDT_ENTRIES_PER_PAGE \
+ (PAGE_SIZE/LDT_ENTRY_SIZE)
+#define LDT_DIRECT_ENTRIES \
+ ((LDT_PAGES_MAX*sizeof(void *))/LDT_ENTRY_SIZE)
+
+struct ldt_entry {
+ __u32 a;
+ __u32 b;
+};
+
+typedef struct uml_ldt {
+ int entry_count;
+ struct mutex lock;
+ union {
+ struct ldt_entry * pages[LDT_PAGES_MAX];
+ struct ldt_entry entries[LDT_DIRECT_ENTRIES];
+ } u;
+} uml_ldt_t;
+
+#endif
diff --git a/arch/um/include/shared/line.h b/arch/um/include/shared/line.h
new file mode 100644
index 0000000..311a0d3
--- /dev/null
+++ b/arch/um/include/shared/line.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __LINE_H__
+#define __LINE_H__
+
+#include "linux/list.h"
+#include "linux/workqueue.h"
+#include "linux/tty.h"
+#include "linux/interrupt.h"
+#include "linux/spinlock.h"
+#include "linux/mutex.h"
+#include "chan_user.h"
+#include "mconsole_kern.h"
+
+/* There's only one modifiable field in this - .mc.list */
+struct line_driver {
+ const char *name;
+ const char *device_name;
+ const short major;
+ const short minor_start;
+ const short type;
+ const short subtype;
+ const int read_irq;
+ const char *read_irq_name;
+ const int write_irq;
+ const char *write_irq_name;
+ struct mc_device mc;
+};
+
+struct line {
+ struct tty_struct *tty;
+ spinlock_t count_lock;
+ int valid;
+
+ char *init_str;
+ int init_pri;
+ struct list_head chan_list;
+
+ /*This lock is actually, mostly, local to*/
+ spinlock_t lock;
+ int throttled;
+ /* Yes, this is a real circular buffer.
+ * XXX: And this should become a struct kfifo!
+ *
+ * buffer points to a buffer allocated on demand, of length
+ * LINE_BUFSIZE, head to the start of the ring, tail to the end.*/
+ char *buffer;
+ char *head;
+ char *tail;
+
+ int sigio;
+ struct delayed_work task;
+ const struct line_driver *driver;
+ int have_irq;
+};
+
+#define LINE_INIT(str, d) \
+ { .count_lock = __SPIN_LOCK_UNLOCKED((str).count_lock), \
+ .init_str = str, \
+ .init_pri = INIT_STATIC, \
+ .valid = 1, \
+ .lock = __SPIN_LOCK_UNLOCKED((str).lock), \
+ .driver = d }
+
+extern void line_close(struct tty_struct *tty, struct file * filp);
+extern int line_open(struct line *lines, struct tty_struct *tty);
+extern int line_setup(struct line *lines, unsigned int sizeof_lines,
+ char *init, char **error_out);
+extern int line_write(struct tty_struct *tty, const unsigned char *buf,
+ int len);
+extern int line_put_char(struct tty_struct *tty, unsigned char ch);
+extern void line_set_termios(struct tty_struct *tty, struct ktermios * old);
+extern int line_chars_in_buffer(struct tty_struct *tty);
+extern void line_flush_buffer(struct tty_struct *tty);
+extern void line_flush_chars(struct tty_struct *tty);
+extern int line_write_room(struct tty_struct *tty);
+extern int line_ioctl(struct tty_struct *tty, struct file * file,
+ unsigned int cmd, unsigned long arg);
+extern void line_throttle(struct tty_struct *tty);
+extern void line_unthrottle(struct tty_struct *tty);
+
+extern char *add_xterm_umid(char *base);
+extern int line_setup_irq(int fd, int input, int output, struct line *line,
+ void *data);
+extern void line_close_chan(struct line *line);
+extern struct tty_driver *register_lines(struct line_driver *line_driver,
+ const struct tty_operations *driver,
+ struct line *lines, int nlines);
+extern void lines_init(struct line *lines, int nlines, struct chan_opts *opts);
+extern void close_lines(struct line *lines, int nlines);
+
+extern int line_config(struct line *lines, unsigned int sizeof_lines,
+ char *str, const struct chan_opts *opts,
+ char **error_out);
+extern int line_id(char **str, int *start_out, int *end_out);
+extern int line_remove(struct line *lines, unsigned int sizeof_lines, int n,
+ char **error_out);
+extern int line_get_config(char *dev, struct line *lines,
+ unsigned int sizeof_lines, char *str,
+ int size, char **error_out);
+
+#endif
diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h
new file mode 100644
index 0000000..e860bc5
--- /dev/null
+++ b/arch/um/include/shared/longjmp.h
@@ -0,0 +1,23 @@
+#ifndef __UML_LONGJMP_H
+#define __UML_LONGJMP_H
+
+#include "sysdep/archsetjmp.h"
+#include "os.h"
+
+extern int setjmp(jmp_buf);
+extern void longjmp(jmp_buf, int);
+
+#define UML_LONGJMP(buf, val) do { \
+ longjmp(*buf, val); \
+} while(0)
+
+#define UML_SETJMP(buf) ({ \
+ int n; \
+ volatile int enable; \
+ enable = get_signals(); \
+ n = setjmp(*buf); \
+ if(n != 0) \
+ set_signals(enable); \
+ n; })
+
+#endif
diff --git a/arch/um/include/shared/mconsole.h b/arch/um/include/shared/mconsole.h
new file mode 100644
index 0000000..c139ae1
--- /dev/null
+++ b/arch/um/include/shared/mconsole.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
+ * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MCONSOLE_H__
+#define __MCONSOLE_H__
+
+#ifndef __KERNEL__
+#include <stdint.h>
+#define u32 uint32_t
+#endif
+
+#include "sysdep/ptrace.h"
+
+#define MCONSOLE_MAGIC (0xcafebabe)
+#define MCONSOLE_MAX_DATA (512)
+#define MCONSOLE_VERSION 2
+
+struct mconsole_request {
+ u32 magic;
+ u32 version;
+ u32 len;
+ char data[MCONSOLE_MAX_DATA];
+};
+
+struct mconsole_reply {
+ u32 err;
+ u32 more;
+ u32 len;
+ char data[MCONSOLE_MAX_DATA];
+};
+
+struct mconsole_notify {
+ u32 magic;
+ u32 version;
+ enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG,
+ MCONSOLE_USER_NOTIFY } type;
+ u32 len;
+ char data[MCONSOLE_MAX_DATA];
+};
+
+struct mc_request;
+
+enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
+
+struct mconsole_command
+{
+ char *command;
+ void (*handler)(struct mc_request *req);
+ enum mc_context context;
+};
+
+struct mc_request
+{
+ int len;
+ int as_interrupt;
+
+ int originating_fd;
+ unsigned int originlen;
+ unsigned char origin[128]; /* sockaddr_un */
+
+ struct mconsole_request request;
+ struct mconsole_command *cmd;
+ struct uml_pt_regs regs;
+};
+
+extern char mconsole_socket_name[];
+
+extern int mconsole_unlink_socket(void);
+extern int mconsole_reply_len(struct mc_request *req, const char *reply,
+ int len, int err, int more);
+extern int mconsole_reply(struct mc_request *req, const char *str, int err,
+ int more);
+
+extern void mconsole_version(struct mc_request *req);
+extern void mconsole_help(struct mc_request *req);
+extern void mconsole_halt(struct mc_request *req);
+extern void mconsole_reboot(struct mc_request *req);
+extern void mconsole_config(struct mc_request *req);
+extern void mconsole_remove(struct mc_request *req);
+extern void mconsole_sysrq(struct mc_request *req);
+extern void mconsole_cad(struct mc_request *req);
+extern void mconsole_stop(struct mc_request *req);
+extern void mconsole_go(struct mc_request *req);
+extern void mconsole_log(struct mc_request *req);
+extern void mconsole_proc(struct mc_request *req);
+extern void mconsole_stack(struct mc_request *req);
+
+extern int mconsole_get_request(int fd, struct mc_request *req);
+extern int mconsole_notify(char *sock_name, int type, const void *data,
+ int len);
+extern char *mconsole_notify_socket(void);
+extern void lock_notify(void);
+extern void unlock_notify(void);
+
+#endif
diff --git a/arch/um/include/shared/mconsole_kern.h b/arch/um/include/shared/mconsole_kern.h
new file mode 100644
index 0000000..d2fe07e
--- /dev/null
+++ b/arch/um/include/shared/mconsole_kern.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MCONSOLE_KERN_H__
+#define __MCONSOLE_KERN_H__
+
+#include "linux/list.h"
+#include "mconsole.h"
+
+struct mconsole_entry {
+ struct list_head list;
+ struct mc_request request;
+};
+
+/* All these methods are called in process context. */
+struct mc_device {
+ struct list_head list;
+ char *name;
+ int (*config)(char *, char **);
+ int (*get_config)(char *, char *, int, char **);
+ int (*id)(char **, int *, int *);
+ int (*remove)(int, char **);
+};
+
+#define CONFIG_CHUNK(str, size, current, chunk, end) \
+do { \
+ current += strlen(chunk); \
+ if(current >= size) \
+ str = NULL; \
+ if(str != NULL){ \
+ strcpy(str, chunk); \
+ str += strlen(chunk); \
+ } \
+ if(end) \
+ current++; \
+} while(0)
+
+#ifdef CONFIG_MCONSOLE
+
+extern void mconsole_register_dev(struct mc_device *new);
+
+#else
+
+static inline void mconsole_register_dev(struct mc_device *new)
+{
+}
+
+#endif
+
+#endif
diff --git a/arch/um/include/shared/mem.h b/arch/um/include/shared/mem.h
new file mode 100644
index 0000000..5cd40e9
--- /dev/null
+++ b/arch/um/include/shared/mem.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MEM_H__
+#define __MEM_H__
+
+extern int phys_mapping(unsigned long phys, unsigned long long *offset_out);
+
+extern unsigned long uml_physmem;
+static inline unsigned long to_phys(void *virt)
+{
+ return(((unsigned long) virt) - uml_physmem);
+}
+
+static inline void *to_virt(unsigned long phys)
+{
+ return((void *) uml_physmem + phys);
+}
+
+#endif
diff --git a/arch/um/include/shared/mem_kern.h b/arch/um/include/shared/mem_kern.h
new file mode 100644
index 0000000..cb7e196
--- /dev/null
+++ b/arch/um/include/shared/mem_kern.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MEM_KERN_H__
+#define __MEM_KERN_H__
+
+#include "linux/list.h"
+#include "linux/types.h"
+
+struct remapper {
+ struct list_head list;
+ int (*proc)(int, unsigned long, int, __u64);
+};
+
+extern void register_remapper(struct remapper *info);
+
+#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
+ * 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/arch/um/include/shared/mem_user.h b/arch/um/include/shared/mem_user.h
new file mode 100644
index 0000000..46384ac
--- /dev/null
+++ b/arch/um/include/shared/mem_user.h
@@ -0,0 +1,62 @@
+/*
+ * arch/um/include/mem_user.h
+ *
+ * BRIEF MODULE DESCRIPTION
+ * user side memory interface for support IO memory inside user mode linux
+ *
+ * Copyright (C) 2001 RidgeRun, Inc.
+ * Author: RidgeRun, Inc.
+ * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef _MEM_USER_H
+#define _MEM_USER_H
+
+struct iomem_region {
+ struct iomem_region *next;
+ char *driver;
+ int fd;
+ int size;
+ unsigned long phys;
+ unsigned long virt;
+};
+
+extern struct iomem_region *iomem_regions;
+extern int iomem_size;
+
+#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
+
+extern int init_mem_user(void);
+extern void setup_memory(void *entry);
+extern unsigned long find_iomem(char *driver, unsigned long *len_out);
+extern int init_maps(unsigned long physmem, unsigned long iomem,
+ unsigned long highmem);
+extern unsigned long get_vm(unsigned long len);
+extern void setup_physmem(unsigned long start, unsigned long usable,
+ unsigned long len, unsigned long long highmem);
+extern void add_iomem(char *name, int fd, unsigned long size);
+extern unsigned long phys_offset(unsigned long phys);
+extern void map_memory(unsigned long virt, unsigned long phys,
+ unsigned long len, int r, int w, int x);
+
+#endif
diff --git a/arch/um/include/shared/net_kern.h b/arch/um/include/shared/net_kern.h
new file mode 100644
index 0000000..d843c79
--- /dev/null
+++ b/arch/um/include/shared/net_kern.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_NET_KERN_H
+#define __UM_NET_KERN_H
+
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/skbuff.h>
+#include <linux/socket.h>
+#include <linux/list.h>
+#include <linux/workqueue.h>
+
+struct uml_net {
+ struct list_head list;
+ struct net_device *dev;
+ struct platform_device pdev;
+ int index;
+ unsigned char mac[ETH_ALEN];
+};
+
+struct uml_net_private {
+ struct list_head list;
+ spinlock_t lock;
+ struct net_device *dev;
+ struct timer_list tl;
+ struct net_device_stats stats;
+ struct work_struct work;
+ int fd;
+ unsigned char mac[ETH_ALEN];
+ int max_packet;
+ unsigned short (*protocol)(struct sk_buff *);
+ int (*open)(void *);
+ void (*close)(int, void *);
+ void (*remove)(void *);
+ int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
+ int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
+
+ void (*add_address)(unsigned char *, unsigned char *, void *);
+ void (*delete_address)(unsigned char *, unsigned char *, void *);
+ char user[0];
+};
+
+struct net_kern_info {
+ void (*init)(struct net_device *, void *);
+ unsigned short (*protocol)(struct sk_buff *);
+ int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
+ int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
+};
+
+struct transport {
+ struct list_head list;
+ const char *name;
+ int (* const setup)(char *, char **, void *);
+ const struct net_user_info *user;
+ const struct net_kern_info *kern;
+ const int private_size;
+ const int setup_size;
+};
+
+extern struct net_device *ether_init(int);
+extern unsigned short ether_protocol(struct sk_buff *);
+extern int tap_setup_common(char *str, char *type, char **dev_name,
+ char **mac_out, char **gate_addr);
+extern void register_transport(struct transport *new);
+extern unsigned short eth_protocol(struct sk_buff *skb);
+
+#endif
diff --git a/arch/um/include/shared/net_user.h b/arch/um/include/shared/net_user.h
new file mode 100644
index 0000000..63bee15
--- /dev/null
+++ b/arch/um/include/shared/net_user.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_NET_USER_H__
+#define __UM_NET_USER_H__
+
+#define ETH_ADDR_LEN (6)
+#define ETH_HEADER_ETHERTAP (16)
+#define ETH_HEADER_OTHER (14)
+#define ETH_MAX_PACKET (1500)
+
+#define UML_NET_VERSION (4)
+
+struct net_user_info {
+ int (*init)(void *, void *);
+ int (*open)(void *);
+ void (*close)(int, void *);
+ void (*remove)(void *);
+ void (*add_address)(unsigned char *, unsigned char *, void *);
+ void (*delete_address)(unsigned char *, unsigned char *, void *);
+ int max_packet;
+ int mtu;
+};
+
+extern void ether_user_init(void *data, void *dev);
+extern void iter_addresses(void *d, void (*cb)(unsigned char *,
+ unsigned char *, void *),
+ void *arg);
+
+extern void *get_output_buffer(int *len_out);
+extern void free_output_buffer(void *buffer);
+
+extern int tap_open_common(void *dev, char *gate_addr);
+extern void tap_check_ips(char *gate_addr, unsigned char *eth_addr);
+
+extern void read_output(int fd, char *output_out, int len);
+
+extern int net_read(int fd, void *buf, int len);
+extern int net_recvfrom(int fd, void *buf, int len);
+extern int net_write(int fd, void *buf, int len);
+extern int net_send(int fd, void *buf, int len);
+extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len);
+
+extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg);
+extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg);
+
+extern char *split_if_spec(char *str, ...);
+
+extern int dev_netmask(void *d, void *m);
+
+#endif
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h
new file mode 100644
index 0000000..cd40fdd
--- /dev/null
+++ b/arch/um/include/shared/os.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __OS_H__
+#define __OS_H__
+
+#include <stdarg.h>
+#include "irq_user.h"
+#include "longjmp.h"
+#include "mm_id.h"
+#include "sysdep/tls.h"
+
+#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
+
+#define OS_TYPE_FILE 1
+#define OS_TYPE_DIR 2
+#define OS_TYPE_SYMLINK 3
+#define OS_TYPE_CHARDEV 4
+#define OS_TYPE_BLOCKDEV 5
+#define OS_TYPE_FIFO 6
+#define OS_TYPE_SOCK 7
+
+/* os_access() flags */
+#define OS_ACC_F_OK 0 /* Test for existence. */
+#define OS_ACC_X_OK 1 /* Test for execute permission. */
+#define OS_ACC_W_OK 2 /* Test for write permission. */
+#define OS_ACC_R_OK 4 /* Test for read permission. */
+#define OS_ACC_RW_OK (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
+
+/*
+ * types taken from stat_file() in hostfs_user.c
+ * (if they are wrong here, they are wrong there...).
+ */
+struct uml_stat {
+ int ust_dev; /* device */
+ unsigned long long ust_ino; /* inode */
+ int ust_mode; /* protection */
+ int ust_nlink; /* number of hard links */
+ int ust_uid; /* user ID of owner */
+ int ust_gid; /* group ID of owner */
+ unsigned long long ust_size; /* total size, in bytes */
+ int ust_blksize; /* blocksize for filesystem I/O */
+ unsigned long long ust_blocks; /* number of blocks allocated */
+ unsigned long ust_atime; /* time of last access */
+ unsigned long ust_mtime; /* time of last modification */
+ unsigned long ust_ctime; /* time of last change */
+};
+
+struct openflags {
+ unsigned int r : 1;
+ unsigned int w : 1;
+ unsigned int s : 1; /* O_SYNC */
+ unsigned int c : 1; /* O_CREAT */
+ unsigned int t : 1; /* O_TRUNC */
+ unsigned int a : 1; /* O_APPEND */
+ unsigned int e : 1; /* O_EXCL */
+ unsigned int cl : 1; /* FD_CLOEXEC */
+};
+
+#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \
+ .t = 0, .a = 0, .e = 0, .cl = 0 })
+
+static inline struct openflags of_read(struct openflags flags)
+{
+ flags.r = 1;
+ return flags;
+}
+
+static inline struct openflags of_write(struct openflags flags)
+{
+ flags.w = 1;
+ return flags;
+}
+
+static inline struct openflags of_rdwr(struct openflags flags)
+{
+ return of_read(of_write(flags));
+}
+
+static inline struct openflags of_set_rw(struct openflags flags, int r, int w)
+{
+ flags.r = r;
+ flags.w = w;
+ return flags;
+}
+
+static inline struct openflags of_sync(struct openflags flags)
+{
+ flags.s = 1;
+ return flags;
+}
+
+static inline struct openflags of_create(struct openflags flags)
+{
+ flags.c = 1;
+ return flags;
+}
+
+static inline struct openflags of_trunc(struct openflags flags)
+{
+ flags.t = 1;
+ return flags;
+}
+
+static inline struct openflags of_append(struct openflags flags)
+{
+ flags.a = 1;
+ return flags;
+}
+
+static inline struct openflags of_excl(struct openflags flags)
+{
+ flags.e = 1;
+ return flags;
+}
+
+static inline struct openflags of_cloexec(struct openflags flags)
+{
+ flags.cl = 1;
+ return flags;
+}
+
+/* file.c */
+extern int os_stat_file(const char *file_name, struct uml_stat *buf);
+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_exec_close(int fd);
+extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
+extern int os_get_ifname(int fd, char *namebuf);
+extern int os_set_slip(int fd);
+extern int os_mode_fd(int fd, int mode);
+
+extern int os_seek_file(int fd, unsigned long long offset);
+extern int os_open_file(const char *file, struct openflags flags, int mode);
+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(const char *file, unsigned long long *size_out);
+extern int os_file_modtime(const 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);
+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(const char *file, int len, int close_on_exec);
+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);
+extern int create_unix_socket(char *file, int len, int close_on_exec);
+extern int os_connect_socket(const char *name);
+extern int os_file_type(char *file);
+extern int os_file_mode(const char *file, struct openflags *mode_out);
+extern int os_lock_file(int fd, int excl);
+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 int os_change_dir(char *dir);
+extern int os_fchange_dir(int fd);
+
+/* start_up.c */
+extern void os_early_checks(void);
+extern void can_do_skas(void);
+extern void os_check_bugs(void);
+extern void check_host_supports_tls(int *supports_tls, int *tls_min);
+
+/* mem.c */
+extern int create_mem_file(unsigned long long len);
+
+/* process.c */
+extern unsigned long os_process_pc(int pid);
+extern int os_process_parent(int pid);
+extern void os_stop_process(int pid);
+extern void os_kill_process(int pid, int reap_child);
+extern void os_kill_ptraced_process(int pid, int reap_child);
+extern long os_ptrace_ldt(long pid, long addr, long data);
+
+extern int os_getpid(void);
+extern int os_getpgrp(void);
+
+extern void init_new_thread_signals(void);
+extern int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr);
+
+extern int os_map_memory(void *virt, int fd, unsigned long long off,
+ unsigned long len, int r, int w, int x);
+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 int os_drop_memory(void *addr, int length);
+extern int can_drop_memory(void);
+extern void os_flush_stdout(void);
+
+/* uaccess.c */
+extern unsigned long __do_user_copy(void *to, const void *from, int n,
+ void **fault_addr, jmp_buf **fault_catcher,
+ void (*op)(void *to, const void *from,
+ int n), int *faulted_out);
+
+/* execvp.c */
+extern int execvp_noalloc(char *buf, const char *file, char *const argv[]);
+/* helper.c */
+extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv);
+extern int run_helper_thread(int (*proc)(void *), void *arg,
+ unsigned int flags, unsigned long *stack_out);
+extern int helper_wait(int pid);
+
+
+/* tls.c */
+extern int os_set_thread_area(user_desc_t *info, int pid);
+extern int os_get_thread_area(user_desc_t *info, int pid);
+
+/* umid.c */
+extern int umid_file_name(char *name, char *buf, int len);
+extern int set_umid(char *name);
+extern char *get_umid(void);
+
+/* signal.c */
+extern void timer_init(void);
+extern void set_sigstack(void *sig_stack, int size);
+extern void remove_sigstack(void);
+extern void set_handler(int sig, void (*handler)(int), int flags, ...);
+extern int change_sig(int signal, int on);
+extern void block_signals(void);
+extern void unblock_signals(void);
+extern int get_signals(void);
+extern int set_signals(int enable);
+
+/* util.c */
+extern void stack_protections(unsigned long address);
+extern int raw(int fd);
+extern void setup_machinename(char *machine_out);
+extern void setup_hostinfo(char *buf, int len);
+extern void os_dump_core(void) __attribute__ ((noreturn));
+
+/* time.c */
+extern void idle_sleep(unsigned long long nsecs);
+extern int set_interval(void);
+extern int timer_one_shot(int ticks);
+extern long long disable_timer(void);
+extern void uml_idle_timer(void);
+extern long long os_nsecs(void);
+
+/* skas/mem.c */
+extern long run_syscall_stub(struct mm_id * mm_idp,
+ int syscall, unsigned long *args, long expected,
+ void **addr, int done);
+extern long syscall_stub_data(struct mm_id * mm_idp,
+ unsigned long *data, int data_count,
+ void **addr, void **stub_addr);
+extern int map(struct mm_id * mm_idp, unsigned long virt,
+ unsigned long len, int prot, int phys_fd,
+ unsigned long long offset, int done, void **data);
+extern int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
+ int done, void **data);
+extern int protect(struct mm_id * mm_idp, unsigned long addr,
+ unsigned long len, unsigned int prot, int done, void **data);
+
+/* skas/process.c */
+extern int is_skas_winch(int pid, int fd, void *data);
+extern int start_userspace(unsigned long stub_stack);
+extern int copy_context_skas0(unsigned long stack, int pid);
+extern void userspace(struct uml_pt_regs *regs);
+extern int map_stub_pages(int fd, unsigned long code, unsigned long data,
+ unsigned long stack);
+extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
+extern void switch_threads(jmp_buf *me, jmp_buf *you);
+extern int start_idle_thread(void *stack, jmp_buf *switch_buf);
+extern void initial_thread_cb_skas(void (*proc)(void *),
+ void *arg);
+extern void halt_skas(void);
+extern void reboot_skas(void);
+
+/* irq.c */
+extern int os_waiting_for_events(struct irq_fd *active_fds);
+extern int os_create_pollfd(int fd, int events, void *tmp_pfd, int size_tmpfds);
+extern void os_free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg,
+ struct irq_fd *active_fds, struct irq_fd ***last_irq_ptr2);
+extern void os_free_irq_later(struct irq_fd *active_fds,
+ int irq, void *dev_id);
+extern int os_get_pollfd(int i);
+extern void os_set_pollfd(int i, int fd);
+extern void os_set_ioignore(void);
+
+/* sigio.c */
+extern int add_sigio_fd(int fd);
+extern int ignore_sigio_fd(int fd);
+extern void maybe_sigio_broken(int fd, int read);
+extern void sigio_broken(int fd, int read);
+
+/* sys-x86_64/prctl.c */
+extern int os_arch_prctl(int pid, int code, unsigned long *addr);
+
+/* tty.c */
+extern int get_pty(void);
+
+/* sys-$ARCH/task_size.c */
+extern unsigned long os_get_top_address(void);
+
+#endif
diff --git a/arch/um/include/shared/process.h b/arch/um/include/shared/process.h
new file mode 100644
index 0000000..bb873a5
--- /dev/null
+++ b/arch/um/include/shared/process.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2000 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __PROCESS_H__
+#define __PROCESS_H__
+
+#include <signal.h>
+
+/* Copied from linux/compiler-gcc.h since we can't include it directly */
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+extern void sig_handler(int sig, struct sigcontext *sc);
+extern void alarm_handler(int sig, struct sigcontext *sc);
+
+#endif
diff --git a/arch/um/include/shared/ptrace_user.h b/arch/um/include/shared/ptrace_user.h
new file mode 100644
index 0000000..4bce6e0
--- /dev/null
+++ b/arch/um/include/shared/ptrace_user.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __PTRACE_USER_H__
+#define __PTRACE_USER_H__
+
+#include "sysdep/ptrace_user.h"
+
+extern int ptrace_getregs(long pid, unsigned long *regs_out);
+extern int ptrace_setregs(long pid, unsigned long *regs_in);
+
+/* syscall emulation path in ptrace */
+
+#ifndef PTRACE_SYSEMU
+#define PTRACE_SYSEMU 31
+#endif
+#ifndef PTRACE_SYSEMU_SINGLESTEP
+#define PTRACE_SYSEMU_SINGLESTEP 32
+#endif
+
+/* On architectures, that started to support PTRACE_O_TRACESYSGOOD
+ * in linux 2.4, there are two different definitions of
+ * PTRACE_SETOPTIONS: linux 2.4 uses 21 while linux 2.6 uses 0x4200.
+ * For binary compatibility, 2.6 also supports the old "21", named
+ * PTRACE_OLDSETOPTION. On these architectures, UML always must use
+ * "21", to ensure the kernel runs on 2.4 and 2.6 host without
+ * recompilation. So, we use PTRACE_OLDSETOPTIONS in UML.
+ * We also want to be able to build the kernel on 2.4, which doesn't
+ * have PTRACE_OLDSETOPTIONS. So, if it is missing, we declare
+ * PTRACE_OLDSETOPTIONS to to be the same as PTRACE_SETOPTIONS.
+ *
+ * On architectures, that start to support PTRACE_O_TRACESYSGOOD on
+ * linux 2.6, PTRACE_OLDSETOPTIONS never is defined, and also isn't
+ * supported by the host kernel. In that case, our trick lets us use
+ * the new 0x4200 with the name PTRACE_OLDSETOPTIONS.
+ */
+#ifndef PTRACE_OLDSETOPTIONS
+#define PTRACE_OLDSETOPTIONS PTRACE_SETOPTIONS
+#endif
+
+void set_using_sysemu(int value);
+int get_using_sysemu(void);
+extern int sysemu_supported;
+
+#define SELECT_PTRACE_OPERATION(sysemu_mode, singlestep_mode) \
+ (((int[3][3] ) { \
+ { PTRACE_SYSCALL, PTRACE_SYSCALL, PTRACE_SINGLESTEP }, \
+ { PTRACE_SYSEMU, PTRACE_SYSEMU, PTRACE_SINGLESTEP }, \
+ { PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP, \
+ PTRACE_SYSEMU_SINGLESTEP } }) \
+ [sysemu_mode][singlestep_mode])
+
+#endif
diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h
new file mode 100644
index 0000000..b0b4589
--- /dev/null
+++ b/arch/um/include/shared/registers.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#ifndef __REGISTERS_H
+#define __REGISTERS_H
+
+#include "sysdep/ptrace.h"
+#include "sysdep/archsetjmp.h"
+
+extern int save_fp_registers(int pid, unsigned long *fp_regs);
+extern int restore_fp_registers(int pid, unsigned long *fp_regs);
+extern int save_fpx_registers(int pid, unsigned long *fp_regs);
+extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
+extern int save_registers(int pid, struct uml_pt_regs *regs);
+extern int restore_registers(int pid, struct uml_pt_regs *regs);
+extern int init_registers(int pid);
+extern void get_safe_registers(unsigned long *regs);
+extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
+extern int get_fp_registers(int pid, unsigned long *regs);
+extern int put_fp_registers(int pid, unsigned long *regs);
+
+#endif
diff --git a/arch/um/include/shared/sigio.h b/arch/um/include/shared/sigio.h
new file mode 100644
index 0000000..434f1a9
--- /dev/null
+++ b/arch/um/include/shared/sigio.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SIGIO_H__
+#define __SIGIO_H__
+
+extern int write_sigio_irq(int fd);
+extern int register_sigio_fd(int fd);
+extern void sigio_lock(void);
+extern void sigio_unlock(void);
+
+#endif
diff --git a/arch/um/include/shared/skas/mm_id.h b/arch/um/include/shared/skas/mm_id.h
new file mode 100644
index 0000000..48dd098
--- /dev/null
+++ b/arch/um/include/shared/skas/mm_id.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __MM_ID_H
+#define __MM_ID_H
+
+struct mm_id {
+ union {
+ int mm_fd;
+ int pid;
+ } u;
+ unsigned long stack;
+};
+
+#endif
diff --git a/arch/um/include/shared/skas/proc_mm.h b/arch/um/include/shared/skas/proc_mm.h
new file mode 100644
index 0000000..9028092
--- /dev/null
+++ b/arch/um/include/shared/skas/proc_mm.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_PROC_MM_H
+#define __SKAS_PROC_MM_H
+
+#define MM_MMAP 54
+#define MM_MUNMAP 55
+#define MM_MPROTECT 56
+#define MM_COPY_SEGMENTS 57
+
+struct mm_mmap {
+ unsigned long addr;
+ unsigned long len;
+ unsigned long prot;
+ unsigned long flags;
+ unsigned long fd;
+ unsigned long offset;
+};
+
+struct mm_munmap {
+ unsigned long addr;
+ unsigned long len;
+};
+
+struct mm_mprotect {
+ unsigned long addr;
+ unsigned long len;
+ unsigned int prot;
+};
+
+struct proc_mm_op {
+ int op;
+ union {
+ struct mm_mmap mmap;
+ struct mm_munmap munmap;
+ struct mm_mprotect mprotect;
+ int copy_segments;
+ } u;
+};
+
+#endif
diff --git a/arch/um/include/shared/skas/skas.h b/arch/um/include/shared/skas/skas.h
new file mode 100644
index 0000000..64d2c74
--- /dev/null
+++ b/arch/um/include/shared/skas/skas.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_H
+#define __SKAS_H
+
+#include "sysdep/ptrace.h"
+
+extern int userspace_pid[];
+extern int proc_mm, ptrace_faultinfo, ptrace_ldt;
+extern int skas_needs_stub;
+
+extern int user_thread(unsigned long stack, int flags);
+extern void new_thread_handler(void);
+extern void handle_syscall(struct uml_pt_regs *regs);
+extern int new_mm(unsigned long stack);
+extern long execute_syscall_skas(void *r);
+extern unsigned long current_stub_stack(void);
+
+#endif
diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h
new file mode 100644
index 0000000..f6ed92c
--- /dev/null
+++ b/arch/um/include/shared/skas/stub-data.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright (C) 2005 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __STUB_DATA_H
+#define __STUB_DATA_H
+
+#include <sys/time.h>
+
+struct stub_data {
+ long offset;
+ int fd;
+ struct itimerval timer;
+ long err;
+};
+
+#endif
diff --git a/arch/um/include/shared/skas_ptrace.h b/arch/um/include/shared/skas_ptrace.h
new file mode 100644
index 0000000..3d31bba
--- /dev/null
+++ b/arch/um/include/shared/skas_ptrace.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SKAS_PTRACE_H
+#define __SKAS_PTRACE_H
+
+#define PTRACE_FAULTINFO 52
+#define PTRACE_SWITCH_MM 55
+
+#include "sysdep/skas_ptrace.h"
+
+#endif
diff --git a/arch/um/include/shared/skas_ptregs.h b/arch/um/include/shared/skas_ptregs.h
new file mode 100644
index 0000000..73db19e
--- /dev/null
+++ b/arch/um/include/shared/skas_ptregs.h
@@ -0,0 +1,6 @@
+#ifndef __SKAS_PT_REGS_
+#define __SKAS_PT_REGS_
+
+#include <user_constants.h>
+
+#endif
diff --git a/arch/um/include/shared/syscall.h b/arch/um/include/shared/syscall.h
new file mode 100644
index 0000000..dda1df9
--- /dev/null
+++ b/arch/um/include/shared/syscall.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSCALL_USER_H
+#define __SYSCALL_USER_H
+
+extern int record_syscall_start(int syscall);
+extern void record_syscall_end(int index, long result);
+
+#endif
diff --git a/arch/um/include/shared/sysrq.h b/arch/um/include/shared/sysrq.h
new file mode 100644
index 0000000..c8d332b
--- /dev/null
+++ b/arch/um/include/shared/sysrq.h
@@ -0,0 +1,7 @@
+#ifndef __UM_SYSRQ_H
+#define __UM_SYSRQ_H
+
+struct task_struct;
+extern void show_trace(struct task_struct* task, unsigned long *stack);
+
+#endif
diff --git a/arch/um/include/shared/task.h b/arch/um/include/shared/task.h
new file mode 100644
index 0000000..3fe726b
--- /dev/null
+++ b/arch/um/include/shared/task.h
@@ -0,0 +1,9 @@
+#ifndef __TASK_H
+#define __TASK_H
+
+#include <kern_constants.h>
+
+#define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS]))
+#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID]))
+
+#endif
diff --git a/arch/um/include/shared/tlb.h b/arch/um/include/shared/tlb.h
new file mode 100644
index 0000000..ecd2265
--- /dev/null
+++ b/arch/um/include/shared/tlb.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __TLB_H__
+#define __TLB_H__
+
+#include "um_mmu.h"
+
+extern void force_flush_all(void);
+extern int flush_tlb_kernel_range_common(unsigned long start,
+ unsigned long end);
+
+#endif
diff --git a/arch/um/include/shared/ubd_user.h b/arch/um/include/shared/ubd_user.h
new file mode 100644
index 0000000..bb66517
--- /dev/null
+++ b/arch/um/include/shared/ubd_user.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_UBD_USER_H
+#define __UM_UBD_USER_H
+
+extern void ignore_sigwinch_sig(void);
+extern int start_io_thread(unsigned long sp, int *fds_out);
+extern int io_thread(void *arg);
+extern int kernel_fd;
+
+#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
+ * 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/arch/um/include/shared/um_malloc.h b/arch/um/include/shared/um_malloc.h
new file mode 100644
index 0000000..c554d70
--- /dev/null
+++ b/arch/um/include/shared/um_malloc.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2005 Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_MALLOC_H__
+#define __UM_MALLOC_H__
+
+#include "kern_constants.h"
+
+extern void *uml_kmalloc(int size, int flags);
+extern void kfree(const void *ptr);
+
+extern void *vmalloc(unsigned long size);
+extern void vfree(void *ptr);
+
+#endif /* __UM_MALLOC_H__ */
+
+
diff --git a/arch/um/include/shared/um_mmu.h b/arch/um/include/shared/um_mmu.h
new file mode 100644
index 0000000..b1a7e47
--- /dev/null
+++ b/arch/um/include/shared/um_mmu.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __ARCH_UM_MMU_H
+#define __ARCH_UM_MMU_H
+
+#include "mm_id.h"
+#include "ldt.h"
+
+typedef struct mm_context {
+ struct mm_id id;
+ struct uml_ldt ldt;
+ struct page **stub_pages;
+} mm_context_t;
+
+extern void __switch_mm(struct mm_id * mm_idp);
+
+/* Avoid tangled inclusion with asm/ldt.h */
+extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm);
+extern void free_ldt(struct mm_context *mm);
+
+#endif
diff --git a/arch/um/include/shared/um_uaccess.h b/arch/um/include/shared/um_uaccess.h
new file mode 100644
index 0000000..45c0499
--- /dev/null
+++ b/arch/um/include/shared/um_uaccess.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __ARCH_UM_UACCESS_H
+#define __ARCH_UM_UACCESS_H
+
+#include <asm/elf.h>
+#include <asm/fixmap.h>
+#include "sysdep/archsetjmp.h"
+
+#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) && \
+ ((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);
+
+extern int __do_copy_to_user(void *to, const void *from, int n,
+ void **fault_addr, jmp_buf **fault_catcher);
+
+/*
+ * 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);
+
+#endif
diff --git a/arch/um/include/shared/user.h b/arch/um/include/shared/user.h
new file mode 100644
index 0000000..293f7c7
--- /dev/null
+++ b/arch/um/include/shared/user.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
+ * Licensed under the GPL
+ */
+
+#ifndef __USER_H__
+#define __USER_H__
+
+#include "kern_constants.h"
+
+/*
+ * The usual definition - copied here because the kernel provides its own,
+ * fancier, type-safe, definition. Using that one would require
+ * copying too much infrastructure for my taste, so userspace files
+ * get less checking than kernel files.
+ */
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+/* This is to get size_t */
+#ifdef __KERNEL__
+#include <linux/types.h>
+#else
+#include <stddef.h>
+#endif
+
+extern void panic(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+
+#ifdef UML_CONFIG_PRINTK
+extern int printk(const char *fmt, ...)
+ __attribute__ ((format (printf, 1, 2)));
+#else
+static inline int printk(const char *fmt, ...)
+{
+ return 0;
+}
+#endif
+
+extern void schedule(void);
+extern int in_aton(char *str);
+extern int open_gdb_chan(void);
+extern size_t strlcpy(char *, const char *, size_t);
+extern size_t strlcat(char *, const char *, size_t);
+
+#endif
OpenPOWER on IntegriCloud