aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-11 18:08:53 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-01-11 18:08:53 -0800
commitf95e6dae6522e0c403bef92405a3577ebd8baee9 (patch)
tree40c9f91e77cba0fddd1c019ae317f5768c267740 /arch
parentf741676a0eea898c7fd2169df9cfcf65a3f76bd1 (diff)
parentaae7d141676c5d83dbc97732f1cf48839f404774 (diff)
downloadhistory-f95e6dae6522e0c403bef92405a3577ebd8baee9.tar.gz
Merge http://lia64.bkbits.net/linux-ia64-release-2.6.11
into ppc970.osdl.org:/home/torvalds/v2.6/linux
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/Kconfig2
-rw-r--r--arch/i386/kernel/apic.c15
-rw-r--r--arch/i386/kernel/cpu/amd.c17
-rw-r--r--arch/i386/kernel/cpu/common.c54
-rw-r--r--arch/i386/kernel/cpu/intel.c45
-rw-r--r--arch/i386/kernel/cpu/proc.c17
-rw-r--r--arch/i386/kernel/kprobes.c19
-rw-r--r--arch/i386/kernel/signal.c6
-rw-r--r--arch/i386/kernel/smpboot.c1
-rw-r--r--arch/i386/mm/ioremap.c6
-rw-r--r--arch/i386/mm/pageattr.c28
-rw-r--r--arch/i386/pci/fixup.c14
-rw-r--r--arch/ia64/pci/pci.c1
-rw-r--r--arch/m32r/mm/init.c3
-rw-r--r--arch/mips/kernel/irixelf.c11
-rw-r--r--arch/parisc/kernel/binfmt_elf32.c6
-rw-r--r--arch/ppc/kernel/idle.c7
-rw-r--r--arch/ppc/kernel/perfmon.c1
-rw-r--r--arch/ppc/mm/init.c1
-rw-r--r--arch/ppc64/kernel/binfmt_elf32.c6
-rw-r--r--arch/ppc64/kernel/kprobes.c2
-rw-r--r--arch/ppc64/kernel/maple_pci.c3
-rw-r--r--arch/ppc64/kernel/misc.S20
-rw-r--r--arch/ppc64/kernel/pSeries_pci.c1
-rw-r--r--arch/ppc64/kernel/pSeries_smp.c56
-rw-r--r--arch/ppc64/kernel/pacaData.c6
-rw-r--r--arch/ppc64/kernel/pci.c33
-rw-r--r--arch/ppc64/kernel/pci.h4
-rw-r--r--arch/ppc64/kernel/pci_dn.c33
-rw-r--r--arch/ppc64/kernel/pmac_pci.c2
-rw-r--r--arch/ppc64/kernel/ppc_ksyms.c1
-rw-r--r--arch/ppc64/kernel/process.c48
-rw-r--r--arch/ppc64/kernel/rtas-proc.c12
-rw-r--r--arch/ppc64/kernel/rtasd.c2
-rw-r--r--arch/ppc64/kernel/smp.c28
-rw-r--r--arch/ppc64/kernel/time.c78
-rw-r--r--arch/ppc64/kernel/traps.c5
-rw-r--r--arch/ppc64/kernel/xics.c17
-rw-r--r--arch/ppc64/mm/init.c1
-rw-r--r--arch/ppc64/mm/numa.c23
-rw-r--r--arch/ppc64/xmon/setjmp.S73
-rw-r--r--arch/ppc64/xmon/setjmp.c77
-rw-r--r--arch/ppc64/xmon/xmon.c24
-rw-r--r--arch/s390/Kconfig7
-rw-r--r--arch/s390/kernel/binfmt_elf32.c9
-rw-r--r--arch/s390/kernel/entry.S135
-rw-r--r--arch/s390/kernel/entry64.S128
-rw-r--r--arch/s390/kernel/irq.c8
-rw-r--r--arch/s390/kernel/time.c42
-rw-r--r--arch/s390/kernel/vtime.c111
-rw-r--r--arch/sparc64/kernel/binfmt_aout32.c14
-rw-r--r--arch/sparc64/kernel/binfmt_elf32.c6
-rw-r--r--arch/um/Kconfig7
-rw-r--r--arch/um/Kconfig_arch16
-rw-r--r--arch/um/Kconfig_char11
-rw-r--r--arch/um/Kconfig_i38620
-rw-r--r--arch/um/Kconfig_x86_6411
-rw-r--r--arch/um/Makefile20
-rw-r--r--arch/um/Makefile-i3868
-rw-r--r--arch/um/Makefile-x86_6435
-rw-r--r--arch/um/defconfig4
-rw-r--r--arch/um/drivers/Makefile3
-rw-r--r--arch/um/drivers/chan_kern.c4
-rw-r--r--arch/um/drivers/cow.h5
-rw-r--r--arch/um/drivers/cow_sys.h4
-rw-r--r--arch/um/drivers/cow_user.c6
-rw-r--r--arch/um/drivers/line.c31
-rw-r--r--arch/um/drivers/mconsole_kern.c11
-rw-r--r--arch/um/drivers/mmapper_kern.c2
-rw-r--r--arch/um/drivers/ubd_kern.c10
-rw-r--r--arch/um/drivers/ubd_user.c2
-rw-r--r--arch/um/include/process.h2
-rw-r--r--arch/um/include/registers.h27
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h45
-rw-r--r--arch/um/include/sysdep-i386/signal.h (renamed from arch/um/kernel/tt/include/ptrace-tt.h)15
-rw-r--r--arch/um/include/sysdep-i386/syscalls.h71
-rw-r--r--arch/um/include/sysdep-ppc/syscalls.h7
-rw-r--r--arch/um/include/sysdep-x86_64/checksum.h151
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h260
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace_user.h69
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h49
-rw-r--r--arch/um/include/sysdep-x86_64/signal.h27
-rw-r--r--arch/um/include/sysdep-x86_64/syscalls.h96
-rw-r--r--arch/um/include/um_uaccess.h14
-rw-r--r--arch/um/include/uml_uaccess.h2
-rw-r--r--arch/um/kernel/checksum.c12
-rw-r--r--arch/um/kernel/exec_kern.c10
-rw-r--r--arch/um/kernel/exitcode.c2
-rw-r--r--arch/um/kernel/irq.c14
-rw-r--r--arch/um/kernel/mem.c14
-rw-r--r--arch/um/kernel/mem_user.c4
-rw-r--r--arch/um/kernel/physmem.c7
-rw-r--r--arch/um/kernel/process.c8
-rw-r--r--arch/um/kernel/process_kern.c20
-rw-r--r--arch/um/kernel/ptrace.c44
-rw-r--r--arch/um/kernel/signal_kern.c41
-rw-r--r--arch/um/kernel/signal_user.c1
-rw-r--r--arch/um/kernel/skas/Makefile2
-rw-r--r--arch/um/kernel/skas/include/ptrace-skas.h57
-rw-r--r--arch/um/kernel/skas/include/skas.h3
-rw-r--r--arch/um/kernel/skas/mem.c5
-rw-r--r--arch/um/kernel/skas/process.c93
-rw-r--r--arch/um/kernel/skas/process_kern.c8
-rw-r--r--arch/um/kernel/skas/tlb.c150
-rw-r--r--arch/um/kernel/skas/trap_user.c1
-rw-r--r--arch/um/kernel/skas/uaccess.c48
-rw-r--r--arch/um/kernel/skas/util/Makefile2
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-i386.c (renamed from arch/um/kernel/skas/util/mk_ptregs.c)4
-rw-r--r--arch/um/kernel/skas/util/mk_ptregs-x86_64.c68
-rw-r--r--arch/um/kernel/smp.c6
-rw-r--r--arch/um/kernel/sys_call_table.c450
-rw-r--r--arch/um/kernel/syscall_kern.c129
-rw-r--r--arch/um/kernel/time_kern.c25
-rw-r--r--arch/um/kernel/tlb.c16
-rw-r--r--arch/um/kernel/trap_kern.c8
-rw-r--r--arch/um/kernel/trap_user.c22
-rw-r--r--arch/um/kernel/tt/Makefile5
-rw-r--r--arch/um/kernel/tt/gdb.c8
-rw-r--r--arch/um/kernel/tt/ptproxy/proxy.c8
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.c1
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.c1
-rw-r--r--arch/um/kernel/tt/syscall_kern.c93
-rw-r--r--arch/um/kernel/tt/tlb.c160
-rw-r--r--arch/um/kernel/tt/tracer.c1
-rw-r--r--arch/um/kernel/tt/trap_user.c1
-rw-r--r--arch/um/kernel/tt/uaccess.c12
-rw-r--r--arch/um/kernel/um_arch.c5
-rw-r--r--arch/um/os-Linux/Makefile7
-rw-r--r--arch/um/os-Linux/elf_aux.c1
-rw-r--r--arch/um/os-Linux/signal.c48
-rw-r--r--arch/um/os-Linux/sys-i386/Makefile11
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c115
-rw-r--r--arch/um/os-Linux/sys-x86_64/Makefile11
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c82
-rw-r--r--arch/um/os-Linux/user_syms.c8
-rw-r--r--arch/um/sys-i386/Makefile2
-rw-r--r--arch/um/sys-i386/delay.c14
-rw-r--r--arch/um/sys-i386/ldt.c14
-rw-r--r--arch/um/sys-i386/ptrace.c24
-rw-r--r--arch/um/sys-i386/sigcontext.c3
-rw-r--r--arch/um/sys-i386/signal.c2
-rw-r--r--arch/um/sys-i386/syscalls.c134
-rw-r--r--arch/um/sys-x86_64/Makefile39
-rw-r--r--arch/um/sys-x86_64/bugs.c122
-rw-r--r--arch/um/sys-x86_64/delay.c26
-rw-r--r--arch/um/sys-x86_64/fault.c23
-rw-r--r--arch/um/sys-x86_64/mem.c25
-rw-r--r--arch/um/sys-x86_64/ptrace.c138
-rw-r--r--arch/um/sys-x86_64/ptrace_user.c64
-rw-r--r--arch/um/sys-x86_64/sigcontext.c39
-rw-r--r--arch/um/sys-x86_64/signal.c276
-rw-r--r--arch/um/sys-x86_64/syscalls.c191
-rw-r--r--arch/um/sys-x86_64/sysrq.c49
-rw-r--r--arch/um/sys-x86_64/util/Makefile10
-rw-r--r--arch/um/sys-x86_64/util/mk_sc.c58
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_kern.c21
-rw-r--r--arch/um/sys-x86_64/util/mk_thread_user.c30
-rw-r--r--arch/x86_64/Kconfig2
-rw-r--r--arch/x86_64/Makefile2
-rw-r--r--arch/x86_64/defconfig120
-rw-r--r--arch/x86_64/ia32/ia32_aout.c12
-rw-r--r--arch/x86_64/ia32/ia32_signal.c6
-rw-r--r--arch/x86_64/ia32/ia32entry.S4
-rw-r--r--arch/x86_64/kernel/aperture.c14
-rw-r--r--arch/x86_64/kernel/apic.c5
-rw-r--r--arch/x86_64/kernel/genapic.c7
-rw-r--r--arch/x86_64/kernel/head.S2
-rw-r--r--arch/x86_64/kernel/head64.c13
-rw-r--r--arch/x86_64/kernel/io_apic.c7
-rw-r--r--arch/x86_64/kernel/mce.c18
-rw-r--r--arch/x86_64/kernel/mpparse.c11
-rw-r--r--arch/x86_64/kernel/setup.c59
-rw-r--r--arch/x86_64/kernel/signal.c8
-rw-r--r--arch/x86_64/lib/io.c8
-rw-r--r--arch/x86_64/lib/old-checksum.c33
-rw-r--r--arch/x86_64/mm/init.c54
-rw-r--r--arch/x86_64/mm/ioremap.c10
-rw-r--r--arch/x86_64/mm/k8topology.c23
-rw-r--r--arch/x86_64/mm/numa.c10
-rw-r--r--arch/x86_64/mm/pageattr.c26
-rw-r--r--arch/x86_64/mm/srat.c19
181 files changed, 4383 insertions, 1560 deletions
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig
index cae9d38b5c9f18..674791c81502fe 100644
--- a/arch/i386/Kconfig
+++ b/arch/i386/Kconfig
@@ -519,7 +519,7 @@ config PREEMPT
config PREEMPT_BKL
bool "Preempt The Big Kernel Lock"
- depends on PREEMPT || SMP
+ depends on PREEMPT
default y
help
This option reduces the latency of the kernel by making the
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index df8900b1f1670a..406f5a93d01b8c 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -877,23 +877,18 @@ static unsigned int __init get_8254_timer_count(void)
/* next tick in 8254 can be caught by catching timer wraparound */
static void __init wait_8254_wraparound(void)
{
- unsigned int curr_count, prev_count=~0;
- int delta;
+ unsigned int curr_count, prev_count;
curr_count = get_8254_timer_count();
-
do {
prev_count = curr_count;
curr_count = get_8254_timer_count();
- delta = curr_count-prev_count;
- /*
- * This limit for delta seems arbitrary, but it isn't, it's
- * slightly above the level of error a buggy Mercury/Neptune
- * chipset timer can cause.
- */
+ /* workaround for broken Mercury/Neptune */
+ if (prev_count >= curr_count + 0x100)
+ curr_count = get_8254_timer_count();
- } while (delta < 300);
+ } while (prev_count >= curr_count);
}
/*
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c
index 091b98ae93b672..ae94585d044513 100644
--- a/arch/i386/kernel/cpu/amd.c
+++ b/arch/i386/kernel/cpu/amd.c
@@ -188,6 +188,23 @@ static void __init init_amd(struct cpuinfo_x86 *c)
}
display_cacheinfo(c);
+ detect_ht(c);
+
+#ifdef CONFIG_X86_HT
+ /* AMD dual core looks like HT but isn't really. Hide it from the
+ scheduler. This works around problems with the domain scheduler.
+ Also probably gives slightly better scheduling and disables
+ SMT nice which is harmful on dual core.
+ TBD tune the domain scheduler for dual core. */
+ if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
+ smp_num_siblings = 1;
+#endif
+
+ if (cpuid_eax(0x80000000) >= 0x80000008) {
+ c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+ if (c->x86_num_cores & (c->x86_num_cores - 1))
+ c->x86_num_cores = 1;
+ }
}
static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c
index aef962cac86202..b619be984d5a88 100644
--- a/arch/i386/kernel/cpu/common.c
+++ b/arch/i386/kernel/cpu/common.c
@@ -10,6 +10,11 @@
#include <asm/msr.h>
#include <asm/io.h>
#include <asm/mmu_context.h>
+#ifdef CONFIG_X86_LOCAL_APIC
+#include <asm/mpspec.h>
+#include <asm/apic.h>
+#include <mach_apic.h>
+#endif
#include "cpu.h"
@@ -274,8 +279,10 @@ void __init generic_identify(struct cpuinfo_x86 * c)
/* AMD-defined flags: level 0x80000001 */
xlvl = cpuid_eax(0x80000000);
if ( (xlvl & 0xffff0000) == 0x80000000 ) {
- if ( xlvl >= 0x80000001 )
+ if ( xlvl >= 0x80000001 ) {
c->x86_capability[1] = cpuid_edx(0x80000001);
+ c->x86_capability[6] = cpuid_ecx(0x80000001);
+ }
if ( xlvl >= 0x80000004 )
get_model_name(c); /* Default name */
}
@@ -321,6 +328,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
c->x86_model = c->x86_mask = 0; /* So far unknown... */
c->x86_vendor_id[0] = '\0'; /* Unset */
c->x86_model_id[0] = '\0'; /* Unset */
+ c->x86_num_cores = 1;
memset(&c->x86_capability, 0, sizeof c->x86_capability);
if (!have_cpuid_p()) {
@@ -429,6 +437,50 @@ void __init dodgy_tsc(void)
cpu_devs[X86_VENDOR_CYRIX]->c_init(&boot_cpu_data);
}
+#ifdef CONFIG_X86_HT
+void __init detect_ht(struct cpuinfo_x86 *c)
+{
+ u32 eax, ebx, ecx, edx;
+ int index_lsb, index_msb, tmp;
+ int cpu = smp_processor_id();
+
+ if (!cpu_has(c, X86_FEATURE_HT))
+ return;
+
+ cpuid(1, &eax, &ebx, &ecx, &edx);
+ smp_num_siblings = (ebx & 0xff0000) >> 16;
+
+ if (smp_num_siblings == 1) {
+ printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
+ } else if (smp_num_siblings > 1 ) {
+ index_lsb = 0;
+ index_msb = 31;
+
+ if (smp_num_siblings > NR_CPUS) {
+ printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
+ smp_num_siblings = 1;
+ return;
+ }
+ tmp = smp_num_siblings;
+ while ((tmp & 1) == 0) {
+ tmp >>=1 ;
+ index_lsb++;
+ }
+ tmp = smp_num_siblings;
+ while ((tmp & 0x80000000 ) == 0) {
+ tmp <<=1 ;
+ index_msb--;
+ }
+ if (index_lsb != index_msb )
+ index_msb++;
+ phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
+
+ printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
+ phys_proc_id[cpu]);
+ }
+}
+#endif
+
void __init print_cpu_info(struct cpuinfo_x86 *c)
{
char *vendor = NULL;
diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c
index eb145ed88d6a55..b8d847b850dc66 100644
--- a/arch/i386/kernel/cpu/intel.c
+++ b/arch/i386/kernel/cpu/intel.c
@@ -139,50 +139,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
if ( p )
strcpy(c->x86_model_id, p);
-#ifdef CONFIG_X86_HT
- if (cpu_has(c, X86_FEATURE_HT)) {
- extern int phys_proc_id[NR_CPUS];
-
- u32 eax, ebx, ecx, edx;
- int index_lsb, index_msb, tmp;
- int cpu = smp_processor_id();
-
- cpuid(1, &eax, &ebx, &ecx, &edx);
- smp_num_siblings = (ebx & 0xff0000) >> 16;
-
- if (smp_num_siblings == 1) {
- printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
- } else if (smp_num_siblings > 1 ) {
- index_lsb = 0;
- index_msb = 31;
-
- if (smp_num_siblings > NR_CPUS) {
- printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
- smp_num_siblings = 1;
- goto too_many_siblings;
- }
- tmp = smp_num_siblings;
- while ((tmp & 1) == 0) {
- tmp >>=1 ;
- index_lsb++;
- }
- tmp = smp_num_siblings;
- while ((tmp & 0x80000000 ) == 0) {
- tmp <<=1 ;
- index_msb--;
- }
- if (index_lsb != index_msb )
- index_msb++;
- phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
-
- printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
- phys_proc_id[cpu]);
- }
-
- }
-too_many_siblings:
-
-#endif
+ detect_ht(c);
/* Work around errata */
Intel_errata_workarounds(c);
diff --git a/arch/i386/kernel/cpu/proc.c b/arch/i386/kernel/cpu/proc.c
index 4ba834c44ea523..c8d83fdc237a35 100644
--- a/arch/i386/kernel/cpu/proc.c
+++ b/arch/i386/kernel/cpu/proc.c
@@ -28,7 +28,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
"pni", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, "syscall", NULL, NULL, NULL, NULL,
NULL, NULL, NULL, "mp", "nx", NULL, "mmxext", NULL,
- NULL, NULL, NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
+ NULL, "fxsr_opt", NULL, NULL, NULL, "lm", "3dnowext", "3dnow",
/* Transmeta-defined */
"recovery", "longrun", NULL, "lrti", NULL, NULL, NULL, NULL,
@@ -45,7 +45,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
/* Intel-defined (#2) */
"pni", NULL, NULL, "monitor", "ds_cpl", NULL, NULL, "est",
- "tm2", NULL, "cid", NULL, NULL, NULL, "xtpr", NULL,
+ "tm2", NULL, "cid", NULL, NULL, "cx16", "xtpr", NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -54,6 +54,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+
+ /* AMD-defined (#2) */
+ "lahf_lm", "cmp_legacy", NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
};
struct cpuinfo_x86 *c = v;
int i, n = c - cpu_data;
@@ -88,11 +94,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
if (c->x86_cache_size >= 0)
seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size);
#ifdef CONFIG_X86_HT
- if (smp_num_siblings > 1) {
- extern int phys_proc_id[NR_CPUS];
- seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
- seq_printf(m, "siblings\t: %d\n", smp_num_siblings);
- }
+ seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
+ seq_printf(m, "siblings\t: %d\n", c->x86_num_cores * smp_num_siblings);
#endif
/* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index b9eb1a95bb53d9..1879a89d00acaf 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -86,15 +86,28 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
* Interrupts are disabled on entry as trap3 is an interrupt gate and they
* remain disabled thorough out this function.
*/
-static inline int kprobe_handler(struct pt_regs *regs)
+static int kprobe_handler(struct pt_regs *regs)
{
struct kprobe *p;
int ret = 0;
- u8 *addr = (u8 *) (regs->eip - 1);
+ kprobe_opcode_t *addr = NULL;
+ unsigned long *lp;
/* We're in an interrupt, but this is clear and BUG()-safe. */
preempt_disable();
-
+ /* Check if the application is using LDT entry for its code segment and
+ * calculate the address by reading the base address from the LDT entry.
+ */
+ if ((regs->xcs & 4) && (current->mm)) {
+ lp = (unsigned long *) ((unsigned long)((regs->xcs >> 3) * 8)
+ + (char *) current->mm->context.ldt);
+ addr = (kprobe_opcode_t *) ((((*lp) >> 16 & 0x0000ffff)
+ | (*(lp +1) & 0xff000000)
+ | ((*(lp +1) << 16) & 0x00ff0000))
+ + regs->eip - sizeof(kprobe_opcode_t));
+ } else {
+ addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
+ }
/* Check we're not actually recursing */
if (kprobe_running()) {
/* We *are* holding lock here, so this is safe.
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 51c4bfc53c938e..f98146004f5e1d 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -190,6 +190,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
+ } else {
+ struct task_struct *me = current;
+ if (me->used_math) {
+ clear_fpu(me);
+ me->used_math = 0;
+ }
}
}
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index caa3d1315a7479..d1ced13320d002 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -61,6 +61,7 @@ static int __initdata smp_b_stepping;
/* Number of siblings per CPU package */
int smp_num_siblings = 1;
int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */
+EXPORT_SYMBOL(phys_proc_id);
/* bitmap of online cpus */
cpumask_t cpu_online_map;
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index 1aa488b7f99917..58ff04eeb9dbc0 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -157,7 +157,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
/*
* Ok, go for it..
*/
- area = get_vm_area(size, VM_IOREMAP);
+ area = get_vm_area(size, VM_IOREMAP | (flags << 20));
if (!area)
return NULL;
area->phys_addr = phys_addr;
@@ -235,9 +235,9 @@ void iounmap(volatile void __iomem *addr)
if (!p) {
printk("__iounmap: bad address %p\n", addr);
return;
- }
+ }
- if (p->flags && p->phys_addr < virt_to_phys(high_memory) - 1) {
+ if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) {
change_page_attr(virt_to_page(__va(p->phys_addr)),
p->size >> PAGE_SHIFT,
PAGE_KERNEL);
diff --git a/arch/i386/mm/pageattr.c b/arch/i386/mm/pageattr.c
index 7647cde233a798..46c86395fe40d9 100644
--- a/arch/i386/mm/pageattr.c
+++ b/arch/i386/mm/pageattr.c
@@ -120,27 +120,35 @@ __change_page_attr(struct page *page, pgprot_t prot)
kpte_page = virt_to_page(kpte);
if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) {
if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
- pte_t old = *kpte;
- pte_t standard = mk_pte(page, PAGE_KERNEL);
set_pte_atomic(kpte, mk_pte(page, prot));
- if (pte_same(old,standard))
- get_page(kpte_page);
} else {
struct page *split = split_large_page(address, prot);
if (!split)
return -ENOMEM;
- get_page(kpte_page);
set_pmd_pte(kpte,address,mk_pte(split, PAGE_KERNEL));
+ kpte_page = split;
}
+ get_page(kpte_page);
} else if ((pte_val(*kpte) & _PAGE_PSE) == 0) {
set_pte_atomic(kpte, mk_pte(page, PAGE_KERNEL));
__put_page(kpte_page);
- }
+ } else
+ BUG();
- if (cpu_has_pse && (page_count(kpte_page) == 1)) {
- list_add(&kpte_page->lru, &df_list);
- revert_page(kpte_page, address);
- }
+ /*
+ * If the pte was reserved, it means it was created at boot
+ * time (not via split_large_page) and in turn we must not
+ * replace it with a largepage.
+ */
+ if (!PageReserved(kpte_page)) {
+ /* memleak and potential failed 2M page regeneration */
+ BUG_ON(!page_count(kpte_page));
+
+ if (cpu_has_pse && (page_count(kpte_page) == 1)) {
+ list_add(&kpte_page->lru, &df_list);
+ revert_page(kpte_page, address);
+ }
+ }
return 0;
}
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c
index 27cf192061c2e2..af18331b3fb294 100644
--- a/arch/i386/pci/fixup.c
+++ b/arch/i386/pci/fixup.c
@@ -227,10 +227,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_
*/
static void __init pci_fixup_nforce2(struct pci_dev *dev)
{
- u32 val, fixed_val;
- u8 rev;
-
- pci_read_config_byte(dev, PCI_REVISION_ID, &rev);
+ u32 val;
/*
* Chip Old value New value
@@ -240,17 +237,14 @@ static void __init pci_fixup_nforce2(struct pci_dev *dev)
* Northbridge chip version may be determined by
* reading the PCI revision ID (0xC1 or greater is C18D).
*/
- fixed_val = rev < 0xC1 ? 0x1F01FF01 : 0x9F01FF01;
-
pci_read_config_dword(dev, 0x6c, &val);
/*
- * Apply fixup only if C1 Halt Disconnect is enabled
- * (bit28) because it is not supported on some boards.
+ * Apply fixup if needed, but don't touch disconnect state
*/
- if ((val & (1 << 28)) && val != fixed_val) {
+ if ((val & 0x00FF0000) != 0x00010000) {
printk(KERN_WARNING "PCI: nForce2 C1 Halt Disconnect fixup\n");
- pci_write_config_dword(dev, 0x6c, fixed_val);
+ pci_write_config_dword(dev, 0x6c, (val & 0xFF00FFFF) | 0x00010000);
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 42800941f17cf5..52951437d9d3b5 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -377,6 +377,7 @@ void pcibios_resource_to_bus(struct pci_dev *dev,
region->start = res->start - offset;
region->end = res->end - offset;
}
+EXPORT_SYMBOL(pcibios_resource_to_bus);
void pcibios_bus_to_resource(struct pci_dev *dev,
struct resource *res, struct pci_bus_region *region)
diff --git a/arch/m32r/mm/init.c b/arch/m32r/mm/init.c
index 736c8d86f64b93..ec968e453f79a1 100644
--- a/arch/m32r/mm/init.c
+++ b/arch/m32r/mm/init.c
@@ -9,8 +9,6 @@
* Copyright (C) 1995 Linus Torvalds
*/
-/* $Id$ */
-
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -19,6 +17,7 @@
#include <linux/swap.h>
#include <linux/highmem.h>
#include <linux/bitops.h>
+#include <linux/nodemask.h>
#include <asm/types.h>
#include <asm/processor.h>
#include <asm/page.h>
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index aee1f399e15b95..43c254299e4a73 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -127,7 +127,9 @@ static void set_brk(unsigned long start, unsigned long end)
end = PAGE_ALIGN(end);
if (end <= start)
return;
+ down_write(&current->mm->mmap_sem);
do_brk(start, end - start);
+ up_write(&current->mm->mmap_sem);
}
@@ -375,7 +377,9 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
/* Map the last of the bss segment */
if (last_bss > len) {
+ down_write(&current->mm->mmap_sem);
do_brk(len, (last_bss - len));
+ up_write(&current->mm->mmap_sem);
}
kfree(elf_phdata);
@@ -562,7 +566,9 @@ void irix_map_prda_page (void)
unsigned long v;
struct prda *pp;
+ down_write(&current->mm->mmap_sem);
v = do_brk (PRDA_ADDRESS, PAGE_SIZE);
+ up_write(&current->mm->mmap_sem);
if (v < 0)
return;
@@ -852,8 +858,11 @@ static int load_irix_library(struct file *file)
len = (elf_phdata->p_filesz + elf_phdata->p_vaddr+ 0xfff) & 0xfffff000;
bss = elf_phdata->p_memsz + elf_phdata->p_vaddr;
- if (bss > len)
+ if (bss > len) {
+ down_write(&current->mm->mmap_sem);
do_brk(len, bss-len);
+ up_write(&current->mm->mmap_sem);
+ }
kfree(elf_phdata);
return 0;
}
diff --git a/arch/parisc/kernel/binfmt_elf32.c b/arch/parisc/kernel/binfmt_elf32.c
index 4486a745b0ef25..6fd07e90aad76b 100644
--- a/arch/parisc/kernel/binfmt_elf32.c
+++ b/arch/parisc/kernel/binfmt_elf32.c
@@ -92,10 +92,12 @@ struct elf_prpsinfo32
current->thread.map_base = DEFAULT_MAP_BASE32; \
current->thread.task_size = DEFAULT_TASK_SIZE32 \
-#define jiffies_to_timeval jiffies_to_compat_timeval
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
{
+ unsigned long jiffies = cputime_to_jiffies(cputime);
value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
value->tv_sec = jiffies / HZ;
}
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index 53547b6de45bd4..ddad50b0129841 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -41,14 +41,17 @@ void default_idle(void)
if (!need_resched()) {
if (powersave != NULL)
powersave();
-#ifdef CONFIG_SMP
else {
+#ifdef CONFIG_SMP
set_thread_flag(TIF_POLLING_NRFLAG);
+ local_irq_enable();
while (!need_resched())
barrier();
clear_thread_flag(TIF_POLLING_NRFLAG);
- }
+#else
+ local_irq_enable();
#endif
+ }
}
if (need_resched())
schedule();
diff --git a/arch/ppc/kernel/perfmon.c b/arch/ppc/kernel/perfmon.c
index 88452272cc9361..cbb29e6f490202 100644
--- a/arch/ppc/kernel/perfmon.c
+++ b/arch/ppc/kernel/perfmon.c
@@ -47,7 +47,6 @@ static void dummy_perf(struct pt_regs *regs)
#else
/* Ensure exceptions are disabled */
-#define MMCR0_PMXE (1UL << (31 - 5))
static void dummy_perf(struct pt_regs *regs)
{
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index e69bc4e94297a1..6e31db0fe4b468 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -31,6 +31,7 @@
#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/initrd.h>
+#include <linux/pagemap.h>
#include <asm/pgalloc.h>
#include <asm/prom.h>
diff --git a/arch/ppc64/kernel/binfmt_elf32.c b/arch/ppc64/kernel/binfmt_elf32.c
index 478e5fce6be174..fadc699a0497c8 100644
--- a/arch/ppc64/kernel/binfmt_elf32.c
+++ b/arch/ppc64/kernel/binfmt_elf32.c
@@ -60,10 +60,12 @@ struct elf_prpsinfo32
#include <linux/time.h>
-#define jiffies_to_timeval jiffies_to_compat_timeval
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
{
+ unsigned long jiffies = cputime_to_jiffies(cputime);
value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
value->tv_sec = jiffies / HZ;
}
diff --git a/arch/ppc64/kernel/kprobes.c b/arch/ppc64/kernel/kprobes.c
index f136d3d8a9479e..677f6272fc2941 100644
--- a/arch/ppc64/kernel/kprobes.c
+++ b/arch/ppc64/kernel/kprobes.c
@@ -99,6 +99,7 @@ static inline int kprobe_handler(struct pt_regs *regs)
p = get_kprobe(addr);
if (!p) {
unlock_kprobes();
+#if 0
if (*addr != BREAKPOINT_INSTRUCTION) {
/*
* The breakpoint instruction was removed right
@@ -109,6 +110,7 @@ static inline int kprobe_handler(struct pt_regs *regs)
*/
ret = 1;
}
+#endif
/* Not one of ours: let kernel handle it */
goto no_kprobe;
}
diff --git a/arch/ppc64/kernel/maple_pci.c b/arch/ppc64/kernel/maple_pci.c
index f8cd5b495d6b0b..53993999b265ac 100644
--- a/arch/ppc64/kernel/maple_pci.c
+++ b/arch/ppc64/kernel/maple_pci.c
@@ -382,9 +382,6 @@ void __init maple_pcibios_fixup(void)
/* Do the mapping of the IO space */
phbs_remap_io();
- /* Fixup the pci_bus sysdata pointers */
- pci_fix_bus_sysdata();
-
DBG(" <- maple_pcibios_fixup\n");
}
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S
index a795ae320b371a..1502b814a55895 100644
--- a/arch/ppc64/kernel/misc.S
+++ b/arch/ppc64/kernel/misc.S
@@ -167,27 +167,7 @@ _GLOBAL(call_with_mmu_off)
xori r0,r0,MSR_IR|MSR_DR
mtspr SPRN_SRR1,r0
rfid
-
-/*
- * Flush instruction cache.
- */
-_GLOBAL(flush_instruction_cache)
-/*
- * This is called by kgdb code
- * and should probably go away
- * to be replaced by invalidating
- * the cache lines that are actually
- * modified
- */
- /* use invalidate-all bit in HID0
- * - is this consistent across all 64-bit cpus? -- paulus */
- mfspr r3,HID0
- ori r3,r3,HID0_ICFI
- mtspr HID0,r3
- sync
- isync
- blr
.section ".toc","aw"
PPC64_CACHES:
diff --git a/arch/ppc64/kernel/pSeries_pci.c b/arch/ppc64/kernel/pSeries_pci.c
index 2b9a00951f2070..8953e94889bab4 100644
--- a/arch/ppc64/kernel/pSeries_pci.c
+++ b/arch/ppc64/kernel/pSeries_pci.c
@@ -552,7 +552,6 @@ void __init pSeries_final_fixup(void)
phbs_remap_io();
pSeries_request_regions();
- pci_fix_bus_sysdata();
pci_addr_cache_build();
}
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c
index d03c4716400171..f8f2007b888505 100644
--- a/arch/ppc64/kernel/pSeries_smp.c
+++ b/arch/ppc64/kernel/pSeries_smp.c
@@ -19,9 +19,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
@@ -40,7 +38,6 @@
#include <asm/smp.h>
#include <asm/paca.h>
#include <asm/time.h>
-#include <asm/ppcdebug.h>
#include <asm/machdep.h>
#include <asm/xics.h>
#include <asm/cputable.h>
@@ -87,11 +84,8 @@ static int query_cpu_stopped(unsigned int pcpu)
#ifdef CONFIG_HOTPLUG_CPU
-int __cpu_disable(void)
+int pSeries_cpu_disable(void)
{
- /* FIXME: go put this in a header somewhere */
- extern void xics_migrate_irqs_away(void);
-
systemcfg->processorCount--;
/*fix boot_cpuid here*/
@@ -103,7 +97,7 @@ int __cpu_disable(void)
return 0;
}
-void __cpu_die(unsigned int cpu)
+void pSeries_cpu_die(unsigned int cpu)
{
int tries;
int cpu_status;
@@ -250,8 +244,6 @@ static void smp_xics_message_pass(int target, int msg)
}
}
-extern void xics_request_IPIs(void);
-
static int __init smp_xics_probe(void)
{
xics_request_IPIs();
@@ -263,6 +255,19 @@ static void __devinit smp_xics_setup_cpu(int cpu)
{
if (cpu != boot_cpuid)
xics_setup_cpu();
+
+ if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
+ vpa_init(cpu);
+
+#ifdef CONFIG_IRQ_ALL_CPUS
+ /*
+ * Put the calling processor into the GIQ. This is really only
+ * necessary from a secondary thread as the OF start-cpu interface
+ * performs this function for us on primary threads.
+ */
+ rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+ (1UL << interrupt_server_size) - 1 - default_distrib_server, 1);
+#endif
}
static spinlock_t timebase_lock = SPIN_LOCK_UNLOCKED;
@@ -290,26 +295,7 @@ static void __devinit pSeries_take_timebase(void)
spin_unlock(&timebase_lock);
}
-static void __devinit pSeries_late_setup_cpu(int cpu)
-{
- extern unsigned int default_distrib_server;
-
- if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR) {
- vpa_init(cpu);
- }
-
-#ifdef CONFIG_IRQ_ALL_CPUS
- /* Put the calling processor into the GIQ. This is really only
- * necessary from a secondary thread as the OF start-cpu interface
- * performs this function for us on primary threads.
- */
- /* TODO: 9005 is #defined in rtas-proc.c -- move to a header */
- rtas_set_indicator(9005, default_distrib_server, 1);
-#endif
-}
-
-
-void __devinit smp_pSeries_kick_cpu(int nr)
+static void __devinit smp_pSeries_kick_cpu(int nr)
{
BUG_ON(nr < 0 || nr >= NR_CPUS);
@@ -329,7 +315,6 @@ static struct smp_ops_t pSeries_mpic_smp_ops = {
.probe = smp_mpic_probe,
.kick_cpu = smp_pSeries_kick_cpu,
.setup_cpu = smp_mpic_setup_cpu,
- .late_setup_cpu = pSeries_late_setup_cpu,
};
static struct smp_ops_t pSeries_xics_smp_ops = {
@@ -337,7 +322,6 @@ static struct smp_ops_t pSeries_xics_smp_ops = {
.probe = smp_xics_probe,
.kick_cpu = smp_pSeries_kick_cpu,
.setup_cpu = smp_xics_setup_cpu,
- .late_setup_cpu = pSeries_late_setup_cpu,
};
/* This is called very early */
@@ -352,6 +336,11 @@ void __init smp_init_pSeries(void)
else
smp_ops = &pSeries_xics_smp_ops;
+#ifdef CONFIG_HOTPLUG_CPU
+ smp_ops->cpu_disable = pSeries_cpu_disable;
+ smp_ops->cpu_die = pSeries_cpu_die;
+#endif
+
/* Start secondary threads on SMT systems; primary threads
* are already in the running state.
*/
@@ -367,9 +356,6 @@ void __init smp_init_pSeries(void)
}
}
- if (cur_cpu_spec->firmware_features & FW_FEATURE_SPLPAR)
- vpa_init(boot_cpuid);
-
/* Non-lpar has additional take/give timebase */
if (rtas_token("freeze-time-base") != RTAS_UNKNOWN_SERVICE) {
smp_ops->give_timebase = pSeries_give_timebase;
diff --git a/arch/ppc64/kernel/pacaData.c b/arch/ppc64/kernel/pacaData.c
index 206c52d8ca66f7..0b18d17b94d4c5 100644
--- a/arch/ppc64/kernel/pacaData.c
+++ b/arch/ppc64/kernel/pacaData.c
@@ -78,13 +78,16 @@ struct paca_struct paca[] = {
#else
PACAINITDATA( 0, 1, NULL, STAB0_PHYS_ADDR, STAB0_VIRT_ADDR),
#endif
+#if NR_CPUS > 1
PACAINITDATA( 1, 0, NULL, 0, 0),
PACAINITDATA( 2, 0, NULL, 0, 0),
PACAINITDATA( 3, 0, NULL, 0, 0),
+#if NR_CPUS > 4
PACAINITDATA( 4, 0, NULL, 0, 0),
PACAINITDATA( 5, 0, NULL, 0, 0),
PACAINITDATA( 6, 0, NULL, 0, 0),
PACAINITDATA( 7, 0, NULL, 0, 0),
+#if NR_CPUS > 8
PACAINITDATA( 8, 0, NULL, 0, 0),
PACAINITDATA( 9, 0, NULL, 0, 0),
PACAINITDATA(10, 0, NULL, 0, 0),
@@ -209,4 +212,7 @@ struct paca_struct paca[] = {
PACAINITDATA(127, 0, NULL, 0, 0),
#endif
#endif
+#endif
+#endif
+#endif
};
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c
index 25822272542e30..a7bf62655601b8 100644
--- a/arch/ppc64/kernel/pci.c
+++ b/arch/ppc64/kernel/pci.c
@@ -91,7 +91,7 @@ void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region
struct resource *res)
{
unsigned long offset = 0;
- struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
if (!hose)
return;
@@ -127,7 +127,7 @@ void pcibios_align_resource(void *data, struct resource *res,
unsigned long size, unsigned long align)
{
struct pci_dev *dev = data;
- struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
unsigned long start = res->start;
unsigned long alignto;
@@ -292,7 +292,7 @@ int pci_domain_nr(struct pci_bus *bus)
#ifdef CONFIG_PPC_ISERIES
return 0;
#else
- struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+ struct pci_controller *hose = pci_bus_to_host(bus);
return hose->global_number;
#endif
@@ -304,7 +304,7 @@ EXPORT_SYMBOL(pci_domain_nr);
int pci_name_bus(char *name, struct pci_bus *bus)
{
#ifndef CONFIG_PPC_ISERIES
- struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+ struct pci_controller *hose = pci_bus_to_host(bus);
if (hose->buid)
sprintf(name, "%04x:%02x", pci_domain_nr(bus), bus->number);
@@ -336,7 +336,7 @@ static __inline__ int __pci_mmap_make_offset(struct pci_dev *dev,
struct vm_area_struct *vma,
enum pci_mmap_state mmap_state)
{
- struct pci_controller *hose = PCI_GET_PHB_PTR(dev);
+ struct pci_controller *hose = pci_bus_to_host(dev->bus);
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
unsigned long io_offset = 0;
int i, res_bit;
@@ -643,7 +643,7 @@ void __devinit pci_setup_phb_io_dynamic(struct pci_controller *hose)
static int get_bus_io_range(struct pci_bus *bus, unsigned long *start_phys,
unsigned long *start_virt, unsigned long *size)
{
- struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+ struct pci_controller *hose = pci_bus_to_host(bus);
struct pci_bus_region region;
struct resource *res;
@@ -728,23 +728,6 @@ void phbs_remap_io(void)
remap_bus_range(hose->bus);
}
-
-/*
- * This function finds the PHB that matching device_node in the
- * OpenFirmware by scanning all the pci_controllers.
- */
-struct pci_controller* pci_find_hose_for_OF_device(struct device_node *node)
-{
- while (node) {
- struct pci_controller *hose, *tmp;
- list_for_each_entry_safe(hose, tmp, &hose_list, list_node)
- if (hose->arch_data == node)
- return hose;
- node=node->parent;
- }
- return NULL;
-}
-
/*
* ppc64 can have multifunction devices that do not respond to function 0.
* In this case we must scan all functions.
@@ -778,7 +761,7 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
struct pci_bus *bus)
{
/* Update device resources. */
- struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+ struct pci_controller *hose = pci_bus_to_host(bus);
int i;
for (i = 0; i < PCI_NUM_RESOURCES; i++) {
@@ -814,7 +797,7 @@ EXPORT_SYMBOL(pcibios_fixup_device_resources);
void __devinit pcibios_fixup_bus(struct pci_bus *bus)
{
- struct pci_controller *hose = PCI_GET_PHB_PTR(bus);
+ struct pci_controller *hose = pci_bus_to_host(bus);
struct pci_dev *dev = bus->self;
struct resource *res;
int i;
diff --git a/arch/ppc64/kernel/pci.h b/arch/ppc64/kernel/pci.h
index 2ed6b674bbca21..28517c14015b92 100644
--- a/arch/ppc64/kernel/pci.h
+++ b/arch/ppc64/kernel/pci.h
@@ -17,7 +17,6 @@ extern unsigned long isa_io_base;
extern void pci_setup_pci_controller(struct pci_controller *hose);
extern void pci_setup_phb_io(struct pci_controller *hose, int primary);
-extern struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node);
extern void pci_setup_phb_io_dynamic(struct pci_controller *hose);
@@ -36,11 +35,8 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
void pci_devs_phb_init(void);
void pci_devs_phb_init_dynamic(struct pci_controller *phb);
-void pci_fix_bus_sysdata(void);
struct device_node *fetch_dev_dn(struct pci_dev *dev);
-#define PCI_GET_PHB_PTR(dev) (((struct device_node *)(dev)->sysdata)->phb)
-
/* PCI address cache management routines */
void pci_addr_cache_insert_device(struct pci_dev *dev);
void pci_addr_cache_remove_device(struct pci_dev *dev);
diff --git a/arch/ppc64/kernel/pci_dn.c b/arch/ppc64/kernel/pci_dn.c
index 962394708ece6e..280b744fe64e3a 100644
--- a/arch/ppc64/kernel/pci_dn.c
+++ b/arch/ppc64/kernel/pci_dn.c
@@ -21,19 +21,12 @@
*/
#include <linux/kernel.h>
#include <linux/pci.h>
-#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/bootmem.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
-#include <asm/irq.h>
#include <asm/prom.h>
-#include <asm/machdep.h>
#include <asm/pci-bridge.h>
-#include <asm/ppcdebug.h>
-#include <asm/iommu.h>
#include "pci.h"
@@ -178,29 +171,3 @@ void __init pci_devs_phb_init(void)
list_for_each_entry_safe(phb, tmp, &hose_list, list_node)
pci_devs_phb_init_dynamic(phb);
}
-
-
-static void __init pci_fixup_bus_sysdata_list(struct list_head *bus_list)
-{
- struct pci_bus *bus;
-
- list_for_each_entry(bus, bus_list, node) {
- if (bus->self)
- bus->sysdata = bus->self->sysdata;
- pci_fixup_bus_sysdata_list(&bus->children);
- }
-}
-
-/*
- * Fixup the bus->sysdata ptrs to point to the bus' device_node.
- * This is done late in pcibios_init(). We do this mostly for
- * sanity, but pci_dma.c uses these at DMA time so they must be
- * correct.
- * To do this we recurse down the bus hierarchy. Note that PHB's
- * have bus->self == NULL, but fortunately bus->sysdata is already
- * correct in this case.
- */
-void __init pci_fix_bus_sysdata(void)
-{
- pci_fixup_bus_sysdata_list(&pci_root_buses);
-}
diff --git a/arch/ppc64/kernel/pmac_pci.c b/arch/ppc64/kernel/pmac_pci.c
index 32634216ad78f6..00a831df6d9f10 100644
--- a/arch/ppc64/kernel/pmac_pci.c
+++ b/arch/ppc64/kernel/pmac_pci.c
@@ -664,8 +664,6 @@ void __init pmac_pcibios_fixup(void)
for_each_pci_dev(dev)
pci_read_irq_line(dev);
-
- pci_fix_bus_sysdata();
}
static void __init pmac_fixup_phb_resources(void)
diff --git a/arch/ppc64/kernel/ppc_ksyms.c b/arch/ppc64/kernel/ppc_ksyms.c
index 7efdaabf5b7b8e..38c0398d823cc8 100644
--- a/arch/ppc64/kernel/ppc_ksyms.c
+++ b/arch/ppc64/kernel/ppc_ksyms.c
@@ -114,7 +114,6 @@ EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(kernel_thread);
-EXPORT_SYMBOL(flush_instruction_cache);
EXPORT_SYMBOL(giveup_fpu);
#ifdef CONFIG_ALTIVEC
EXPORT_SYMBOL(giveup_altivec);
diff --git a/arch/ppc64/kernel/process.c b/arch/ppc64/kernel/process.c
index e647e7bc95c18f..d90a50e456696f 100644
--- a/arch/ppc64/kernel/process.c
+++ b/arch/ppc64/kernel/process.c
@@ -214,23 +214,57 @@ struct task_struct *__switch_to(struct task_struct *prev,
return last;
}
+static int instructions_to_print = 16;
+
+static void show_instructions(struct pt_regs *regs)
+{
+ int i;
+ unsigned long pc = regs->nip - (instructions_to_print * 3 / 4 *
+ sizeof(int));
+
+ printk("Instruction dump:");
+
+ for (i = 0; i < instructions_to_print; i++) {
+ int instr;
+
+ if (!(i % 8))
+ printk("\n");
+
+ if (((REGION_ID(pc) != KERNEL_REGION_ID) &&
+ (REGION_ID(pc) != VMALLOC_REGION_ID)) ||
+ __get_user(instr, (unsigned int *)pc)) {
+ printk("XXXXXXXX ");
+ } else {
+ if (regs->nip == pc)
+ printk("<%08x> ", instr);
+ else
+ printk("%08x ", instr);
+ }
+
+ pc += sizeof(int);
+ }
+
+ printk("\n");
+}
+
void show_regs(struct pt_regs * regs)
{
int i;
unsigned long trap;
- printk("NIP: %016lX XER: %016lX LR: %016lX\n",
- regs->nip, regs->xer, regs->link);
+ printk("NIP: %016lX XER: %08X LR: %016lX CTR: %016lX\n",
+ regs->nip, (unsigned int)regs->xer, regs->link, regs->ctr);
printk("REGS: %p TRAP: %04lx %s (%s)\n",
regs, regs->trap, print_tainted(), UTS_RELEASE);
- printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
+ printk("MSR: %016lx EE: %01x PR: %01x FP: %01x ME: %01x "
+ "IR/DR: %01x%01x CR: %08X\n",
regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
regs->msr&MSR_IR ? 1 : 0,
- regs->msr&MSR_DR ? 1 : 0);
+ regs->msr&MSR_DR ? 1 : 0,
+ (unsigned int)regs->ccr);
trap = TRAP(regs);
- if (trap == 0x300 || trap == 0x380 || trap == 0x600)
- printk("DAR: %016lx, DSISR: %016lx\n", regs->dar, regs->dsisr);
+ printk("DAR: %016lx DSISR: %016lx\n", regs->dar, regs->dsisr);
printk("TASK: %p[%d] '%s' THREAD: %p",
current, current->pid, current->comm, current->thread_info);
@@ -257,6 +291,8 @@ void show_regs(struct pt_regs * regs)
printk("LR [%016lx] ", regs->link);
print_symbol("%s\n", regs->link);
show_stack(current, (unsigned long *)regs->gpr[1]);
+ if (!user_mode(regs))
+ show_instructions(regs);
}
void exit_thread(void)
diff --git a/arch/ppc64/kernel/rtas-proc.c b/arch/ppc64/kernel/rtas-proc.c
index ed07210b9917df..28b1f1521f2165 100644
--- a/arch/ppc64/kernel/rtas-proc.c
+++ b/arch/ppc64/kernel/rtas-proc.c
@@ -52,7 +52,6 @@
#define IBM_VOLTAGE 0x232a /* 9002 */
#define IBM_DRCONNECTOR 0x232b /* 9003 */
#define IBM_POWERSUPPLY 0x232c /* 9004 */
-#define IBM_INTQUEUE 0x232d /* 9005 */
/* Status return values */
#define SENSOR_CRITICAL_HIGH 13
@@ -107,7 +106,6 @@
#define DR_ACTION 0x2329 /* 9001 */
#define DR_INDICATOR 0x232a /* 9002 */
/* 9003 - 9004: Vendor specific */
-#define GLOBAL_INTERRUPT_QUEUE 0x232d /* 9005 */
/* 9006 - 9999: Vendor specific */
/* other */
@@ -553,7 +551,6 @@ static void ppc_rtas_process_sensor(struct seq_file *m,
"No current flow" };
const char * ibm_drconnector[] = { "Empty", "Present", "Unusable",
"Exchange" };
- const char * ibm_intqueue[] = { "Disabled", "Enabled" };
int have_strings = 0;
int num_states = 0;
@@ -665,15 +662,6 @@ static void ppc_rtas_process_sensor(struct seq_file *m,
case IBM_POWERSUPPLY:
seq_printf(m, "Powersupply:\t");
break;
- case IBM_INTQUEUE:
- seq_printf(m, "Interrupt queue:\t");
- num_states = sizeof(ibm_intqueue) / sizeof(char *);
- if (state < num_states) {
- seq_printf(m, "%s\t",
- ibm_intqueue[state]);
- have_strings = 1;
- }
- break;
default:
seq_printf(m, "Unknown sensor (type %d), ignoring it\n",
s->token);
diff --git a/arch/ppc64/kernel/rtasd.c b/arch/ppc64/kernel/rtasd.c
index ade32f6a6d30a8..b5a96ec9f3bcd3 100644
--- a/arch/ppc64/kernel/rtasd.c
+++ b/arch/ppc64/kernel/rtasd.c
@@ -486,7 +486,7 @@ static int __init rtas_init(void)
/* No RTAS, only warn if we are on a pSeries box */
if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) {
- if (systemcfg->platform & PLATFORM_PSERIES);
+ if (systemcfg->platform & PLATFORM_PSERIES)
printk(KERN_ERR "rtasd: no event-scan on system\n");
return 1;
}
diff --git a/arch/ppc64/kernel/smp.c b/arch/ppc64/kernel/smp.c
index db78b2f03884de..f5b4a8f295815d 100644
--- a/arch/ppc64/kernel/smp.c
+++ b/arch/ppc64/kernel/smp.c
@@ -22,9 +22,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/smp.h>
-#include <linux/smp_lock.h>
#include <linux/interrupt.h>
-#include <linux/kernel_stat.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/spinlock.h>
@@ -38,12 +36,10 @@
#include <asm/irq.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-#include <asm/io.h>
#include <asm/prom.h>
#include <asm/smp.h>
#include <asm/paca.h>
#include <asm/time.h>
-#include <asm/ppcdebug.h>
#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/system.h>
@@ -58,7 +54,6 @@
#endif
int smp_threads_ready;
-unsigned long cache_decay_ticks;
cpumask_t cpu_possible_map = CPU_MASK_NONE;
cpumask_t cpu_online_map = CPU_MASK_NONE;
@@ -77,10 +72,6 @@ void smp_call_function_interrupt(void);
int smt_enabled_at_boot = 1;
-/* Low level assembly function used to backup CPU 0 state */
-extern void __save_cpu_setup(void);
-
-
#ifdef CONFIG_PPC_MULTIPLATFORM
void smp_mpic_message_pass(int target, int msg)
{
@@ -507,9 +498,6 @@ int __devinit start_secondary(void *unused)
if (smp_ops->take_timebase)
smp_ops->take_timebase();
- if (smp_ops->late_setup_cpu)
- smp_ops->late_setup_cpu(cpu);
-
spin_lock(&call_lock);
cpu_set(cpu, cpu_online_map);
spin_unlock(&call_lock);
@@ -551,3 +539,19 @@ void __init smp_cpus_done(unsigned int max_cpus)
*/
cpu_present_map = cpu_possible_map;
}
+
+#ifdef CONFIG_HOTPLUG_CPU
+int __cpu_disable(void)
+{
+ if (smp_ops->cpu_disable)
+ return smp_ops->cpu_disable();
+
+ return -ENOSYS;
+}
+
+void __cpu_die(unsigned int cpu)
+{
+ if (smp_ops->cpu_die)
+ smp_ops->cpu_die(cpu);
+}
+#endif
diff --git a/arch/ppc64/kernel/time.c b/arch/ppc64/kernel/time.c
index 1a6493196f2dfe..01b21095b76cd2 100644
--- a/arch/ppc64/kernel/time.c
+++ b/arch/ppc64/kernel/time.c
@@ -142,16 +142,54 @@ static __inline__ void timer_check_rtc(void)
}
}
+/*
+ * This version of gettimeofday has microsecond resolution.
+ */
+static inline void __do_gettimeofday(struct timeval *tv, unsigned long tb_val)
+{
+ unsigned long sec, usec, tb_ticks;
+ unsigned long xsec, tb_xsec;
+ struct gettimeofday_vars * temp_varp;
+ unsigned long temp_tb_to_xs, temp_stamp_xsec;
+
+ /*
+ * These calculations are faster (gets rid of divides)
+ * if done in units of 1/2^20 rather than microseconds.
+ * The conversion to microseconds at the end is done
+ * without a divide (and in fact, without a multiply)
+ */
+ tb_ticks = tb_val - do_gtod.tb_orig_stamp;
+ temp_varp = do_gtod.varp;
+ temp_tb_to_xs = temp_varp->tb_to_xs;
+ temp_stamp_xsec = temp_varp->stamp_xsec;
+ tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
+ xsec = temp_stamp_xsec + tb_xsec;
+ sec = xsec / XSEC_PER_SEC;
+ xsec -= sec * XSEC_PER_SEC;
+ usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
+
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+ __do_gettimeofday(tv, get_tb());
+}
+
+EXPORT_SYMBOL(do_gettimeofday);
+
/* Synchronize xtime with do_gettimeofday */
-static __inline__ void timer_sync_xtime( unsigned long cur_tb )
+static inline void timer_sync_xtime(unsigned long cur_tb)
{
struct timeval my_tv;
- if ( cur_tb > next_xtime_sync_tb ) {
+ if (cur_tb > next_xtime_sync_tb) {
next_xtime_sync_tb = cur_tb + xtime_sync_interval;
- do_gettimeofday( &my_tv );
- if ( xtime.tv_sec <= my_tv.tv_sec ) {
+ __do_gettimeofday(&my_tv, cur_tb);
+
+ if (xtime.tv_sec <= my_tv.tv_sec) {
xtime.tv_sec = my_tv.tv_sec;
xtime.tv_nsec = my_tv.tv_usec * 1000;
}
@@ -274,7 +312,7 @@ int timer_interrupt(struct pt_regs * regs)
write_seqlock(&xtime_lock);
tb_last_stamp = lpaca->next_jiffy_update_tb;
do_timer(regs);
- timer_sync_xtime( cur_tb );
+ timer_sync_xtime(lpaca->next_jiffy_update_tb);
timer_check_rtc();
write_sequnlock(&xtime_lock);
if ( adjusting_time && (time_adjust == 0) )
@@ -313,36 +351,6 @@ unsigned long long sched_clock(void)
return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
}
-/*
- * This version of gettimeofday has microsecond resolution.
- */
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long sec, usec, tb_ticks;
- unsigned long xsec, tb_xsec;
- struct gettimeofday_vars * temp_varp;
- unsigned long temp_tb_to_xs, temp_stamp_xsec;
-
- /* These calculations are faster (gets rid of divides)
- * if done in units of 1/2^20 rather than microseconds.
- * The conversion to microseconds at the end is done
- * without a divide (and in fact, without a multiply) */
- tb_ticks = get_tb() - do_gtod.tb_orig_stamp;
- temp_varp = do_gtod.varp;
- temp_tb_to_xs = temp_varp->tb_to_xs;
- temp_stamp_xsec = temp_varp->stamp_xsec;
- tb_xsec = mulhdu( tb_ticks, temp_tb_to_xs );
- xsec = temp_stamp_xsec + tb_xsec;
- sec = xsec / XSEC_PER_SEC;
- xsec -= sec * XSEC_PER_SEC;
- usec = (xsec * USEC_PER_SEC)/XSEC_PER_SEC;
-
- tv->tv_sec = sec;
- tv->tv_usec = usec;
-}
-
-EXPORT_SYMBOL(do_gettimeofday);
-
int do_settimeofday(struct timespec *tv)
{
time_t wtm_sec, new_sec = tv->tv_sec;
diff --git a/arch/ppc64/kernel/traps.c b/arch/ppc64/kernel/traps.c
index 44f04fc727fd5a..418aff49933ed1 100644
--- a/arch/ppc64/kernel/traps.c
+++ b/arch/ppc64/kernel/traps.c
@@ -127,6 +127,7 @@ int die(const char *str, struct pt_regs *regs, long err)
}
if (nl)
printk("\n");
+ print_modules();
show_regs(regs);
bust_spinlocks(0);
spin_unlock_irq(&die_lock);
@@ -343,7 +344,7 @@ extern struct bug_entry __start___bug_table[], __stop___bug_table[];
#define module_find_bug(x) NULL
#endif
-static struct bug_entry *find_bug(unsigned long bugaddr)
+struct bug_entry *find_bug(unsigned long bugaddr)
{
struct bug_entry *bug;
@@ -353,7 +354,7 @@ static struct bug_entry *find_bug(unsigned long bugaddr)
return module_find_bug(bugaddr);
}
-int
+static int
check_bug_trap(struct pt_regs *regs)
{
struct bug_entry *bug;
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
index b9fdcc60d6e8e0..eca025abe0987b 100644
--- a/arch/ppc64/kernel/xics.c
+++ b/arch/ppc64/kernel/xics.c
@@ -91,6 +91,7 @@ static int xics_irq_8259_cascade_real = 0;
static unsigned int default_server = 0xFF;
/* also referenced in smp.c... */
unsigned int default_distrib_server = 0;
+unsigned int interrupt_server_size = 8;
/*
* XICS only has a single IPI, so encode the messages per CPU
@@ -511,6 +512,10 @@ nextnode:
default_server = ireg[0];
default_distrib_server = ireg[i-1]; /* take last element */
}
+ ireg = (uint *)get_property(np,
+ "ibm,interrupt-server#-size", NULL);
+ if (ireg)
+ interrupt_server_size = *ireg;
break;
}
}
@@ -643,20 +648,16 @@ static void xics_set_affinity(unsigned int virq, cpumask_t cpumask)
/* Interrupts are disabled. */
void xics_migrate_irqs_away(void)
{
- int set_indicator = rtas_token("set-indicator");
- const unsigned int giqs = 9005UL; /* Global Interrupt Queue Server */
- int status = 0;
+ int status;
unsigned int irq, virq, cpu = smp_processor_id();
- BUG_ON(set_indicator == RTAS_UNKNOWN_SERVICE);
-
/* Reject any interrupt that was queued to us... */
ops->cppr_info(cpu, 0);
iosync();
- /* Refuse any new interrupts... */
- rtas_call(set_indicator, 3, 1, &status, giqs,
- hard_smp_processor_id(), 0);
+ /* remove ourselves from the global interrupt queue */
+ status = rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE,
+ (1UL << interrupt_server_size) - 1 - default_distrib_server, 0);
WARN_ON(status != 0);
/* Allow IPIs again... */
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c
index 056db88671b4d9..723a3dc77db6d3 100644
--- a/arch/ppc64/mm/init.c
+++ b/arch/ppc64/mm/init.c
@@ -37,6 +37,7 @@
#include <linux/bootmem.h>
#include <linux/highmem.h>
#include <linux/idr.h>
+#include <linux/nodemask.h>
#include <asm/pgalloc.h>
#include <asm/page.h>
diff --git a/arch/ppc64/mm/numa.c b/arch/ppc64/mm/numa.c
index ad07e3d0d3445e..83d7ec3b7c104e 100644
--- a/arch/ppc64/mm/numa.c
+++ b/arch/ppc64/mm/numa.c
@@ -345,8 +345,6 @@ new_range:
numa_domain = 0;
}
- node_set_online(numa_domain);
-
if (max_domain < numa_domain)
max_domain = numa_domain;
@@ -361,14 +359,19 @@ new_range:
init_node_data[numa_domain].node_start_pfn +
init_node_data[numa_domain].node_spanned_pages;
if (shouldstart != (start / PAGE_SIZE)) {
- printk(KERN_ERR "WARNING: Hole in node, "
- "disabling region start %lx "
- "length %lx\n", start, size);
- continue;
+ /* Revert to non-numa for now */
+ printk(KERN_ERR
+ "WARNING: Unexpected node layout: "
+ "region start %lx length %lx\n",
+ start, size);
+ printk(KERN_ERR "NUMA is disabled\n");
+ goto err;
}
init_node_data[numa_domain].node_spanned_pages +=
size / PAGE_SIZE;
} else {
+ node_set_online(numa_domain);
+
init_node_data[numa_domain].node_start_pfn =
start / PAGE_SIZE;
init_node_data[numa_domain].node_spanned_pages =
@@ -388,6 +391,14 @@ new_range:
node_set_online(i);
return 0;
+err:
+ /* Something has gone wrong; revert any setup we've done */
+ for_each_node(i) {
+ node_set_offline(i);
+ init_node_data[i].node_start_pfn = 0;
+ init_node_data[i].node_spanned_pages = 0;
+ }
+ return -1;
}
static void __init setup_nonnuma(void)
diff --git a/arch/ppc64/xmon/setjmp.S b/arch/ppc64/xmon/setjmp.S
new file mode 100644
index 00000000000000..30ee643d557cd8
--- /dev/null
+++ b/arch/ppc64/xmon/setjmp.S
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * 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.
+ *
+ * NOTE: assert(sizeof(buf) > 184)
+ */
+#include <asm/processor.h>
+#include <asm/ppc_asm.h>
+
+_GLOBAL(xmon_setjmp)
+ mflr r0
+ std r0,0(r3)
+ std r1,8(r3)
+ std r2,16(r3)
+ mfcr r0
+ std r0,24(r3)
+ std r13,32(r3)
+ std r14,40(r3)
+ std r15,48(r3)
+ std r16,56(r3)
+ std r17,64(r3)
+ std r18,72(r3)
+ std r19,80(r3)
+ std r20,88(r3)
+ std r21,96(r3)
+ std r22,104(r3)
+ std r23,112(r3)
+ std r24,120(r3)
+ std r25,128(r3)
+ std r26,136(r3)
+ std r27,144(r3)
+ std r28,152(r3)
+ std r29,160(r3)
+ std r30,168(r3)
+ std r31,176(r3)
+ li r3,0
+ blr
+
+_GLOBAL(xmon_longjmp)
+ cmpdi r4,0
+ bne 1f
+ li r4,1
+1: ld r13,32(r3)
+ ld r14,40(r3)
+ ld r15,48(r3)
+ ld r16,56(r3)
+ ld r17,64(r3)
+ ld r18,72(r3)
+ ld r19,80(r3)
+ ld r20,88(r3)
+ ld r21,96(r3)
+ ld r22,104(r3)
+ ld r23,112(r3)
+ ld r24,120(r3)
+ ld r25,128(r3)
+ ld r26,136(r3)
+ ld r27,144(r3)
+ ld r28,152(r3)
+ ld r29,160(r3)
+ ld r30,168(r3)
+ ld r31,176(r3)
+ ld r0,24(r3)
+ mtcrf 56,r0
+ ld r0,0(r3)
+ ld r1,8(r3)
+ ld r2,16(r3)
+ mtlr r0
+ mr r3,r4
+ blr
diff --git a/arch/ppc64/xmon/setjmp.c b/arch/ppc64/xmon/setjmp.c
deleted file mode 100644
index a3f6135c5669b5..00000000000000
--- a/arch/ppc64/xmon/setjmp.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 1996 Paul Mackerras.
- *
- * 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.
- *
- * NB this file must be compiled with -O2.
- */
-
-int
-xmon_setjmp(long *buf) /* NOTE: assert(sizeof(buf) > 184) */
-{
- /* XXX should save fp regs as well */
- asm volatile (
- "mflr 0; std 0,0(%0)\n\
- std 1,8(%0)\n\
- std 2,16(%0)\n\
- mfcr 0; std 0,24(%0)\n\
- std 13,32(%0)\n\
- std 14,40(%0)\n\
- std 15,48(%0)\n\
- std 16,56(%0)\n\
- std 17,64(%0)\n\
- std 18,72(%0)\n\
- std 19,80(%0)\n\
- std 20,88(%0)\n\
- std 21,96(%0)\n\
- std 22,104(%0)\n\
- std 23,112(%0)\n\
- std 24,120(%0)\n\
- std 25,128(%0)\n\
- std 26,136(%0)\n\
- std 27,144(%0)\n\
- std 28,152(%0)\n\
- std 29,160(%0)\n\
- std 30,168(%0)\n\
- std 31,176(%0)\n\
- " : : "r" (buf));
- return 0;
-}
-
-void
-xmon_longjmp(long *buf, int val)
-{
- if (val == 0)
- val = 1;
- asm volatile (
- "ld 13,32(%0)\n\
- ld 14,40(%0)\n\
- ld 15,48(%0)\n\
- ld 16,56(%0)\n\
- ld 17,64(%0)\n\
- ld 18,72(%0)\n\
- ld 19,80(%0)\n\
- ld 20,88(%0)\n\
- ld 21,96(%0)\n\
- ld 22,104(%0)\n\
- ld 23,112(%0)\n\
- ld 24,120(%0)\n\
- ld 25,128(%0)\n\
- ld 26,136(%0)\n\
- ld 27,144(%0)\n\
- ld 28,152(%0)\n\
- ld 29,160(%0)\n\
- ld 30,168(%0)\n\
- ld 31,176(%0)\n\
- ld 0,24(%0)\n\
- mtcrf 0x38,0\n\
- ld 0,0(%0)\n\
- ld 1,8(%0)\n\
- ld 2,16(%0)\n\
- mtlr 0\n\
- mr 3,%1\n\
- " : : "r" (buf), "r" (val));
-}
diff --git a/arch/ppc64/xmon/xmon.c b/arch/ppc64/xmon/xmon.c
index c53046d52e6c1b..2be270592fb399 100644
--- a/arch/ppc64/xmon/xmon.c
+++ b/arch/ppc64/xmon/xmon.c
@@ -31,6 +31,7 @@
#include <asm/cputable.h>
#include <asm/rtas.h>
#include <asm/sstep.h>
+#include <asm/bug.h>
#include "nonstdio.h"
#include "privinst.h"
@@ -1319,6 +1320,26 @@ static void backtrace(struct pt_regs *excp)
scannl();
}
+static void print_bug_trap(struct pt_regs *regs)
+{
+ struct bug_entry *bug;
+ unsigned long addr;
+
+ if (regs->msr & MSR_PR)
+ return; /* not in kernel */
+ addr = regs->nip; /* address of trap instruction */
+ if (addr < PAGE_OFFSET)
+ return;
+ bug = find_bug(regs->nip);
+ if (bug == NULL)
+ return;
+ if (bug->line & BUG_WARNING_TRAP)
+ return;
+
+ printf("kernel BUG in %s at %s:%d!\n",
+ bug->function, bug->file, (unsigned int)bug->line);
+}
+
void excprint(struct pt_regs *fp)
{
unsigned long trap;
@@ -1350,6 +1371,9 @@ void excprint(struct pt_regs *fp)
printf(" pid = %ld, comm = %s\n",
current->pid, current->comm);
}
+
+ if (trap == 0x700)
+ print_bug_trap(fp);
}
void prregs(struct pt_regs *fp)
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 85ecab32be8915..8394c4e5107332 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -367,6 +367,13 @@ config VIRT_TIMER
This provides a kernel interface for virtual CPU timers.
Default is disabled.
+config VIRT_CPU_ACCOUNTING
+ bool "Base user process accounting on virtual cpu timer"
+ depends on VIRT_TIMER
+ help
+ Select this option to use CPU timer deltas to do user
+ process accounting.
+
config APPLDATA_BASE
bool "Linux - VM Monitor Stream, base infrastructure"
depends on PROC_FS && VIRT_TIMER=y
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index 1100c409b5bb7e..03ba5893f17b7f 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -197,12 +197,13 @@ MODULE_AUTHOR("Gerhard Tonn <ton@de.ibm.com>");
#undef MODULE_DESCRIPTION
#undef MODULE_AUTHOR
-#define jiffies_to_timeval jiffies_to_compat_timeval
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
{
- value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
- value->tv_sec = jiffies / HZ;
+ value->tv_usec = cputime % 1000000;
+ value->tv_sec = cputime / 1000000;
}
#include "../../../fs/binfmt_elf.c"
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index f72f9ec9be55a5..c0e09b33febe6f 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -66,6 +66,27 @@ STACK_SIZE = 1 << STACK_SHIFT
* R15 - kernel stack pointer
*/
+ .macro STORE_TIMER lc_offset
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ stpt \lc_offset
+#endif
+ .endm
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ .macro UPDATE_VTIME lc_from,lc_to,lc_sum
+ lm %r10,%r11,\lc_from
+ sl %r10,\lc_to
+ sl %r11,\lc_to+4
+ bc 3,BASED(0f)
+ sl %r10,BASED(.Lc_1)
+0: al %r10,\lc_sum
+ al %r11,\lc_sum+4
+ bc 12,BASED(1f)
+ al %r10,BASED(.Lc_1)
+1: stm %r10,%r11,\lc_sum
+ .endm
+#endif
+
.macro SAVE_ALL_BASE savearea
stm %r12,%r15,\savearea
l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
@@ -118,6 +139,7 @@ STACK_SIZE = 1 << STACK_SHIFT
ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
.endif
lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user
+ STORE_TIMER __LC_EXIT_TIMER
lpsw __LC_RETURN_PSW # back to caller
.endm
@@ -159,9 +181,21 @@ __critical_start:
.globl system_call
system_call:
+ STORE_TIMER __LC_SYNC_ENTER_TIMER
+sysc_saveall:
SAVE_ALL_BASE __LC_SAVE_AREA
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
lh %r7,0x8a # get svc number from lowcore
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+sysc_vtime:
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(sysc_do_svc)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+sysc_stime:
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+sysc_update:
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+#endif
sysc_do_svc:
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
sla %r7,2 # *4 and test for svc 0
@@ -391,10 +425,19 @@ pgm_check_handler:
* we just ignore the PER event (FIXME: is there anything we have to do
* for LPSW?).
*/
+ STORE_TIMER __LC_SYNC_ENTER_TIMER
SAVE_ALL_BASE __LC_SAVE_AREA
tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
bnz BASED(pgm_per) # got per exception -> special case
SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(pgm_no_vtime)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime:
+#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r3,__LC_PGM_ILC # load program interruption code
la %r8,0x7f
@@ -425,6 +468,14 @@ pgm_per:
#
pgm_per_std:
SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(pgm_no_vtime2)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime2:
+#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
@@ -442,6 +493,14 @@ pgm_per_std:
#
pgm_svcper:
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(pgm_no_vtime3)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime3:
+#endif
lh %r7,0x8a # get svc number from lowcore
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r1,__TI_task(%r9)
@@ -458,9 +517,18 @@ pgm_svcper:
.globl io_int_handler
io_int_handler:
+ STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+16
SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(io_no_vtime)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+io_no_vtime:
+#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ
la %r2,SP_PTREGS(%r15) # address of register-save area
@@ -549,9 +617,18 @@ io_sigpending:
.globl ext_int_handler
ext_int_handler:
+ STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+16
SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(ext_no_vtime)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+ext_no_vtime:
+#endif
l %r9,__LC_THREAD_INFO # load pointer to thread_info struct
la %r2,SP_PTREGS(%r15) # address of register-save area
lh %r3,__LC_EXT_INT_CODE # get interruption code
@@ -565,8 +642,17 @@ ext_int_handler:
.globl mcck_int_handler
mcck_int_handler:
+ STORE_TIMER __LC_ASYNC_ENTER_TIMER
SAVE_ALL_BASE __LC_SAVE_AREA+32
SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+32,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(mcck_no_vtime)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+mcck_no_vtime:
+#endif
l %r1,BASED(.Ls390_mcck)
basr %r14,%r1 # call machine check handler
mcck_return:
@@ -661,17 +747,47 @@ cleanup_critical:
br %r14
cleanup_system_call:
- mvc __LC_RETURN_PSW(4),0(%r12)
- clc 4(4,%r12),BASED(cleanup_table_system_call)
- bne BASED(0f)
+ mvc __LC_RETURN_PSW(8),0(%r12)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4)
+ bh BASED(0f)
+ mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
+0: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8)
+ bhe BASED(cleanup_vtime)
+#endif
+ clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn)
+ bh BASED(0f)
mvc __LC_SAVE_AREA(16),__LC_SAVE_AREA+16
0: st %r13,__LC_SAVE_AREA+20
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
st %r15,__LC_SAVE_AREA+28
lh %r7,0x8a
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+cleanup_vtime:
+ clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12)
+ bhe BASED(cleanup_stime)
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ bz BASED(cleanup_novtime)
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+cleanup_stime:
+ clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16)
+ bh BASED(cleanup_update)
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+cleanup_update:
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+cleanup_novtime:
+#endif
mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4)
la %r12,__LC_RETURN_PSW
br %r14
+cleanup_system_call_insn:
+ .long sysc_saveall + 0x80000000
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ .long system_call + 0x80000000
+ .long sysc_vtime + 0x80000000
+ .long sysc_stime + 0x80000000
+ .long sysc_update + 0x80000000
+#endif
cleanup_sysc_return:
mvc __LC_RETURN_PSW(4),0(%r12)
@@ -680,15 +796,23 @@ cleanup_sysc_return:
br %r14
cleanup_sysc_leave:
- clc 4(4,%r12),BASED(cleanup_sysc_leave_lpsw)
+ clc 4(4,%r12),BASED(cleanup_sysc_leave_insn)
+ be BASED(0f)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
+ clc 4(4,%r12),BASED(cleanup_sysc_leave_insn+4)
be BASED(0f)
+#endif
mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
mvc __LC_SAVE_AREA+16(16),SP_R12(%r15)
lm %r0,%r11,SP_R0(%r15)
l %r15,SP_R15(%r15)
0: la %r12,__LC_RETURN_PSW
br %r14
-cleanup_sysc_leave_lpsw:
+cleanup_sysc_leave_insn:
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ .long sysc_leave + 14 + 0x80000000
+#endif
.long sysc_leave + 10 + 0x80000000
/*
@@ -704,6 +828,7 @@ cleanup_sysc_leave_lpsw:
.L0x028: .short 0x028
.L0x030: .short 0x030
.L0x038: .short 0x038
+.Lc_1: .long 1
/*
* Symbol constants
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index adbe2a5f5f72b0..51527ab8c8f974 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -58,6 +58,21 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
#define BASED(name) name-system_call(%r13)
+ .macro STORE_TIMER lc_offset
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ stpt \lc_offset
+#endif
+ .endm
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ .macro UPDATE_VTIME lc_from,lc_to,lc_sum
+ lg %r10,\lc_from
+ slg %r10,\lc_to
+ alg %r10,\lc_sum
+ stg %r10,\lc_sum
+ .endm
+#endif
+
/*
* Register usage in interrupt handlers:
* R9 - pointer to current task structure
@@ -117,6 +132,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED)
ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
.endif
lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user
+ STORE_TIMER __LC_EXIT_TIMER
lpswe __LC_RETURN_PSW # back to caller
.endm
@@ -156,9 +172,21 @@ __critical_start:
.globl system_call
system_call:
+ STORE_TIMER __LC_SYNC_ENTER_TIMER
+sysc_saveall:
SAVE_ALL_BASE __LC_SAVE_AREA
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+sysc_vtime:
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz sysc_do_svc
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+sysc_stime:
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+sysc_update:
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+#endif
sysc_do_svc:
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
slag %r7,%r7,2 # *4 and test for svc 0
@@ -441,10 +469,19 @@ pgm_check_handler:
* we just ignore the PER event (FIXME: is there anything we have to do
* for LPSW?).
*/
+ STORE_TIMER __LC_SYNC_ENTER_TIMER
SAVE_ALL_BASE __LC_SAVE_AREA
tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception
jnz pgm_per # got per exception -> special case
SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz pgm_no_vtime
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime:
+#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
lgf %r3,__LC_PGM_ILC # load program interruption code
lghi %r8,0x7f
@@ -475,6 +512,14 @@ pgm_per:
#
pgm_per_std:
SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz pgm_no_vtime2
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime2:
+#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
lg %r1,__TI_task(%r9)
mvc __THREAD_per+__PER_atmid(2,%r1),__LC_PER_ATMID
@@ -492,6 +537,14 @@ pgm_per_std:
#
pgm_svcper:
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz pgm_no_vtime3
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+pgm_no_vtime3:
+#endif
llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
lg %r1,__TI_task(%r9)
@@ -507,9 +560,18 @@ pgm_svcper:
*/
.globl io_int_handler
io_int_handler:
+ STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+32
SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz io_no_vtime
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+io_no_vtime:
+#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
la %r2,SP_PTREGS(%r15) # address of register-save area
brasl %r14,do_IRQ # call standard irq handler
@@ -595,9 +657,18 @@ io_sigpending:
*/
.globl ext_int_handler
ext_int_handler:
+ STORE_TIMER __LC_ASYNC_ENTER_TIMER
stck __LC_INT_CLOCK
SAVE_ALL_BASE __LC_SAVE_AREA+32
SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz ext_no_vtime
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+ext_no_vtime:
+#endif
lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct
la %r2,SP_PTREGS(%r15) # address of register-save area
llgh %r3,__LC_EXT_INT_CODE # get interruption code
@@ -609,8 +680,17 @@ ext_int_handler:
*/
.globl mcck_int_handler
mcck_int_handler:
+ STORE_TIMER __LC_ASYNC_ENTER_TIMER
SAVE_ALL_BASE __LC_SAVE_AREA+64
SAVE_ALL __LC_MCK_OLD_PSW,__LC_SAVE_AREA+64,0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz mcck_no_vtime
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER
+mcck_no_vtime:
+#endif
brasl %r14,s390_do_machine_check
mcck_return:
RESTORE_ALL 0
@@ -700,17 +780,47 @@ cleanup_critical:
br %r14
cleanup_system_call:
- mvc __LC_RETURN_PSW(8),0(%r12)
- clc 8(8,%r12),BASED(cleanup_table_system_call)
- jne 0f
+ mvc __LC_RETURN_PSW(16),0(%r12)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8)
+ jh 0f
+ mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
+0: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16)
+ jhe cleanup_vtime
+#endif
+ clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
+ jh 0f
mvc __LC_SAVE_AREA(32),__LC_SAVE_AREA+32
0: stg %r13,__LC_SAVE_AREA+40
SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1
stg %r15,__LC_SAVE_AREA+56
llgh %r7,__LC_SVC_INT_CODE
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+cleanup_vtime:
+ clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24)
+ jhe cleanup_stime
+ tm SP_PSW+1(%r15),0x01 # interrupting from user ?
+ jz cleanup_novtime
+ UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
+cleanup_stime:
+ clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32)
+ jh cleanup_update
+ UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
+cleanup_update:
+ mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
+cleanup_novtime:
+#endif
mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8)
la %r12,__LC_RETURN_PSW
br %r14
+cleanup_system_call_insn:
+ .quad sysc_saveall
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ .quad system_call
+ .quad sysc_vtime
+ .quad sysc_stime
+ .quad sysc_update
+#endif
cleanup_sysc_return:
mvc __LC_RETURN_PSW(8),0(%r12)
@@ -719,15 +829,23 @@ cleanup_sysc_return:
br %r14
cleanup_sysc_leave:
- clc 8(8,%r12),BASED(cleanup_sysc_leave_lpsw)
+ clc 8(8,%r12),BASED(cleanup_sysc_leave_insn)
+ je 0f
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER
+ clc 8(8,%r12),BASED(cleanup_sysc_leave_insn+8)
je 0f
+#endif
mvc __LC_RETURN_PSW(16),SP_PSW(%r15)
mvc __LC_SAVE_AREA+32(32),SP_R12(%r15)
lmg %r0,%r11,SP_R0(%r15)
lg %r15,SP_R15(%r15)
0: la %r12,__LC_RETURN_PSW
br %r14
-cleanup_sysc_leave_lpsw:
+cleanup_sysc_leave_insn:
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ .quad sysc_leave + 16
+#endif
.quad sysc_leave + 12
/*
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 75275fe905b134..59bfceabaebebe 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -71,6 +71,10 @@ asmlinkage void do_softirq(void)
local_irq_save(flags);
+ account_system_vtime(current);
+
+ local_bh_disable();
+
if (local_softirq_pending()) {
/* Get current stack pointer. */
asm volatile("la %0,0(15)" : "=a" (old));
@@ -93,6 +97,10 @@ asmlinkage void do_softirq(void)
__do_softirq();
}
+ account_system_vtime(current);
+
+ __local_bh_enable();
+
local_irq_restore(flags);
}
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 2fea300f4b479c..995e2cd38e773f 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -150,28 +150,6 @@ int do_settimeofday(struct timespec *tv)
EXPORT_SYMBOL(do_settimeofday);
-#ifndef CONFIG_ARCH_S390X
-
-static inline __u32
-__calculate_ticks(__u64 elapsed)
-{
- register_pair rp;
-
- rp.pair = elapsed >> 1;
- asm ("dr %0,%1" : "+d" (rp) : "d" (CLK_TICKS_PER_JIFFY >> 1));
- return rp.subreg.odd;
-}
-
-#else /* CONFIG_ARCH_S390X */
-
-static inline __u32
-__calculate_ticks(__u64 elapsed)
-{
- return elapsed / CLK_TICKS_PER_JIFFY;
-}
-
-#endif /* CONFIG_ARCH_S390X */
-
#ifdef CONFIG_PROFILING
#define s390_do_profile(regs) profile_tick(CPU_PROFILING, regs)
@@ -187,14 +165,14 @@ __calculate_ticks(__u64 elapsed)
void account_ticks(struct pt_regs *regs)
{
__u64 tmp;
- __u32 ticks;
+ __u32 ticks, xticks;
/* Calculate how many ticks have passed. */
if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer)
return;
tmp = S390_lowcore.int_clock - S390_lowcore.jiffy_timer;
if (tmp >= 2*CLK_TICKS_PER_JIFFY) { /* more than two ticks ? */
- ticks = __calculate_ticks(tmp) + 1;
+ ticks = __div(tmp, CLK_TICKS_PER_JIFFY) + 1;
S390_lowcore.jiffy_timer +=
CLK_TICKS_PER_JIFFY * (__u64) ticks;
} else if (tmp >= CLK_TICKS_PER_JIFFY) {
@@ -216,11 +194,9 @@ void account_ticks(struct pt_regs *regs)
*/
write_seqlock(&xtime_lock);
if (S390_lowcore.jiffy_timer > xtime_cc) {
- __u32 xticks;
-
tmp = S390_lowcore.jiffy_timer - xtime_cc;
if (tmp >= 2*CLK_TICKS_PER_JIFFY) {
- xticks = __calculate_ticks(tmp);
+ xticks = __div(tmp, CLK_TICKS_PER_JIFFY);
xtime_cc += (__u64) xticks * CLK_TICKS_PER_JIFFY;
} else {
xticks = 1;
@@ -230,14 +206,18 @@ void account_ticks(struct pt_regs *regs)
do_timer(regs);
}
write_sequnlock(&xtime_lock);
- while (ticks--)
- update_process_times(user_mode(regs));
#else
- while (ticks--) {
+ for (xticks = ticks; xticks > 0; xticks--)
do_timer(regs);
+#endif
+
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+ account_user_vtime(current);
+#else
+ while (ticks--)
update_process_times(user_mode(regs));
- }
#endif
+
s390_do_profile(regs);
}
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 02d2179e40828a..63cdfec3ba99b7 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -17,6 +17,8 @@
#include <linux/types.h>
#include <linux/timex.h>
#include <linux/notifier.h>
+#include <linux/kernel_stat.h>
+#include <linux/rcupdate.h>
#include <asm/s390_ext.h>
#include <asm/timer.h>
@@ -25,7 +27,95 @@
static ext_int_info_t ext_int_info_timer;
DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
-void start_cpu_timer(void)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/*
+ * Update process times based on virtual cpu times stored by entry.S
+ * to the lowcore fields user_timer, system_timer & steal_clock.
+ */
+void account_user_vtime(struct task_struct *tsk)
+{
+ cputime_t cputime;
+ __u64 timer, clock;
+ int rcu_user_flag;
+
+ timer = S390_lowcore.last_update_timer;
+ clock = S390_lowcore.last_update_clock;
+ asm volatile (" STPT %0\n" /* Store current cpu timer value */
+ " STCK %1" /* Store current tod clock value */
+ : "=m" (S390_lowcore.last_update_timer),
+ "=m" (S390_lowcore.last_update_clock) );
+ S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
+ S390_lowcore.steal_clock += S390_lowcore.last_update_clock - clock;
+
+ cputime = S390_lowcore.user_timer >> 12;
+ rcu_user_flag = cputime != 0;
+ S390_lowcore.user_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_user_time(tsk, cputime);
+
+ cputime = S390_lowcore.system_timer >> 12;
+ S390_lowcore.system_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_system_time(tsk, HARDIRQ_OFFSET, cputime);
+
+ cputime = S390_lowcore.steal_clock;
+ if ((__s64) cputime > 0) {
+ cputime >>= 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_steal_time(tsk, cputime);
+ }
+
+ run_local_timers();
+ if (rcu_pending(smp_processor_id()))
+ rcu_check_callbacks(smp_processor_id(), rcu_user_flag);
+ scheduler_tick();
+}
+
+/*
+ * Update process times based on virtual cpu times stored by entry.S
+ * to the lowcore fields user_timer, system_timer & steal_clock.
+ */
+void account_system_vtime(struct task_struct *tsk)
+{
+ cputime_t cputime;
+ __u64 timer;
+
+ timer = S390_lowcore.last_update_timer;
+ asm volatile (" STPT %0" /* Store current cpu timer value */
+ : "=m" (S390_lowcore.last_update_timer) );
+ S390_lowcore.system_timer += timer - S390_lowcore.last_update_timer;
+
+ cputime = S390_lowcore.system_timer >> 12;
+ S390_lowcore.system_timer -= cputime << 12;
+ S390_lowcore.steal_clock -= cputime << 12;
+ account_system_time(tsk, 0, cputime);
+}
+
+static inline void set_vtimer(__u64 expires)
+{
+ __u64 timer;
+
+ asm volatile (" STPT %0\n" /* Store current cpu timer value */
+ " SPT %1" /* Set new value immediatly afterwards */
+ : "=m" (timer) : "m" (expires) );
+ S390_lowcore.system_timer += S390_lowcore.last_update_timer - timer;
+ S390_lowcore.last_update_timer = expires;
+
+ /* store expire time for this CPU timer */
+ per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
+}
+#else
+static inline void set_vtimer(__u64 expires)
+{
+ S390_lowcore.last_update_timer = expires;
+ asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
+
+ /* store expire time for this CPU timer */
+ per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
+}
+#endif
+
+static void start_cpu_timer(void)
{
struct vtimer_queue *vt_list;
@@ -33,7 +123,7 @@ void start_cpu_timer(void)
set_vtimer(vt_list->idle);
}
-void stop_cpu_timer(void)
+static void stop_cpu_timer(void)
{
__u64 done;
struct vtimer_queue *vt_list;
@@ -71,19 +161,11 @@ void stop_cpu_timer(void)
set_vtimer(VTIMER_MAX_SLICE);
}
-void set_vtimer(__u64 expires)
-{
- asm volatile ("SPT %0" : : "m" (expires));
-
- /* store expire time for this CPU timer */
- per_cpu(virt_cpu_timer, smp_processor_id()).to_expire = expires;
-}
-
/*
* Sorted add to a list. List is linear searched until first bigger
* element is found.
*/
-void list_add_sorted(struct vtimer_list *timer, struct list_head *head)
+static void list_add_sorted(struct vtimer_list *timer, struct list_head *head)
{
struct vtimer_list *event;
@@ -429,11 +511,12 @@ void init_cpu_vtimer(void)
{
struct vtimer_queue *vt_list;
unsigned long cr0;
- __u64 timer;
/* kick the virtual timer */
- timer = VTIMER_MAX_SLICE;
- asm volatile ("SPT %0" : : "m" (timer));
+ S390_lowcore.exit_timer = VTIMER_MAX_SLICE;
+ S390_lowcore.last_update_timer = VTIMER_MAX_SLICE;
+ asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
+ asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock));
__ctl_store(cr0, 0, 0);
cr0 |= 0x400;
__ctl_load(cr0, 0, 0);
diff --git a/arch/sparc64/kernel/binfmt_aout32.c b/arch/sparc64/kernel/binfmt_aout32.c
index 64d547853b48c0..1afe88f6abc082 100644
--- a/arch/sparc64/kernel/binfmt_aout32.c
+++ b/arch/sparc64/kernel/binfmt_aout32.c
@@ -49,7 +49,9 @@ static void set_brk(unsigned long start, unsigned long end)
end = PAGE_ALIGN(end);
if (end <= start)
return;
+ down_write(&current->mm->mmap_sem);
do_brk(start, end - start);
+ up_write(&current->mm->mmap_sem);
}
/*
@@ -95,7 +97,7 @@ static int aout32_core_dump(long signr, struct pt_regs *regs, struct file *file)
set_fs(KERNEL_DS);
has_dumped = 1;
current->flags |= PF_DUMPCORE;
- strncpy(dump.u_comm, current->comm, sizeof(current->comm));
+ strncpy(dump.u_comm, current->comm, sizeof(dump.u_comm));
dump.signal = signr;
dump_thread(regs, &dump);
@@ -246,10 +248,14 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (N_MAGIC(ex) == NMAGIC) {
loff_t pos = fd_offset;
/* Fuck me plenty... */
+ down_write(&current->mm->mmap_sem);
error = do_brk(N_TXTADDR(ex), ex.a_text);
+ up_write(&current->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
ex.a_text, &pos);
+ down_write(&current->mm->mmap_sem);
error = do_brk(N_DATADDR(ex), ex.a_data);
+ up_write(&current->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, (char __user *)N_DATADDR(ex),
ex.a_data, &pos);
goto beyond_if;
@@ -257,8 +263,10 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (N_MAGIC(ex) == OMAGIC) {
loff_t pos = fd_offset;
+ down_write(&current->mm->mmap_sem);
do_brk(N_TXTADDR(ex) & PAGE_MASK,
ex.a_text+ex.a_data + PAGE_SIZE - 1);
+ up_write(&current->mm->mmap_sem);
bprm->file->f_op->read(bprm->file, (char __user *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
} else {
@@ -272,7 +280,9 @@ static int load_aout32_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (!bprm->file->f_op->mmap) {
loff_t pos = fd_offset;
+ down_write(&current->mm->mmap_sem);
do_brk(0, ex.a_text+ex.a_data);
+ up_write(&current->mm->mmap_sem);
bprm->file->f_op->read(bprm->file,
(char __user *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
@@ -389,7 +399,9 @@ static int load_aout32_library(struct file *file)
len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) {
+ down_write(&current->mm->mmap_sem);
error = do_brk(start_addr + len, bss - len);
+ up_write(&current->mm->mmap_sem);
retval = error;
if (error != start_addr + len)
goto out;
diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c
index c13eaf0307588f..a1a12d2aa3530e 100644
--- a/arch/sparc64/kernel/binfmt_elf32.c
+++ b/arch/sparc64/kernel/binfmt_elf32.c
@@ -132,10 +132,12 @@ struct elf_prpsinfo32
#include <linux/time.h>
-#define jiffies_to_timeval jiffies_to_compat_timeval
+#undef cputime_to_timeval
+#define cputime_to_timeval cputime_to_compat_timeval
static __inline__ void
-jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value)
+cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
{
+ unsigned long jiffies = cputime_to_jiffies(cputime);
value->tv_usec = (jiffies % HZ) * (1000000L / HZ);
value->tv_sec = jiffies / HZ;
}
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 06ba2aca73a54c..f399b64a137c4f 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -68,6 +68,8 @@ config MODE_SKAS
to CONFIG_MODE_TT). Otherwise, it is safe to say Y. Disabling this
option will shrink the UML binary slightly.
+source "arch/um/Kconfig_arch"
+
config NET
bool "Networking support"
help
@@ -283,7 +285,10 @@ if BROKEN
endif
config INPUT
- bool
+ bool "Dummy option"
+ depends BROKEN
default n
+ help
+ This is a dummy option to get rid of warnings.
source "arch/um/Kconfig.debug"
diff --git a/arch/um/Kconfig_arch b/arch/um/Kconfig_arch
new file mode 100644
index 00000000000000..2f5f053bc46195
--- /dev/null
+++ b/arch/um/Kconfig_arch
@@ -0,0 +1,16 @@
+config 64_BIT
+ bool
+ default n
+
+config TOP_ADDR
+ hex
+ default 0xc0000000 if !HOST_2G_2G
+ default 0x80000000 if HOST_2G_2G
+
+config 3_LEVEL_PGTABLES
+ bool "Three-level pagetables"
+ default n
+ help
+ Three-level pagetables will let UML have more than 4G of physical
+ memory. All the memory that can't be mapped directly will be treated
+ as high memory.
diff --git a/arch/um/Kconfig_char b/arch/um/Kconfig_char
index 7a933d1b5d5bd2..fa34a9698586a1 100644
--- a/arch/um/Kconfig_char
+++ b/arch/um/Kconfig_char
@@ -23,15 +23,6 @@ config SSL
Unless you have a specific reason for disabling this, say Y.
-config FD_CHAN
- bool "file descriptor channel support"
- help
- This option enables support for attaching UML consoles and serial
- lines to already set up file descriptors. Generally, the main
- console is attached to file descriptors 0 and 1 (stdin and stdout),
- so it would be wise to leave this enabled unless you intend to
- attach it to some other host device.
-
config NULL_CHAN
bool "null channel support"
help
@@ -80,7 +71,7 @@ config XTERM_CHAN
config NOCONFIG_CHAN
bool
- default !(XTERM_CHAN && TTY_CHAN && PTY_CHAN && PORT_CHAN && FD_CHAN && NULL_CHAN)
+ default !(XTERM_CHAN && TTY_CHAN && PTY_CHAN && PORT_CHAN && NULL_CHAN)
config CON_ZERO_CHAN
string "Default main console channel initialization"
diff --git a/arch/um/Kconfig_i386 b/arch/um/Kconfig_i386
new file mode 100644
index 00000000000000..e3d956db3daad5
--- /dev/null
+++ b/arch/um/Kconfig_i386
@@ -0,0 +1,20 @@
+config 64_BIT
+ bool
+ default n
+
+config TOP_ADDR
+ hex
+ default 0xc0000000 if !HOST_2G_2G
+ default 0x80000000 if HOST_2G_2G
+
+config 3_LEVEL_PGTABLES
+ bool "Three-level pagetables"
+ default n
+ help
+ Three-level pagetables will let UML have more than 4G of physical
+ memory. All the memory that can't be mapped directly will be treated
+ as high memory.
+
+config ARCH_HAS_SC_SIGNALS
+ bool
+ default y
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64
new file mode 100644
index 00000000000000..0d3d05cab5b7d7
--- /dev/null
+++ b/arch/um/Kconfig_x86_64
@@ -0,0 +1,11 @@
+config 64_BIT
+ bool
+ default y
+
+config 3_LEVEL_PGTABLES
+ bool
+ default y
+
+config ARCH_HAS_SC_SIGNALS
+ bool
+ default n
diff --git a/arch/um/Makefile b/arch/um/Makefile
index b8371a95849a05..a21b5d1da07fa9 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -12,14 +12,17 @@ SHELL := /bin/bash
filechk_gen_header = $<
core-y += $(ARCH_DIR)/kernel/ \
- $(ARCH_DIR)/drivers/ \
- $(ARCH_DIR)/sys-$(SUBARCH)/
+ $(ARCH_DIR)/drivers/
+
+clean-dirs := sys-$(SUBARCH)
# Have to precede the include because the included Makefiles reference them.
SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
- arch-signal.h module.h
+ arch-signal.h module.h vm-flags.h
SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
+CLEAN_FILES += $(ARCH_SYMLINKS)
+
ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
$(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
@@ -38,6 +41,9 @@ SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)
include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)
+core-y += $(SUBARCH_CORE)
+libs-y += $(SUBARCH_LIBS)
+
# -Derrno=kernel_errno - This turns all kernel references to errno into
# kernel_errno to separate them from the libc errno. This allows -fno-common
# in CFLAGS. Otherwise, it would cause ld to complain about the two different
@@ -77,6 +83,11 @@ define archhelp
echo ' find in the kernel root.'
endef
+$(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch)
+
+CLEAN_FILES += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h \
+ $(TOPDIR)/$(ARCH_DIR)/os
+
prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \
$(ARCH_DIR)/kernel/vmlinux.lds.S
@@ -137,7 +148,8 @@ USER_CFLAGS += -D_GNU_SOURCE
#When cleaning we don't include .config, so we don't include
#TT or skas makefiles and don't clean skas_ptregs.h.
CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
- $(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h
+ $(GEN_HEADERS) $(ARCH_DIR)/include/skas_ptregs.h \
+ $(ARCH_DIR)/util/mk_constants $(ARCH_DIR)/util/mk_task
MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
$(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) $(ARCH_DIR)/os
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 7c7d008478b691..97b223bfa78e57 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -1,8 +1,6 @@
-ifeq ($(CONFIG_HOST_2G_2G), y)
-TOP_ADDR := 0x80000000
-else
-TOP_ADDR := 0xc0000000
-endif
+SUBARCH_CORE := arch/um/sys-i386/
+
+TOP_ADDR := $(CONFIG_TOP_ADDR)
ifeq ($(CONFIG_MODE_SKAS),y)
ifneq ($(CONFIG_MODE_TT),y)
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64
index 705df73454c821..9638cac9316509 100644
--- a/arch/um/Makefile-x86_64
+++ b/arch/um/Makefile-x86_64
@@ -1 +1,36 @@
+# Copyright 2003 - 2004 Pathscale, Inc
+# Released under the GPL
+
+SUBARCH_LIBS := arch/um/sys-x86_64/
+START := 0x60000000
+
+CFLAGS += -U__$(SUBARCH)__ -fno-builtin
ARCH_USER_CFLAGS := -D__x86_64__
+
+ELF_ARCH := i386:x86-64
+ELF_FORMAT := elf64-x86-64
+
+SYS_UTIL_DIR := $(ARCH_DIR)/sys-x86_64/util
+SYS_DIR := $(ARCH_DIR)/include/sysdep-x86_64
+
+SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
+
+prepare: $(SYS_HEADERS)
+
+$(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
+ $(call filechk,gen_header)
+
+$(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
+ $(call filechk,gen_header)
+
+$(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE
+ $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
+
+$(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE
+ $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
+
+CLEAN_FILES += $(SYS_HEADERS)
+
+LIBC_DIR := /usr/lib64
+
+export LIBC_DIR
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 708878e397a918..66f902a9907b10 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -17,6 +17,7 @@ CONFIG_GENERIC_CALIBRATE_DELAY=y
#
CONFIG_MODE_TT=y
CONFIG_MODE_SKAS=y
+# CONFIG_3_LEVEL_PGTABLES is not set
CONFIG_NET=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
@@ -91,13 +92,12 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
CONFIG_STDERR_CONSOLE=y
CONFIG_STDIO_CONSOLE=y
CONFIG_SSL=y
-CONFIG_FD_CHAN=y
CONFIG_NULL_CHAN=y
CONFIG_PORT_CHAN=y
CONFIG_PTY_CHAN=y
CONFIG_TTY_CHAN=y
CONFIG_XTERM_CHAN=y
-# CONFIG_NOCONFIG_CHAN is not set
+CONFIG_NOCONFIG_CHAN=y
CONFIG_CON_ZERO_CHAN="fd:0,fd:1"
CONFIG_CON_CHAN="xterm"
CONFIG_SSL_CHAN="pty"
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index 3a3ac38017f4fc..e94da95ffdcfa8 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -20,7 +20,7 @@ ubd-objs := ubd_kern.o ubd_user.o
port-objs := port_kern.o port_user.o
harddog-objs := harddog_kern.o harddog_user.o
-obj-y := stdio_console.o $(CHAN_OBJS)
+obj-y := stdio_console.o fd.o $(CHAN_OBJS)
obj-$(CONFIG_SSL) += ssl.o
obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
@@ -34,7 +34,6 @@ obj-$(CONFIG_MCONSOLE) += mconsole.o
obj-$(CONFIG_MMAPPER) += mmapper_kern.o
obj-$(CONFIG_BLK_DEV_UBD) += ubd.o
obj-$(CONFIG_HOSTAUDIO) += hostaudio.o
-obj-$(CONFIG_FD_CHAN) += fd.o
obj-$(CONFIG_NULL_CHAN) += null.o
obj-$(CONFIG_PORT_CHAN) += port.o
obj-$(CONFIG_PTY_CHAN) += pty.o
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index bf4bb736e6afac..f30ae1b0bcc04b 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -399,11 +399,7 @@ struct chan_type {
};
struct chan_type chan_table[] = {
-#ifdef CONFIG_FD_CHAN
{ "fd", &fd_ops },
-#else
- { "fd", &not_configged_ops },
-#endif
#ifdef CONFIG_NULL_CHAN
{ "null", &null_ops },
diff --git a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
index 19517312aa863d..4fcbe8b1b77e11 100644
--- a/arch/um/drivers/cow.h
+++ b/arch/um/drivers/cow.h
@@ -21,11 +21,12 @@ extern int file_reader(__u64 offset, char *buf, int len, void *arg);
extern int read_cow_header(int (*reader)(__u64, char *, int, void *),
void *arg, __u32 *version_out,
char **backing_file_out, time_t *mtime_out,
- __u64 *size_out, int *sectorsize_out,
+ unsigned long long *size_out, int *sectorsize_out,
__u32 *align_out, int *bitmap_offset_out);
extern int write_cow_header(char *cow_file, int fd, char *backing_file,
- int sectorsize, int alignment, long long *size);
+ int sectorsize, int alignment,
+ unsigned long long *size);
extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
int bitmap_offset, unsigned long *bitmap_len_out,
diff --git a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
index ce251f08305fe6..c83fc5d68936d1 100644
--- a/arch/um/drivers/cow_sys.h
+++ b/arch/um/drivers/cow_sys.h
@@ -23,12 +23,12 @@ static inline char *cow_strdup(char *str)
return(uml_strdup(str));
}
-static inline int cow_seek_file(int fd, __u64 offset)
+static inline int cow_seek_file(int fd, unsigned long long offset)
{
return(os_seek_file(fd, offset));
}
-static inline int cow_file_size(char *file, __u64 *size_out)
+static inline int cow_file_size(char *file, unsigned long long *size_out)
{
return(os_file_size(file, size_out));
}
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 122664b6b16ada..c43425c1ee1f25 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -159,7 +159,7 @@ static int absolutize(char *to, int size, char *from)
}
int write_cow_header(char *cow_file, int fd, char *backing_file,
- int sectorsize, int alignment, long long *size)
+ int sectorsize, int alignment, unsigned long long *size)
{
struct cow_header_v3 *header;
unsigned long modtime;
@@ -236,7 +236,7 @@ int file_reader(__u64 offset, char *buf, int len, void *arg)
int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
__u32 *version_out, char **backing_file_out,
- time_t *mtime_out, __u64 *size_out,
+ time_t *mtime_out, unsigned long long *size_out,
int *sectorsize_out, __u32 *align_out,
int *bitmap_offset_out)
{
@@ -329,7 +329,7 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
int alignment, int *bitmap_offset_out,
unsigned long *bitmap_len_out, int *data_offset_out)
{
- __u64 size, offset;
+ unsigned long long size, offset;
char zero = 0;
int err;
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 73d6e3e0af51d8..baa9f7f46bc30a 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -198,6 +198,37 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
ret = 0;
switch(cmd) {
+#ifdef TIOCGETP
+ case TIOCGETP:
+ case TIOCSETP:
+ case TIOCSETN:
+#endif
+#ifdef TIOCGETC
+ case TIOCGETC:
+ case TIOCSETC:
+#endif
+#ifdef TIOCGLTC
+ case TIOCGLTC:
+ case TIOCSLTC:
+#endif
+ case TCGETS:
+ case TCSETSF:
+ case TCSETSW:
+ case TCSETS:
+ case TCGETA:
+ case TCSETAF:
+ case TCSETAW:
+ case TCSETA:
+ case TCXONC:
+ case TCFLSH:
+ case TIOCOUTQ:
+ case TIOCINQ:
+ case TIOCGLCKTRMIOS:
+ case TIOCSLCKTRMIOS:
+ case TIOCPKT:
+ case TIOCGSOFTCAR:
+ case TIOCSSOFTCAR:
+ return -ENOIOCTLCMD;
#if 0
case TCwhatever:
/* do something */
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 0c87589c078134..ecbabd351c6d3f 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -73,11 +73,12 @@ DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
static irqreturn_t mconsole_interrupt(int irq, void *dev_id,
struct pt_regs *regs)
{
- int fd;
+ /* long to avoid size mismatch warnings from gcc */
+ long fd;
struct mconsole_entry *new;
struct mc_request req;
- fd = (int) dev_id;
+ fd = (long) dev_id;
while (mconsole_get_request(fd, &req)){
if(req.cmd->context == MCONSOLE_INTR)
(*req.cmd->handler)(&req);
@@ -457,7 +458,9 @@ static char *notify_socket = NULL;
int mconsole_init(void)
{
- int err, sock;
+ /* long to avoid size mismatch warnings from gcc */
+ long sock;
+ int err;
char file[256];
if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
@@ -496,7 +499,7 @@ int mconsole_init(void)
__initcall(mconsole_init);
-static int write_proc_mconsole(struct file *file, const char *buffer,
+static int write_proc_mconsole(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char *buf;
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 1546b0429ce22e..a63231dffe058e 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -8,6 +8,8 @@
* Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
*
*/
+
+#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/time.h>
#include <linux/devfs_fs_kernel.h>
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index f05c2b7514f212..17d85730086b81 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -172,7 +172,7 @@ static struct proc_dir_entry *proc_ide = NULL;
static void make_proc_ide(void)
{
- proc_ide_root = proc_mkdir("ide", 0);
+ proc_ide_root = proc_mkdir("ide", NULL);
proc_ide = proc_mkdir("ide0", proc_ide_root);
}
@@ -1087,7 +1087,7 @@ static void do_ubd_request(request_queue_t *q)
static int ubd_ioctl(struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{
- struct hd_geometry *loc = (struct hd_geometry *) arg;
+ struct hd_geometry __user *loc = (struct hd_geometry __user *) arg;
struct ubd *dev = inode->i_bdev->bd_disk->private_data;
struct hd_driveid ubd_id = {
.cyls = 0,
@@ -1108,19 +1108,19 @@ static int ubd_ioctl(struct inode * inode, struct file * file,
case HDIO_GET_IDENTITY:
ubd_id.cyls = dev->size / (128 * 32 * 512);
- if(copy_to_user((char *) arg, (char *) &ubd_id,
+ if(copy_to_user((char __user *) arg, (char *) &ubd_id,
sizeof(ubd_id)))
return(-EFAULT);
return(0);
case CDROMVOLREAD:
- if(copy_from_user(&volume, (char *) arg, sizeof(volume)))
+ if(copy_from_user(&volume, (char __user *) arg, sizeof(volume)))
return(-EFAULT);
volume.channel0 = 255;
volume.channel1 = 255;
volume.channel2 = 255;
volume.channel3 = 255;
- if(copy_to_user((char *) arg, &volume, sizeof(volume)))
+ if(copy_to_user((char __user *) arg, &volume, sizeof(volume)))
return(-EFAULT);
return(0);
}
diff --git a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
index 882d2f7c1ee72a..c6d8ffa5641b52 100644
--- a/arch/um/drivers/ubd_user.c
+++ b/arch/um/drivers/ubd_user.c
@@ -107,7 +107,7 @@ int open_ubd_file(char *file, struct openflags *openflags,
int *create_cow_out)
{
time_t mtime;
- __u64 size;
+ unsigned long long size;
__u32 version, align;
char *backing_file;
int fd, err, sectorsize, same, mode = 0644;
diff --git a/arch/um/include/process.h b/arch/um/include/process.h
index 07af218574fdf3..5af9157ff54fb0 100644
--- a/arch/um/include/process.h
+++ b/arch/um/include/process.h
@@ -6,7 +6,7 @@
#ifndef __PROCESS_H__
#define __PROCESS_H__
-#include <asm/sigcontext.h>
+#include <signal.h>
extern void sig_handler(int sig, struct sigcontext sc);
extern void alarm_handler(int sig, struct sigcontext sc);
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
new file mode 100644
index 00000000000000..87899df0072f81
--- /dev/null
+++ b/arch/um/include/registers.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#ifndef __REGISTERS_H
+#define __REGISTERS_H
+
+#include "sysdep/ptrace.h"
+
+extern void init_thread_registers(union uml_pt_regs *to);
+extern void save_registers(int pid, union uml_pt_regs *regs);
+extern void restore_registers(int pid, union uml_pt_regs *regs);
+extern void init_registers(int pid);
+
+#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/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index fc8e4f314ca6f1..dc126e5e25ac50 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -9,11 +9,52 @@
#include "uml-config.h"
#ifdef UML_CONFIG_MODE_TT
-#include "ptrace-tt.h"
+#include "sysdep/sc.h"
#endif
#ifdef UML_CONFIG_MODE_SKAS
-#include "ptrace-skas.h"
+
+/* syscall emulation path in ptrace */
+
+#ifndef PTRACE_SYSEMU
+#define PTRACE_SYSEMU 31
+#endif
+
+void set_using_sysemu(int value);
+int get_using_sysemu(void);
+extern int sysemu_supported;
+
+#include "skas_ptregs.h"
+
+#define HOST_FRAME_SIZE 17
+
+#define REGS_IP(r) ((r)[HOST_IP])
+#define REGS_SP(r) ((r)[HOST_SP])
+#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
+#define REGS_EAX(r) ((r)[HOST_EAX])
+#define REGS_EBX(r) ((r)[HOST_EBX])
+#define REGS_ECX(r) ((r)[HOST_ECX])
+#define REGS_EDX(r) ((r)[HOST_EDX])
+#define REGS_ESI(r) ((r)[HOST_ESI])
+#define REGS_EDI(r) ((r)[HOST_EDI])
+#define REGS_EBP(r) ((r)[HOST_EBP])
+#define REGS_CS(r) ((r)[HOST_CS])
+#define REGS_SS(r) ((r)[HOST_SS])
+#define REGS_DS(r) ((r)[HOST_DS])
+#define REGS_ES(r) ((r)[HOST_ES])
+#define REGS_FS(r) ((r)[HOST_FS])
+#define REGS_GS(r) ((r)[HOST_GS])
+
+#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
+
+#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
+
+#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
+
+#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
+
+#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
+
#endif
#ifndef PTRACE_SYSEMU_SINGLESTEP
#define PTRACE_SYSEMU_SINGLESTEP 32
diff --git a/arch/um/kernel/tt/include/ptrace-tt.h b/arch/um/include/sysdep-i386/signal.h
index 3084c1db867863..b1e1f7a7749992 100644
--- a/arch/um/kernel/tt/include/ptrace-tt.h
+++ b/arch/um/include/sysdep-i386/signal.h
@@ -1,16 +1,15 @@
-/*
- * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
+/*
+ * Copyright (C) 2004 PathScale, Inc
* Licensed under the GPL
*/
-#ifndef __PTRACE_TT_H
-#define __PTRACE_TT_H
+#ifndef __I386_SIGNAL_H_
+#define __I386_SIGNAL_H_
-#include "uml-config.h"
+#include <signal.h>
-#ifdef UML_CONFIG_MODE_TT
-#include "sysdep/sc.h"
-#endif
+#define ARCH_GET_SIGCONTEXT(sc, sig) \
+ do sc = (struct sigcontext *) (&sig + 1); while(0)
#endif
diff --git a/arch/um/include/sysdep-i386/syscalls.h b/arch/um/include/sysdep-i386/syscalls.h
index 47687dcf2b51be..36d9beec431b8b 100644
--- a/arch/um/include/sysdep-i386/syscalls.h
+++ b/arch/um/include/sysdep-i386/syscalls.h
@@ -8,11 +8,70 @@
typedef long syscall_handler_t(struct pt_regs);
+/* Not declared on x86, incompatible declarations on x86_64, so these have
+ * to go here rather than in sys_call_table.c
+ */
+extern syscall_handler_t sys_ptrace;
+extern syscall_handler_t sys_rt_sigaction;
+
+extern syscall_handler_t old_mmap_i386;
+
#define EXECUTE_SYSCALL(syscall, regs) \
((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(&regs->regs))
+extern long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff);
+
#define ARCH_SYSCALLS \
+ [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, \
+ [ __NR_break ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_oldstat ] = (syscall_handler_t *) sys_stat, \
+ [ __NR_umount ] = (syscall_handler_t *) sys_oldumount, \
+ [ __NR_stime ] = um_stime, \
+ [ __NR_oldfstat ] = (syscall_handler_t *) sys_fstat, \
+ [ __NR_stty ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_gtty ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_nice ] = (syscall_handler_t *) sys_nice, \
+ [ __NR_ftime ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_prof ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_signal ] = (syscall_handler_t *) sys_signal, \
+ [ __NR_lock ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_mpx ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_ulimit ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_oldolduname ] = (syscall_handler_t *) sys_olduname, \
+ [ __NR_sigaction ] = (syscall_handler_t *) sys_sigaction, \
+ [ __NR_sgetmask ] = (syscall_handler_t *) sys_sgetmask, \
+ [ __NR_ssetmask ] = (syscall_handler_t *) sys_ssetmask, \
+ [ __NR_sigsuspend ] = (syscall_handler_t *) sys_sigsuspend, \
+ [ __NR_sigpending ] = (syscall_handler_t *) sys_sigpending, \
+ [ __NR_oldlstat ] = (syscall_handler_t *) sys_lstat, \
+ [ __NR_readdir ] = old_readdir, \
+ [ __NR_profil ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_socketcall ] = (syscall_handler_t *) sys_socketcall, \
+ [ __NR_olduname ] = (syscall_handler_t *) sys_uname, \
+ [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_idle ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_ipc ] = (syscall_handler_t *) sys_ipc, \
+ [ __NR_sigreturn ] = (syscall_handler_t *) sys_sigreturn, \
+ [ __NR_sigprocmask ] = (syscall_handler_t *) sys_sigprocmask, \
+ [ __NR_bdflush ] = (syscall_handler_t *) sys_bdflush, \
+ [ __NR__llseek ] = (syscall_handler_t *) sys_llseek, \
+ [ __NR__newselect ] = (syscall_handler_t *) sys_select, \
+ [ __NR_vm86 ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_mmap ] = (syscall_handler_t *) old_mmap_i386, \
+ [ __NR_ugetrlimit ] = (syscall_handler_t *) sys_getrlimit, \
+ [ __NR_mmap2 ] = (syscall_handler_t *) sys_mmap2, \
+ [ __NR_truncate64 ] = (syscall_handler_t *) sys_truncate64, \
+ [ __NR_ftruncate64 ] = (syscall_handler_t *) sys_ftruncate64, \
+ [ __NR_stat64 ] = (syscall_handler_t *) sys_stat64, \
+ [ __NR_lstat64 ] = (syscall_handler_t *) sys_lstat64, \
+ [ __NR_fstat64 ] = (syscall_handler_t *) sys_fstat64, \
+ [ __NR_fcntl64 ] = (syscall_handler_t *) sys_fcntl64, \
+ [ __NR_sendfile64 ] = (syscall_handler_t *) sys_sendfile64, \
+ [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64, \
+ [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64, \
+ [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64, \
[ __NR_select ] = (syscall_handler_t *) old_select, \
[ __NR_vm86old ] = (syscall_handler_t *) sys_ni_syscall, \
[ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
@@ -38,11 +97,19 @@ typedef long syscall_handler_t(struct pt_regs);
[ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
[ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
[ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
- [ 222 ] = (syscall_handler_t *) sys_ni_syscall,
+ [ 222 ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
+ [ 251 ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
+ [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
+ [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall,
/* 222 doesn't yet have a name in include/asm-i386/unistd.h */
-#define LAST_ARCH_SYSCALL 222
+#define LAST_ARCH_SYSCALL __NR_vserver
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/include/sysdep-ppc/syscalls.h b/arch/um/include/sysdep-ppc/syscalls.h
index d703d0d12c7e24..679df351e19b6b 100644
--- a/arch/um/include/sysdep-ppc/syscalls.h
+++ b/arch/um/include/sysdep-ppc/syscalls.h
@@ -34,9 +34,12 @@ int old_mmap(unsigned long addr, unsigned long len,
[ __NR_multiplexer ] = sys_ni_syscall, \
[ __NR_mmap ] = old_mmap, \
[ __NR_madvise ] = sys_madvise, \
- [ __NR_mincore ] = sys_mincore,
+ [ __NR_mincore ] = sys_mincore, \
+ [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
+ [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64,
-#define LAST_ARCH_SYSCALL __NR_mincore
+#define LAST_ARCH_SYSCALL __NR_fadvise64
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h
new file mode 100644
index 00000000000000..d57aa7f3130ea6
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/checksum.h
@@ -0,0 +1,151 @@
+/*
+ * Licensed under the GPL
+ */
+
+#ifndef __UM_SYSDEP_CHECKSUM_H
+#define __UM_SYSDEP_CHECKSUM_H
+
+#include "linux/string.h"
+#include "linux/in6.h"
+#include "asm/uaccess.h"
+
+extern unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
+ int sum, int *err_ptr);
+extern unsigned csum_partial(const unsigned char *buff, unsigned len,
+ unsigned sum);
+
+/*
+ * Note: when you get a NULL pointer exception here this means someone
+ * passed in an incorrect kernel address to one of these functions.
+ *
+ * If you use these functions directly please don't forget the
+ * verify_area().
+ */
+
+static __inline__
+unsigned int csum_partial_copy_nocheck(const char *src, char *dst,
+ int len, int sum)
+{
+ memcpy(dst, src, len);
+ return(csum_partial(dst, len, sum));
+}
+
+static __inline__
+unsigned int csum_partial_copy_from_user(const char *src, char *dst,
+ int len, int sum, int *err_ptr)
+{
+ return csum_partial_copy_from(src, dst, len, sum, err_ptr);
+}
+
+/**
+ * csum_fold - Fold and invert a 32bit checksum.
+ * sum: 32bit unfolded sum
+ *
+ * Fold a 32bit running checksum to 16bit and invert it. This is usually
+ * the last step before putting a checksum into a packet.
+ * Make sure not to mix with 64bit checksums.
+ */
+static inline unsigned int csum_fold(unsigned int sum)
+{
+ __asm__(
+ " addl %1,%0\n"
+ " adcl $0xffff,%0"
+ : "=r" (sum)
+ : "r" (sum << 16), "0" (sum & 0xffff0000)
+ );
+ return (~sum) >> 16;
+}
+
+/**
+ * csum_tcpup_nofold - Compute an IPv4 pseudo header checksum.
+ * @saddr: source address
+ * @daddr: destination address
+ * @len: length of packet
+ * @proto: ip protocol of packet
+ * @sum: initial sum to be added in (32bit unfolded)
+ *
+ * Returns the pseudo header checksum the input data. Result is
+ * 32bit unfolded.
+ */
+static inline unsigned long
+csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len,
+ unsigned short proto, unsigned int sum)
+{
+ asm(" addl %1, %0\n"
+ " adcl %2, %0\n"
+ " adcl %3, %0\n"
+ " adcl $0, %0\n"
+ : "=r" (sum)
+ : "g" (daddr), "g" (saddr), "g" ((ntohs(len)<<16)+proto*256), "0" (sum));
+ return sum;
+}
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr,
+ unsigned long daddr,
+ unsigned short len,
+ unsigned short proto,
+ unsigned int sum)
+{
+ return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum));
+}
+
+/**
+ * ip_fast_csum - Compute the IPv4 header checksum efficiently.
+ * iph: ipv4 header
+ * ihl: length of header / 4
+ */
+static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
+{
+ unsigned int sum;
+
+ asm( " movl (%1), %0\n"
+ " subl $4, %2\n"
+ " jbe 2f\n"
+ " addl 4(%1), %0\n"
+ " adcl 8(%1), %0\n"
+ " adcl 12(%1), %0\n"
+ "1: adcl 16(%1), %0\n"
+ " lea 4(%1), %1\n"
+ " decl %2\n"
+ " jne 1b\n"
+ " adcl $0, %0\n"
+ " movl %0, %2\n"
+ " shrl $16, %0\n"
+ " addw %w2, %w0\n"
+ " adcl $0, %0\n"
+ " notl %0\n"
+ "2:"
+ /* Since the input registers which are loaded with iph and ipl
+ are modified, we must also specify them as outputs, or gcc
+ will assume they contain their original values. */
+ : "=r" (sum), "=r" (iph), "=r" (ihl)
+ : "1" (iph), "2" (ihl)
+ : "memory");
+ return(sum);
+}
+
+static inline unsigned add32_with_carry(unsigned a, unsigned b)
+{
+ asm("addl %2,%0\n\t"
+ "adcl $0,%0"
+ : "=r" (a)
+ : "0" (a), "r" (b));
+ return a;
+}
+
+#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/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
new file mode 100644
index 00000000000000..64b1cc16752df5
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_PTRACE_H
+#define __SYSDEP_X86_64_PTRACE_H
+
+#include "uml-config.h"
+
+#ifdef UML_CONFIG_MODE_TT
+#include "sysdep/sc.h"
+#endif
+
+#ifdef UML_CONFIG_MODE_SKAS
+#include "skas_ptregs.h"
+
+#define REGS_IP(r) ((r)[HOST_IP])
+#define REGS_SP(r) ((r)[HOST_SP])
+
+#define REGS_RBX(r) ((r)[HOST_RBX])
+#define REGS_RCX(r) ((r)[HOST_RCX])
+#define REGS_RDX(r) ((r)[HOST_RDX])
+#define REGS_RSI(r) ((r)[HOST_RSI])
+#define REGS_RDI(r) ((r)[HOST_RDI])
+#define REGS_RBP(r) ((r)[HOST_RBP])
+#define REGS_RAX(r) ((r)[HOST_RAX])
+#define REGS_R8(r) ((r)[HOST_R8])
+#define REGS_R9(r) ((r)[HOST_R9])
+#define REGS_R10(r) ((r)[HOST_R10])
+#define REGS_R11(r) ((r)[HOST_R11])
+#define REGS_R12(r) ((r)[HOST_R12])
+#define REGS_R13(r) ((r)[HOST_R13])
+#define REGS_R14(r) ((r)[HOST_R14])
+#define REGS_R15(r) ((r)[HOST_R15])
+#define REGS_CS(r) ((r)[HOST_CS])
+#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
+#define REGS_SS(r) ((r)[HOST_SS])
+
+#define HOST_FS_BASE 21
+#define HOST_GS_BASE 22
+#define HOST_DS 23
+#define HOST_ES 24
+#define HOST_FS 25
+#define HOST_GS 26
+
+#define REGS_FS_BASE(r) ((r)[HOST_FS_BASE])
+#define REGS_GS_BASE(r) ((r)[HOST_GS_BASE])
+#define REGS_DS(r) ((r)[HOST_DS])
+#define REGS_ES(r) ((r)[HOST_ES])
+#define REGS_FS(r) ((r)[HOST_FS])
+#define REGS_GS(r) ((r)[HOST_GS])
+
+#define REGS_ORIG_RAX(r) ((r)[HOST_ORIG_RAX])
+
+#define REGS_SET_SYSCALL_RETURN(r, res) REGS_RAX(r) = (res)
+
+#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
+
+#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
+
+#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
+
+#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
+
+#define REGS_TRAP(r) ((r)->trap_type)
+
+#define REGS_ERR(r) ((r)->fault_type)
+
+#endif
+
+#include "choose-mode.h"
+
+/* XXX */
+union uml_pt_regs {
+#ifdef UML_CONFIG_MODE_TT
+ struct tt_regs {
+ long syscall;
+ unsigned long orig_rax;
+ void *sc;
+ } tt;
+#endif
+#ifdef UML_CONFIG_MODE_SKAS
+ struct skas_regs {
+ /* XXX */
+ unsigned long regs[27];
+ unsigned long fp[65];
+ unsigned long fault_addr;
+ unsigned long fault_type;
+ unsigned long trap_type;
+ long syscall;
+ int is_user;
+ } skas;
+#endif
+};
+
+#define EMPTY_UML_PT_REGS { }
+
+/* XXX */
+extern int mode_tt;
+
+#define UPT_RBX(r) CHOOSE_MODE(SC_RBX(UPT_SC(r)), REGS_RBX((r)->skas.regs))
+#define UPT_RCX(r) CHOOSE_MODE(SC_RCX(UPT_SC(r)), REGS_RCX((r)->skas.regs))
+#define UPT_RDX(r) CHOOSE_MODE(SC_RDX(UPT_SC(r)), REGS_RDX((r)->skas.regs))
+#define UPT_RSI(r) CHOOSE_MODE(SC_RSI(UPT_SC(r)), REGS_RSI((r)->skas.regs))
+#define UPT_RDI(r) CHOOSE_MODE(SC_RDI(UPT_SC(r)), REGS_RDI((r)->skas.regs))
+#define UPT_RBP(r) CHOOSE_MODE(SC_RBP(UPT_SC(r)), REGS_RBP((r)->skas.regs))
+#define UPT_RAX(r) CHOOSE_MODE(SC_RAX(UPT_SC(r)), REGS_RAX((r)->skas.regs))
+#define UPT_R8(r) CHOOSE_MODE(SC_R8(UPT_SC(r)), REGS_R8((r)->skas.regs))
+#define UPT_R9(r) CHOOSE_MODE(SC_R9(UPT_SC(r)), REGS_R9((r)->skas.regs))
+#define UPT_R10(r) CHOOSE_MODE(SC_R10(UPT_SC(r)), REGS_R10((r)->skas.regs))
+#define UPT_R11(r) CHOOSE_MODE(SC_R11(UPT_SC(r)), REGS_R11((r)->skas.regs))
+#define UPT_R12(r) CHOOSE_MODE(SC_R12(UPT_SC(r)), REGS_R12((r)->skas.regs))
+#define UPT_R13(r) CHOOSE_MODE(SC_R13(UPT_SC(r)), REGS_R13((r)->skas.regs))
+#define UPT_R14(r) CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs))
+#define UPT_R15(r) CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs))
+#define UPT_CS(r) CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
+#define UPT_FS(r) CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
+#define UPT_GS(r) CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
+#define UPT_DS(r) CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
+#define UPT_ES(r) CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
+#define UPT_CS(r) CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
+#define UPT_ORIG_RAX(r) \
+ CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs))
+
+#define UPT_IP(r) CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
+#define UPT_SP(r) CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
+
+#define UPT_EFLAGS(r) \
+ CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
+#define UPT_SC(r) ((r)->tt.sc)
+#define UPT_SYSCALL_NR(r) CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
+
+extern int user_context(unsigned long sp);
+
+#define UPT_IS_USER(r) \
+ CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
+
+#define UPT_SYSCALL_ARG1(r) UPT_RDI(r)
+#define UPT_SYSCALL_ARG2(r) UPT_RSI(r)
+#define UPT_SYSCALL_ARG3(r) UPT_RDX(r)
+#define UPT_SYSCALL_ARG4(r) UPT_R10(r)
+#define UPT_SYSCALL_ARG5(r) UPT_R8(r)
+#define UPT_SYSCALL_ARG6(r) UPT_R9(r)
+
+struct syscall_args {
+ unsigned long args[6];
+};
+
+#define SYSCALL_ARGS(r) ((struct syscall_args) \
+ { .args = { UPT_SYSCALL_ARG1(r), \
+ UPT_SYSCALL_ARG2(r), \
+ UPT_SYSCALL_ARG3(r), \
+ UPT_SYSCALL_ARG4(r), \
+ UPT_SYSCALL_ARG5(r), \
+ UPT_SYSCALL_ARG6(r) } } )
+
+#define UPT_REG(regs, reg) \
+ ({ unsigned long val; \
+ switch(reg){ \
+ case R8: val = UPT_R8(regs); break; \
+ case R9: val = UPT_R9(regs); break; \
+ case R10: val = UPT_R10(regs); break; \
+ case R11: val = UPT_R11(regs); break; \
+ case R12: val = UPT_R12(regs); break; \
+ case R13: val = UPT_R13(regs); break; \
+ case R14: val = UPT_R14(regs); break; \
+ case R15: val = UPT_R15(regs); break; \
+ case RIP: val = UPT_IP(regs); break; \
+ case RSP: val = UPT_SP(regs); break; \
+ case RAX: val = UPT_RAX(regs); break; \
+ case RBX: val = UPT_RBX(regs); break; \
+ case RCX: val = UPT_RCX(regs); break; \
+ case RDX: val = UPT_RDX(regs); break; \
+ case RSI: val = UPT_RSI(regs); break; \
+ case RDI: val = UPT_RDI(regs); break; \
+ case RBP: val = UPT_RBP(regs); break; \
+ case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
+ case CS: val = UPT_CS(regs); break; \
+ case DS: val = UPT_DS(regs); break; \
+ case ES: val = UPT_ES(regs); break; \
+ case FS: val = UPT_FS(regs); break; \
+ case GS: val = UPT_GS(regs); break; \
+ case EFLAGS: val = UPT_EFLAGS(regs); break; \
+ default : \
+ panic("Bad register in UPT_REG : %d\n", reg); \
+ val = -1; \
+ } \
+ val; \
+ })
+
+
+#define UPT_SET(regs, reg, val) \
+ ({ unsigned long val; \
+ switch(reg){ \
+ case R8: UPT_R8(regs) = val; break; \
+ case R9: UPT_R9(regs) = val; break; \
+ case R10: UPT_R10(regs) = val; break; \
+ case R11: UPT_R11(regs) = val; break; \
+ case R12: UPT_R12(regs) = val; break; \
+ case R13: UPT_R13(regs) = val; break; \
+ case R14: UPT_R14(regs) = val; break; \
+ case R15: UPT_R15(regs) = val; break; \
+ case RIP: UPT_IP(regs) = val; break; \
+ case RSP: UPT_SP(regs) = val; break; \
+ case RAX: UPT_RAX(regs) = val; break; \
+ case RBX: UPT_RBX(regs) = val; break; \
+ case RCX: UPT_RCX(regs) = val; break; \
+ case RDX: UPT_RDX(regs) = val; break; \
+ case RSI: UPT_RSI(regs) = val; break; \
+ case RDI: UPT_RDI(regs) = val; break; \
+ case RBP: UPT_RBP(regs) = val; break; \
+ case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \
+ case CS: UPT_CS(regs) = val; break; \
+ case DS: UPT_DS(regs) = val; break; \
+ case ES: UPT_ES(regs) = val; break; \
+ case FS: UPT_FS(regs) = val; break; \
+ case GS: UPT_GS(regs) = val; break; \
+ case EFLAGS: UPT_EFLAGS(regs) = val; break; \
+ default : \
+ panic("Bad register in UPT_SET : %d\n", reg); \
+ break; \
+ } \
+ val; \
+ })
+
+#define UPT_SET_SYSCALL_RETURN(r, res) \
+ CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \
+ REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
+
+#define UPT_RESTART_SYSCALL(r) \
+ CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
+ REGS_RESTART_SYSCALL((r)->skas.regs))
+
+#define UPT_SEGV_IS_FIXABLE(r) \
+ CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
+ REGS_SEGV_IS_FIXABLE(&r->skas))
+
+#define UPT_FAULT_ADDR(r) \
+ CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas))
+
+#define UPT_FAULT_WRITE(r) \
+ CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas))
+
+#define UPT_TRAP(r) CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas))
+#define UPT_ERR(r) CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas))
+
+#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/sysdep-x86_64/ptrace_user.h b/arch/um/include/sysdep-x86_64/ptrace_user.h
new file mode 100644
index 00000000000000..a7bb52bbe6240a
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/ptrace_user.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_PTRACE_USER_H__
+#define __SYSDEP_X86_64_PTRACE_USER_H__
+
+#define __FRAME_OFFSETS
+#include <asm/ptrace.h>
+#undef __FRAME_OFFSETS
+
+#define PT_INDEX(off) ((off) / sizeof(unsigned long))
+
+#define PT_SYSCALL_NR(regs) ((regs)[PT_INDEX(ORIG_RAX)])
+#define PT_SYSCALL_NR_OFFSET (ORIG_RAX)
+
+#define PT_SYSCALL_ARG1(regs) (((unsigned long *) (regs))[PT_INDEX(RDI)])
+#define PT_SYSCALL_ARG1_OFFSET (RDI)
+
+#define PT_SYSCALL_ARG2(regs) (((unsigned long *) (regs))[PT_INDEX(RSI)])
+#define PT_SYSCALL_ARG2_OFFSET (RSI)
+
+#define PT_SYSCALL_ARG3(regs) (((unsigned long *) (regs))[PT_INDEX(RDX)])
+#define PT_SYSCALL_ARG3_OFFSET (RDX)
+
+#define PT_SYSCALL_ARG4(regs) (((unsigned long *) (regs))[PT_INDEX(RCX)])
+#define PT_SYSCALL_ARG4_OFFSET (RCX)
+
+#define PT_SYSCALL_ARG5(regs) (((unsigned long *) (regs))[PT_INDEX(R8)])
+#define PT_SYSCALL_ARG5_OFFSET (R8)
+
+#define PT_SYSCALL_ARG6(regs) (((unsigned long *) (regs))[PT_INDEX(R9)])
+#define PT_SYSCALL_ARG6_OFFSET (R9)
+
+#define PT_SYSCALL_RET_OFFSET (RAX)
+
+#define PT_IP_OFFSET (RIP)
+#define PT_IP(regs) ((regs)[PT_INDEX(RIP)])
+
+#define PT_SP_OFFSET (RSP)
+#define PT_SP(regs) ((regs)[PT_INDEX(RSP)])
+
+#define PT_ORIG_RAX_OFFSET (ORIG_RAX)
+#define PT_ORIG_RAX(regs) ((regs)[PT_INDEX(ORIG_RAX)])
+
+#define MAX_REG_OFFSET (FRAME_SIZE)
+#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
+
+/* x86_64 FC3 doesn't define this in /usr/include/linux/ptrace.h even though
+ * it's defined in the kernel's include/linux/ptrace.h
+ */
+#ifndef PTRACE_SETOPTIONS
+#define PTRACE_SETOPTIONS 0x4200
+#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/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
new file mode 100644
index 00000000000000..6a0c346b640408
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_SIGCONTEXT_H
+#define __SYSDEP_X86_64_SIGCONTEXT_H
+
+#include "sc.h"
+
+#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
+
+#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
+#define SC_SET_SYSCALL_RETURN(sc, result) SC_RAX(sc) = (result)
+
+#define SC_FAULT_ADDR(sc) SC_CR2(sc)
+#define SC_FAULT_TYPE(sc) SC_ERR(sc)
+
+#define FAULT_WRITE(err) ((err) & 2)
+
+#define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc))
+
+#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc)
+
+/* ptrace expects that, at the start of a system call, %eax contains
+ * -ENOSYS, so this makes it so.
+ */
+
+#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
+
+#define SEGV_IS_FIXABLE(trap) ((trap) == 14)
+#define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc))
+
+extern unsigned long *sc_sigmask(void *sc_ptr);
+
+#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/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h
new file mode 100644
index 00000000000000..e5e52756fab4fb
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/signal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#ifndef __X86_64_SIGNAL_H_
+#define __X86_64_SIGNAL_H_
+
+#define ARCH_GET_SIGCONTEXT(sc, sig_addr) \
+ do { \
+ struct ucontext *__uc; \
+ asm("movq %%rdx, %0" : "=r" (__uc)); \
+ sc = (struct sigcontext *) &__uc->uc_mcontext; \
+ } 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/sysdep-x86_64/syscalls.h b/arch/um/include/sysdep-x86_64/syscalls.h
new file mode 100644
index 00000000000000..65fd494420f990
--- /dev/null
+++ b/arch/um/include/sysdep-x86_64/syscalls.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#ifndef __SYSDEP_X86_64_SYSCALLS_H__
+#define __SYSDEP_X86_64_SYSCALLS_H__
+
+#include <linux/msg.h>
+#include <linux/shm.h>
+
+typedef long syscall_handler_t(void);
+
+extern syscall_handler_t *ia32_sys_call_table[];
+
+#define EXECUTE_SYSCALL(syscall, regs) \
+ (((long (*)(long, long, long, long, long, long)) \
+ (*sys_call_table[syscall]))(UPT_SYSCALL_ARG1(&regs->regs), \
+ UPT_SYSCALL_ARG2(&regs->regs), \
+ UPT_SYSCALL_ARG3(&regs->regs), \
+ UPT_SYSCALL_ARG4(&regs->regs), \
+ UPT_SYSCALL_ARG5(&regs->regs), \
+ UPT_SYSCALL_ARG6(&regs->regs)))
+
+extern long old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff);
+extern syscall_handler_t wrap_sys_shmat;
+extern syscall_handler_t sys_modify_ldt;
+extern syscall_handler_t sys_arch_prctl;
+
+#define ARCH_SYSCALLS \
+ [ __NR_mmap ] = (syscall_handler_t *) old_mmap, \
+ [ __NR_select ] = (syscall_handler_t *) sys_select, \
+ [ __NR_mincore ] = (syscall_handler_t *) sys_mincore, \
+ [ __NR_madvise ] = (syscall_handler_t *) sys_madvise, \
+ [ __NR_shmget ] = (syscall_handler_t *) sys_shmget, \
+ [ __NR_shmat ] = (syscall_handler_t *) wrap_sys_shmat, \
+ [ __NR_shmctl ] = (syscall_handler_t *) sys_shmctl, \
+ [ __NR_semop ] = (syscall_handler_t *) sys_semop, \
+ [ __NR_semget ] = (syscall_handler_t *) sys_semget, \
+ [ __NR_semctl ] = (syscall_handler_t *) sys_semctl, \
+ [ __NR_shmdt ] = (syscall_handler_t *) sys_shmdt, \
+ [ __NR_msgget ] = (syscall_handler_t *) sys_msgget, \
+ [ __NR_msgsnd ] = (syscall_handler_t *) sys_msgsnd, \
+ [ __NR_msgrcv ] = (syscall_handler_t *) sys_msgrcv, \
+ [ __NR_msgctl ] = (syscall_handler_t *) sys_msgctl, \
+ [ __NR_pivot_root ] = (syscall_handler_t *) sys_pivot_root, \
+ [ __NR_tuxcall ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_security ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_epoll_ctl_old ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_epoll_wait_old ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_modify_ldt ] = (syscall_handler_t *) sys_modify_ldt, \
+ [ __NR_arch_prctl ] = (syscall_handler_t *) sys_arch_prctl, \
+ [ __NR_socket ] = (syscall_handler_t *) sys_socket, \
+ [ __NR_connect ] = (syscall_handler_t *) sys_connect, \
+ [ __NR_accept ] = (syscall_handler_t *) sys_accept, \
+ [ __NR_recvfrom ] = (syscall_handler_t *) sys_recvfrom, \
+ [ __NR_recvmsg ] = (syscall_handler_t *) sys_recvmsg, \
+ [ __NR_sendmsg ] = (syscall_handler_t *) sys_sendmsg, \
+ [ __NR_bind ] = (syscall_handler_t *) sys_bind, \
+ [ __NR_listen ] = (syscall_handler_t *) sys_listen, \
+ [ __NR_getsockname ] = (syscall_handler_t *) sys_getsockname, \
+ [ __NR_getpeername ] = (syscall_handler_t *) sys_getpeername, \
+ [ __NR_socketpair ] = (syscall_handler_t *) sys_socketpair, \
+ [ __NR_sendto ] = (syscall_handler_t *) sys_sendto, \
+ [ __NR_shutdown ] = (syscall_handler_t *) sys_shutdown, \
+ [ __NR_setsockopt ] = (syscall_handler_t *) sys_setsockopt, \
+ [ __NR_getsockopt ] = (syscall_handler_t *) sys_getsockopt, \
+ [ __NR_iopl ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_set_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_get_thread_area ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_remap_file_pages ] = (syscall_handler_t *) sys_remap_file_pages, \
+ [ __NR_semtimedop ] = (syscall_handler_t *) sys_semtimedop, \
+ [ __NR_fadvise64 ] = (syscall_handler_t *) sys_fadvise64, \
+ [ 223 ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ __NR_utimes ] = (syscall_handler_t *) sys_utimes, \
+ [ __NR_vserver ] = (syscall_handler_t *) sys_ni_syscall, \
+ [ 251 ] = (syscall_handler_t *) sys_ni_syscall,
+
+#define LAST_ARCH_SYSCALL 251
+#define NR_syscalls 1024
+
+#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/um_uaccess.h b/arch/um/include/um_uaccess.h
index 0924fcc95f1cf1..4eb302cbf8650d 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -20,19 +20,19 @@
#define access_ok(type, addr, size) \
CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
-static inline int verify_area(int type, const void * addr, unsigned long size)
+static inline int verify_area(int type, const void __user *addr, unsigned long size)
{
- return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
+ return (CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr,
size));
}
-static inline int copy_from_user(void *to, const void *from, int n)
+static inline int copy_from_user(void *to, const void __user *from, int n)
{
return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
from, n));
}
-static inline int copy_to_user(void *to, const void *from, int n)
+static inline int copy_to_user(void __user *to, const void *from, int n)
{
return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to,
from, n));
@@ -57,7 +57,7 @@ static inline int copy_to_user(void *to, const void *from, int n)
* and returns @count.
*/
-static inline int strncpy_from_user(char *dst, const char *src, int count)
+static inline int strncpy_from_user(char *dst, const char __user *src, int count)
{
return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
dst, src, count));
@@ -89,7 +89,7 @@ static inline int __clear_user(void *mem, int len)
* Returns number of bytes that could not be cleared.
* On success, this will be zero.
*/
-static inline int clear_user(void *mem, int len)
+static inline int clear_user(void __user *mem, int len)
{
return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
}
@@ -105,7 +105,7 @@ static inline int clear_user(void *mem, int len)
* On exception, returns 0.
* If the string is too long, returns a value greater than @n.
*/
-static inline int strnlen_user(const void *str, int len)
+static inline int strnlen_user(const void __user *str, long len)
{
return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
}
diff --git a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
index 785ccd51bbf526..f77eb642845385 100644
--- a/arch/um/include/uml_uaccess.h
+++ b/arch/um/include/uml_uaccess.h
@@ -7,7 +7,7 @@
#define __UML_UACCESS_H__
extern int __do_copy_to_user(void *to, const void *from, int n,
- void **fault_addr, void **fault_catcher);
+ void **fault_addr, void **fault_catcher);
extern unsigned long __do_user_copy(void *to, const void *from, int n,
void **fault_addr, void **fault_catcher,
void (*op)(void *to, const void *from,
diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c
index fa50a9b81ca204..669783580fe51c 100644
--- a/arch/um/kernel/checksum.c
+++ b/arch/um/kernel/checksum.c
@@ -2,16 +2,16 @@
#include "linux/errno.h"
#include "linux/module.h"
-extern unsigned int arch_csum_partial(const char *buff, int len, int sum);
+unsigned int arch_csum_partial(const char *buff, int len, int sum);
-extern unsigned int csum_partial(char *buff, int len, int sum)
+unsigned int csum_partial(char *buff, int len, int sum)
{
- return(arch_csum_partial(buff, len, sum));
+ return arch_csum_partial(buff, len, sum);
}
EXPORT_SYMBOL(csum_partial);
-unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
+unsigned int csum_partial_copy_to(const char *src, char __user *dst, int len,
int sum, int *err_ptr)
{
if(copy_to_user(dst, src, len)){
@@ -22,7 +22,7 @@ unsigned int csum_partial_copy_to(const char *src, char *dst, int len,
return(arch_csum_partial(src, len, sum));
}
-unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
+unsigned int csum_partial_copy_from(const char __user *src, char *dst, int len,
int sum, int *err_ptr)
{
if(copy_from_user(dst, src, len)){
@@ -30,7 +30,7 @@ unsigned int csum_partial_copy_from(const char *src, char *dst, int len,
return(-1);
}
- return(arch_csum_partial(dst, len, sum));
+ return arch_csum_partial(dst, len, sum);
}
/*
diff --git a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
index 4336240c179a4c..49ddabe69be74e 100644
--- a/arch/um/kernel/exec_kern.c
+++ b/arch/um/kernel/exec_kern.c
@@ -34,7 +34,8 @@ void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
extern void log_exec(char **argv, void *tty);
-static long execve1(char *file, char **argv, char **env)
+static long execve1(char *file, char __user * __user *argv,
+ char *__user __user *env)
{
long error;
@@ -51,7 +52,7 @@ static long execve1(char *file, char **argv, char **env)
return(error);
}
-long um_execve(char *file, char **argv, char **env)
+long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
{
long err;
@@ -61,13 +62,14 @@ long um_execve(char *file, char **argv, char **env)
return(err);
}
-long sys_execve(char *file, char **argv, char **env)
+long sys_execve(char *file, char __user *__user *argv,
+ char __user *__user *env)
{
long error;
char *filename;
lock_kernel();
- filename = getname((char *) file);
+ filename = getname((char __user *) file);
error = PTR_ERR(filename);
if (IS_ERR(filename)) goto out;
error = execve1(filename, argv, env);
diff --git a/arch/um/kernel/exitcode.c b/arch/um/kernel/exitcode.c
index 14a748e2e25a25..0ea87f24b36fde 100644
--- a/arch/um/kernel/exitcode.c
+++ b/arch/um/kernel/exitcode.c
@@ -27,7 +27,7 @@ static int read_proc_exitcode(char *page, char **start, off_t off,
return(len);
}
-static int write_proc_exitcode(struct file *file, const char *buffer,
+static int write_proc_exitcode(struct file *file, const char __user *buffer,
unsigned long count, void *data)
{
char *end, buf[sizeof("nnnnn\0")];
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 9d572b6ffd1dbb..ab7417b78c87b8 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -45,9 +45,8 @@ int show_interrupts(struct seq_file *p, void *v)
if (i == 0) {
seq_printf(p, " ");
- for (j=0; j<NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ",j);
+ for_each_cpu(j)
+ seq_printf(p, "CPU%d ",j);
seq_putc(p, '\n');
}
@@ -60,9 +59,8 @@ int show_interrupts(struct seq_file *p, void *v)
#ifndef CONFIG_SMP
seq_printf(p, "%10u ", kstat_irqs(i));
#else
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
+ for_each_cpu(j)
+ seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].handler->typename);
seq_printf(p, " %s", action->name);
@@ -154,13 +152,13 @@ void __init init_IRQ(void)
int i;
irq_desc[TIMER_IRQ].status = IRQ_DISABLED;
- irq_desc[TIMER_IRQ].action = 0;
+ irq_desc[TIMER_IRQ].action = NULL;
irq_desc[TIMER_IRQ].depth = 1;
irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type;
enable_irq(TIMER_IRQ);
for(i=1;i<NR_IRQS;i++){
irq_desc[i].status = IRQ_DISABLED;
- irq_desc[i].action = 0;
+ irq_desc[i].action = NULL;
irq_desc[i].depth = 1;
irq_desc[i].handler = &SIGIO_irq_type;
enable_irq(i);
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index 4279161c884905..b138eca53d0698 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -25,7 +25,7 @@ extern char __binary_start;
/* Changed during early boot */
unsigned long *empty_zero_page = NULL;
unsigned long *empty_bad_page = NULL;
-pgd_t swapper_pg_dir[1024];
+pgd_t swapper_pg_dir[PTRS_PER_PGD];
unsigned long highmem;
int kmalloc_ok = 0;
@@ -130,12 +130,13 @@ static void __init fixrange_init(unsigned long start, unsigned long end,
}
}
-#if CONFIG_HIGHMEM
+#ifdef CONFIG_HIGHMEM
pte_t *kmap_pte;
pgprot_t kmap_prot;
#define kmap_get_fixmap_pte(vaddr) \
- pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
+ pte_offset_kernel(pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)),\
+ (vaddr)), (vaddr))
void __init kmap_init(void)
{
@@ -172,6 +173,7 @@ static void init_highmem(void)
static void __init fixaddr_user_init( void)
{
+#if FIXADDR_USER_START != 0
long size = FIXADDR_USER_END - FIXADDR_USER_START;
pgd_t *pgd;
pmd_t *pmd;
@@ -191,6 +193,7 @@ static void __init fixaddr_user_init( void)
pte = pte_offset_kernel(pmd, vaddr);
pte_set_val( (*pte), paddr, PAGE_READONLY);
}
+#endif
}
void paging_init(void)
@@ -232,7 +235,7 @@ struct page *arch_validate(struct page *page, int mask, int order)
addr = (unsigned long) page_address(page);
for(i = 0; i < (1 << order); i++){
current->thread.fault_addr = (void *) addr;
- if(__do_copy_to_user((void *) addr, &zero,
+ if(__do_copy_to_user((void __user *) addr, &zero,
sizeof(zero),
&current->thread.fault_addr,
&current->thread.fault_catcher)){
@@ -241,6 +244,7 @@ struct page *arch_validate(struct page *page, int mask, int order)
}
addr += PAGE_SIZE;
}
+
if(i == (1 << order)) return(page);
page = alloc_pages(mask, order);
goto again;
@@ -335,7 +339,7 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
{
struct page *pte;
- pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
+ pte = alloc_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
return pte;
}
diff --git a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
index 33f71e76495177..4a663fd434bbaf 100644
--- a/arch/um/kernel/mem_user.c
+++ b/arch/um/kernel/mem_user.c
@@ -48,8 +48,6 @@
#include "tempfile.h"
#include "kern_constants.h"
-extern struct mem_region physmem_region;
-
#define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
static int create_tmp_file(unsigned long len)
@@ -135,7 +133,7 @@ static int create_anon_file(unsigned long len)
addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if(addr == MAP_FAILED){
- os_print_error((int) addr, "mapping physmem file");
+ perror("mapping physmem file");
exit(1);
}
munmap(addr, len);
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 3253bc0e3a5cad..2853028657b36b 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -309,7 +309,7 @@ struct page *__virt_to_page(const unsigned long virt)
return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
}
-unsigned long page_to_phys(struct page *page)
+phys_t page_to_phys(struct page *page)
{
return((page - mem_map) << PAGE_SHIFT);
}
@@ -318,8 +318,9 @@ pte_t mk_pte(struct page *page, pgprot_t pgprot)
{
pte_t pte;
- pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
- if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
+ pte_set_val(pte, page_to_phys(page), pgprot);
+ if(pte_present(pte))
+ pte_mknewprot(pte_mknewpage(pte));
return(pte);
}
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index 7460bd36e534e1..1e638b8131996f 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -13,14 +13,10 @@
#include <setjmp.h>
#include <sys/time.h>
#include <sys/ptrace.h>
-#include <linux/ptrace.h>
#include <sys/wait.h>
#include <sys/mman.h>
-#include <asm/ptrace.h>
-#include <asm/sigcontext.h>
#include <asm/unistd.h>
#include <asm/page.h>
-#include <asm/user.h>
#include "user_util.h"
#include "kern_util.h"
#include "user.h"
@@ -28,6 +24,7 @@
#include "signal_kern.h"
#include "signal_user.h"
#include "sysdep/ptrace.h"
+#include "sysdep/ptrace_user.h"
#include "sysdep/sigcontext.h"
#include "irq_user.h"
#include "ptrace_user.h"
@@ -40,6 +37,7 @@
#ifdef UML_CONFIG_MODE_SKAS
#include "skas.h"
#include "skas_ptrace.h"
+#include "registers.h"
#endif
void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
@@ -330,7 +328,7 @@ void __init check_ptrace(void)
CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
if(n < 0)
panic("check_ptrace : wait failed, errno = %d", errno);
- if(!WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP + 0x80)))
+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP + 0x80))
panic("check_ptrace : expected SIGTRAP + 0x80, "
"got status = %d", status);
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
index 2af5a343cf1c2b..8d003f351eb38f 100644
--- a/arch/um/kernel/process_kern.c
+++ b/arch/um/kernel/process_kern.c
@@ -235,18 +235,28 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
pte_t *pte_out)
{
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
if(task->mm == NULL)
return(ERR_PTR(-EINVAL));
pgd = pgd_offset(task->mm, addr);
- pmd = pmd_offset(pgd, addr);
+ if(!pgd_present(*pgd))
+ return(ERR_PTR(-EINVAL));
+
+ pud = pud_offset(pgd, addr);
+ if(!pud_present(*pud))
+ return(ERR_PTR(-EINVAL));
+
+ pmd = pmd_offset(pud, addr);
if(!pmd_present(*pmd))
return(ERR_PTR(-EINVAL));
+
pte = pte_offset_kernel(pmd, addr);
if(!pte_present(*pte))
return(ERR_PTR(-EINVAL));
+
if(pte_out != NULL)
*pte_out = *pte;
return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK));
@@ -358,22 +368,22 @@ void *get_init_task(void)
return(&init_thread_union.thread_info.task);
}
-int copy_to_user_proc(void *to, void *from, int size)
+int copy_to_user_proc(void __user *to, void *from, int size)
{
return(copy_to_user(to, from, size));
}
-int copy_from_user_proc(void *to, void *from, int size)
+int copy_from_user_proc(void *to, void __user *from, int size)
{
return(copy_from_user(to, from, size));
}
-int clear_user_proc(void *buf, int size)
+int clear_user_proc(void __user *buf, int size)
{
return(clear_user(buf, size));
}
-int strlen_user_proc(char *str)
+int strlen_user_proc(char __user *str)
{
return(strlen_user(str));
}
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index daf1cb54d023bf..0d8e7696960039 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -16,6 +16,7 @@
#include "asm/uaccess.h"
#include "kern_util.h"
#include "ptrace_user.h"
+#include "skas_ptrace.h"
/*
* Called by kernel/ptrace.c when detaching..
@@ -80,7 +81,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
if (copied != sizeof(tmp))
break;
- ret = put_user(tmp,(unsigned long *) data);
+ ret = put_user(tmp, (unsigned long __user *) data);
break;
}
@@ -102,7 +103,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
addr = addr >> 2;
tmp = child->thread.arch.debugregs[addr];
}
- ret = put_user(tmp, (unsigned long *) data);
+ ret = put_user(tmp, (unsigned long __user *) data);
break;
}
@@ -200,7 +201,8 @@ long sys_ptrace(long request, long pid, long addr, long data)
break;
}
for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
- __put_user(getreg(child, i), (unsigned long *) data);
+ __put_user(getreg(child, i),
+ (unsigned long __user *) data);
data += sizeof(long);
}
ret = 0;
@@ -216,7 +218,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
break;
}
for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) {
- __get_user(tmp, (unsigned long *) data);
+ __get_user(tmp, (unsigned long __user *) data);
putreg(child, i, tmp);
data += sizeof(long);
}
@@ -250,14 +252,14 @@ long sys_ptrace(long request, long pid, long addr, long data)
fault = ((struct ptrace_faultinfo)
{ .is_write = child->thread.err,
.addr = child->thread.cr2 });
- ret = copy_to_user((unsigned long *) data, &fault,
+ ret = copy_to_user((unsigned long __user *) data, &fault,
sizeof(fault));
if(ret)
break;
break;
}
case PTRACE_SIGPENDING:
- ret = copy_to_user((unsigned long *) data,
+ ret = copy_to_user((unsigned long __user *) data,
&child->pending.signal,
sizeof(child->pending.signal));
break;
@@ -265,7 +267,7 @@ long sys_ptrace(long request, long pid, long addr, long data)
case PTRACE_LDT: {
struct ptrace_ldt ldt;
- if(copy_from_user(&ldt, (unsigned long *) data,
+ if(copy_from_user(&ldt, (unsigned long __user *) data,
sizeof(ldt))){
ret = -EIO;
break;
@@ -306,6 +308,25 @@ long sys_ptrace(long request, long pid, long addr, long data)
return ret;
}
+void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
+ int error_code)
+{
+ struct siginfo info;
+
+ memset(&info, 0, sizeof(info));
+ info.si_signo = SIGTRAP;
+ info.si_code = TRAP_BRKPT;
+
+ /* User-mode eip? */
+ info.si_addr = UPT_IS_USER(regs) ? (void __user *) UPT_IP(regs) : NULL;
+
+ /* Send us the fakey SIGTRAP */
+ force_sig_info(SIGTRAP, &info, tsk);
+}
+
+/* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
+ * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
+ */
void syscall_trace(union uml_pt_regs *regs, int entryexit)
{
int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
@@ -320,14 +341,19 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
audit_syscall_exit(current, regs->eax);
}
- if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_singlestep)
+ /* Fake a debug trap */
+ if (is_singlestep)
+ send_sigtrap(current, regs, 0);
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
+
if (!(current->ptrace & PT_PTRACED))
return;
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
- tracesysgood = (current->ptrace & PT_TRACESYSGOOD) && !is_singlestep;
+ tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
if (entryexit) /* force do_signal() --> is_syscall() */
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
index 2a5b9b8ef3f8ba..7807a3e8c426e3 100644
--- a/arch/um/kernel/signal_kern.c
+++ b/arch/um/kernel/signal_kern.c
@@ -74,10 +74,12 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
sp = current->sas_ss_sp + current->sas_ss_size;
- if(ka->sa.sa_flags & SA_SIGINFO)
- err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
- else
+#ifdef CONFIG_ARCH_HAS_SC_SIGNALS
+ if(!(ka->sa.sa_flags & SA_SIGINFO))
err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
+ else
+#endif
+ err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
if(err){
spin_lock_irq(&current->sighand->siglock);
@@ -194,38 +196,7 @@ long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
}
}
-int sys_sigaction(int sig, const struct old_sigaction __user *act,
- struct old_sigaction __user *oact)
-{
- struct k_sigaction new_ka, old_ka;
- int ret;
-
- if (act) {
- old_sigset_t mask;
- if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
- __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
- __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
- return -EFAULT;
- __get_user(new_ka.sa.sa_flags, &act->sa_flags);
- __get_user(mask, &act->sa_mask);
- siginitset(&new_ka.sa.sa_mask, mask);
- }
-
- ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
-
- if (!ret && oact) {
- if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
- __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
- __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
- return -EFAULT;
- __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
- __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
- }
-
- return ret;
-}
-
-long sys_sigaltstack(const stack_t *uss, stack_t *uoss)
+long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
{
return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
}
diff --git a/arch/um/kernel/signal_user.c b/arch/um/kernel/signal_user.c
index 2468cd6a625d54..62f457835fb1dc 100644
--- a/arch/um/kernel/signal_user.c
+++ b/arch/um/kernel/signal_user.c
@@ -41,6 +41,7 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
while((mask = va_arg(ap, int)) != -1){
sigaddset(&action.sa_mask, mask);
}
+ va_end(ap);
action.sa_flags = flags;
action.sa_restorer = NULL;
if(sigaction(sig, &action, NULL) < 0)
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index d7b61cba94487b..c340c9cbf19b8e 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -6,8 +6,6 @@
obj-y := exec_kern.o mem.o mem_user.o mmu.o process.o process_kern.o \
syscall_kern.o syscall_user.o time.o tlb.o trap_user.o uaccess.o \
-subdir-y := util
-
USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
diff --git a/arch/um/kernel/skas/include/ptrace-skas.h b/arch/um/kernel/skas/include/ptrace-skas.h
deleted file mode 100644
index f5c5268cc4925a..00000000000000
--- a/arch/um/kernel/skas/include/ptrace-skas.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
- * Licensed under the GPL
- */
-
-#ifndef __PTRACE_SKAS_H
-#define __PTRACE_SKAS_H
-
-#include "uml-config.h"
-
-#ifdef UML_CONFIG_MODE_SKAS
-
-#include "skas_ptregs.h"
-
-#define HOST_FRAME_SIZE 17
-
-#define REGS_IP(r) ((r)[HOST_IP])
-#define REGS_SP(r) ((r)[HOST_SP])
-#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS])
-#define REGS_EAX(r) ((r)[HOST_EAX])
-#define REGS_EBX(r) ((r)[HOST_EBX])
-#define REGS_ECX(r) ((r)[HOST_ECX])
-#define REGS_EDX(r) ((r)[HOST_EDX])
-#define REGS_ESI(r) ((r)[HOST_ESI])
-#define REGS_EDI(r) ((r)[HOST_EDI])
-#define REGS_EBP(r) ((r)[HOST_EBP])
-#define REGS_CS(r) ((r)[HOST_CS])
-#define REGS_SS(r) ((r)[HOST_SS])
-#define REGS_DS(r) ((r)[HOST_DS])
-#define REGS_ES(r) ((r)[HOST_ES])
-#define REGS_FS(r) ((r)[HOST_FS])
-#define REGS_GS(r) ((r)[HOST_GS])
-
-#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res)
-
-#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
-
-#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type)
-
-#define REGS_FAULT_ADDR(r) ((r)->fault_addr)
-
-#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type)
-
-#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/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
index 2f6eaa37455d79..1c7fcd3effc204 100644
--- a/arch/um/kernel/skas/include/skas.h
+++ b/arch/um/kernel/skas/include/skas.h
@@ -29,10 +29,7 @@ extern int protect(int fd, unsigned long addr, unsigned long len,
int r, int w, int x, int must_succeed);
extern void user_signal(int sig, union uml_pt_regs *regs);
extern int new_mm(int from);
-extern void save_registers(union uml_pt_regs *regs);
-extern void restore_registers(union uml_pt_regs *regs);
extern void start_userspace(int cpu);
-extern void init_registers(int pid);
#endif
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
index ec169a86cdbe2e..438db2f43456b4 100644
--- a/arch/um/kernel/skas/mem.c
+++ b/arch/um/kernel/skas/mem.c
@@ -13,8 +13,13 @@ unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out,
/* Round up to the nearest 4M */
unsigned long top = ROUND_4M((unsigned long) &arg);
+#ifdef CONFIG_HOST_TASK_SIZE
+ *host_size_out = CONFIG_HOST_TASK_SIZE;
+ *task_size_out = CONFIG_HOST_TASK_SIZE;
+#else
*host_size_out = top;
*task_size_out = top;
+#endif
return(((unsigned long) set_task_sizes_skas) & ~0xffffff);
}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 247b06d09c59f9..6b1acc66ff949e 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -28,6 +28,7 @@
#include "skas_ptrace.h"
#include "chan_user.h"
#include "signal_user.h"
+#include "registers.h"
int is_skas_winch(int pid, int fd, void *data)
{
@@ -38,13 +39,6 @@ int is_skas_winch(int pid, int fd, void *data)
return(1);
}
-/* These are set once at boot time and not changed thereafter */
-
-unsigned long exec_regs[FRAME_SIZE];
-unsigned long exec_fp_regs[HOST_FP_SIZE];
-unsigned long exec_fpx_regs[HOST_XFP_SIZE];
-int have_fpx_regs = 1;
-
static void handle_segv(int pid)
{
struct ptrace_faultinfo fault;
@@ -79,7 +73,8 @@ static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu
"errno = %d\n", errno);
CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
- if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != (SIGTRAP + 0x80)))
+ if((err < 0) || !WIFSTOPPED(status) ||
+ (WSTOPSIG(status) != SIGTRAP + 0x80))
panic("handle_trap - failed to wait at end of syscall, "
"errno = %d, status = %d\n", errno, status);
}
@@ -97,6 +92,7 @@ static int userspace_tramp(void *arg)
}
/* Each element set once, and only accessed by a single processor anyway */
+#undef NR_CPUS
#define NR_CPUS 1
int userspace_pid[NR_CPUS];
@@ -143,7 +139,7 @@ void userspace(union uml_pt_regs *regs)
int err, status, op, pid = userspace_pid[0];
int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/
- restore_registers(regs);
+ restore_registers(pid, regs);
local_using_sysemu = get_using_sysemu();
@@ -160,7 +156,7 @@ void userspace(union uml_pt_regs *regs)
errno);
regs->skas.is_user = 1;
- save_registers(regs);
+ save_registers(pid, regs);
UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
if(WIFSTOPPED(status)){
@@ -192,7 +188,7 @@ void userspace(union uml_pt_regs *regs)
PT_SYSCALL_NR(regs->skas.regs) = -1;
}
- restore_registers(regs);
+ restore_registers(pid, regs);
/*Now we ended the syscall, so re-read local_using_sysemu.*/
local_using_sysemu = get_using_sysemu();
@@ -243,58 +239,6 @@ void thread_wait(void *sw, void *fb)
siglongjmp(*fork_buf, 1);
}
-static int move_registers(int pid, int int_op, int fp_op,
- union uml_pt_regs *regs, unsigned long *fp_regs)
-{
- if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
- return(-errno);
- if(ptrace(fp_op, pid, 0, fp_regs) < 0)
- return(-errno);
- return(0);
-}
-
-void save_registers(union uml_pt_regs *regs)
-{
- unsigned long *fp_regs;
- int err, fp_op;
-
- if(have_fpx_regs){
- fp_op = PTRACE_GETFPXREGS;
- fp_regs = regs->skas.xfp;
- }
- else {
- fp_op = PTRACE_GETFPREGS;
- fp_regs = regs->skas.fp;
- }
-
- err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs,
- fp_regs);
- if(err)
- panic("save_registers - saving registers failed, errno = %d\n",
- -err);
-}
-
-void restore_registers(union uml_pt_regs *regs)
-{
- unsigned long *fp_regs;
- int err, fp_op;
-
- if(have_fpx_regs){
- fp_op = PTRACE_SETFPXREGS;
- fp_regs = regs->skas.xfp;
- }
- else {
- fp_op = PTRACE_SETFPREGS;
- fp_regs = regs->skas.fp;
- }
-
- err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs,
- fp_regs);
- if(err)
- panic("restore_registers - saving registers failed, "
- "errno = %d\n", -err);
-}
-
void switch_threads(void *me, void *next)
{
sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
@@ -394,29 +338,6 @@ void kill_off_processes_skas(void)
os_kill_ptraced_process(userspace_pid[0], 1);
}
-void init_registers(int pid)
-{
- int err;
-
- if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0)
- panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
- errno);
-
- err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
- if(!err)
- return;
-
- have_fpx_regs = 0;
- if(errno != EIO)
- panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
- errno);
-
- err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
- if(err)
- panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
- errno);
-}
-
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
index 648955b0476ff9..5d096ea63b97a6 100644
--- a/arch/um/kernel/skas/process_kern.c
+++ b/arch/um/kernel/skas/process_kern.c
@@ -22,6 +22,7 @@
#include "kern.h"
#include "mode.h"
#include "proc_mm.h"
+#include "registers.h"
void *switch_to_skas(void *prev, void *next)
{
@@ -118,12 +119,7 @@ int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
handler = fork_handler;
}
else {
- memcpy(p->thread.regs.regs.skas.regs, exec_regs,
- sizeof(p->thread.regs.regs.skas.regs));
- memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs,
- sizeof(p->thread.regs.regs.skas.fp));
- memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs,
- sizeof(p->thread.regs.regs.skas.xfp));
+ init_thread_registers(&p->thread.regs.regs);
p->thread.request.u.thread = current->thread.request.u.thread;
handler = new_thread_handler;
}
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
index 02e3e06bb03313..956fb0102a1ee4 100644
--- a/arch/um/kernel/skas/tlb.c
+++ b/arch/um/kernel/skas/tlb.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
* Licensed under the GPL
*/
@@ -18,52 +19,86 @@ static void fix_range(struct mm_struct *mm, unsigned long start_addr,
unsigned long end_addr, int force)
{
pgd_t *npgd;
+ pud_t *npud;
pmd_t *npmd;
pte_t *npte;
- unsigned long addr;
+ unsigned long addr, end;
int r, w, x, err, fd;
if(mm == NULL) return;
fd = mm->context.skas.mm_fd;
for(addr = start_addr; addr < end_addr;){
npgd = pgd_offset(mm, addr);
- npmd = pmd_offset(npgd, addr);
- if(pmd_present(*npmd)){
- npte = pte_offset_kernel(npmd, addr);
- r = pte_read(*npte);
- w = pte_write(*npte);
- x = pte_exec(*npte);
- if(!pte_dirty(*npte)) w = 0;
- if(!pte_young(*npte)){
- r = 0;
- w = 0;
- }
- if(force || pte_newpage(*npte)){
- err = unmap(fd, (void *) addr, PAGE_SIZE);
+ if(!pgd_present(*npgd)){
+ if(force || pgd_newpage(*npgd)){
+ end = addr + PGDIR_SIZE;
+ if(end > end_addr)
+ end = end_addr;
+ err = unmap(fd, (void *) addr, end - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
- if(pte_present(*npte))
- map(fd, addr,
- pte_val(*npte) & PAGE_MASK,
- PAGE_SIZE, r, w, x);
+ pgd_mkuptodate(*npgd);
}
- else if(pte_newprot(*npte)){
- protect(fd, addr, PAGE_SIZE, r, w, x, 1);
+ addr += PGDIR_SIZE;
+ continue;
+ }
+
+ npud = pud_offset(npgd, addr);
+ if(!pud_present(*npud)){
+ if(force || pud_newpage(*npud)){
+ end = addr + PUD_SIZE;
+ if(end > end_addr)
+ end = end_addr;
+ err = unmap(fd, (void *) addr, end - addr);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
+ pud_mkuptodate(*npud);
}
- *npte = pte_mkuptodate(*npte);
- addr += PAGE_SIZE;
+ addr += PUD_SIZE;
+ continue;
}
- else {
+
+ npmd = pmd_offset(npud, addr);
+ if(!pmd_present(*npmd)){
if(force || pmd_newpage(*npmd)){
- err = unmap(fd, (void *) addr, PMD_SIZE);
+ end = addr + PMD_SIZE;
+ if(end > end_addr)
+ end = end_addr;
+ err = unmap(fd, (void *) addr, end - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
pmd_mkuptodate(*npmd);
}
addr += PMD_SIZE;
+ continue;
+ }
+
+ npte = pte_offset_kernel(npmd, addr);
+ r = pte_read(*npte);
+ w = pte_write(*npte);
+ x = pte_exec(*npte);
+ if(!pte_dirty(*npte))
+ w = 0;
+ if(!pte_young(*npte)){
+ r = 0;
+ w = 0;
+ }
+ if(force || pte_newpage(*npte)){
+ err = unmap(fd, (void *) addr, PAGE_SIZE);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n", -err);
+ if(pte_present(*npte))
+ map(fd, addr, pte_val(*npte) & PAGE_MASK,
+ PAGE_SIZE, r, w, x);
}
+ else if(pte_newprot(*npte))
+ protect(fd, addr, PAGE_SIZE, r, w, x, 1);
+
+ *npte = pte_mkuptodate(*npte);
+ addr += PAGE_SIZE;
}
}
@@ -71,45 +106,82 @@ void flush_tlb_kernel_range_skas(unsigned long start, unsigned long end)
{
struct mm_struct *mm;
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- unsigned long addr;
+ unsigned long addr, last;
int updated = 0, err;
mm = &init_mm;
for(addr = start; addr < end;){
pgd = pgd_offset(mm, addr);
- pmd = pmd_offset(pgd, addr);
- if(pmd_present(*pmd)){
- pte = pte_offset_kernel(pmd, addr);
- if(!pte_present(*pte) || pte_newpage(*pte)){
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
+ if(!pgd_present(*pgd)){
+ if(pgd_newpage(*pgd)){
updated = 1;
+ last = addr + PGDIR_SIZE;
+ if(last > end)
+ last = end;
err = os_unmap_memory((void *) addr,
- PAGE_SIZE);
+ last - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
- if(pte_present(*pte))
- map_memory(addr,
- pte_val(*pte) & PAGE_MASK,
- PAGE_SIZE, 1, 1, 1);
}
- else if(pte_newprot(*pte)){
+ addr += PGDIR_SIZE;
+ continue;
+ }
+
+ pud = pud_offset(pgd, addr);
+ if(!pud_present(*pud)){
+ if(pud_newpage(*pud)){
updated = 1;
- protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+ last = addr + PUD_SIZE;
+ if(last > end)
+ last = end;
+ err = os_unmap_memory((void *) addr,
+ last - addr);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
}
- addr += PAGE_SIZE;
+ addr += PUD_SIZE;
+ continue;
}
- else {
+
+ pmd = pmd_offset(pud, addr);
+ if(!pmd_present(*pmd)){
if(pmd_newpage(*pmd)){
updated = 1;
- err = os_unmap_memory((void *) addr, PMD_SIZE);
+ last = addr + PMD_SIZE;
+ if(last > end)
+ last = end;
+ err = os_unmap_memory((void *) addr,
+ last - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
}
addr += PMD_SIZE;
+ continue;
+ }
+
+ pte = pte_offset_kernel(pmd, addr);
+ if(!pte_present(*pte) || pte_newpage(*pte)){
+ updated = 1;
+ err = os_unmap_memory((void *) addr, PAGE_SIZE);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n", -err);
+ if(pte_present(*pte))
+ map_memory(addr, pte_val(*pte) & PAGE_MASK,
+ PAGE_SIZE, 1, 1, 1);
}
+ else if(pte_newprot(*pte)){
+ updated = 1;
+ protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+ }
+ addr += PAGE_SIZE;
}
}
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
index 96593709a6e169..09248772de6059 100644
--- a/arch/um/kernel/skas/trap_user.c
+++ b/arch/um/kernel/skas/trap_user.c
@@ -5,7 +5,6 @@
#include <signal.h>
#include <errno.h>
-#include <asm/sigcontext.h>
#include "sysdep/ptrace.h"
#include "signal_user.h"
#include "user_util.h"
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 77048cd6775cb7..c8e5fe49583aee 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -54,15 +54,23 @@ static int do_op(unsigned long addr, int len, int is_write,
static void do_buffer_op(void *jmpbuf, void *arg_ptr)
{
- va_list args = *((va_list *) arg_ptr);
- unsigned long addr = va_arg(args, unsigned long);
- int len = va_arg(args, int);
- int is_write = va_arg(args, int);
- int (*op)(unsigned long, int, void *) = va_arg(args, void *);
- void *arg = va_arg(args, void *);
- int *res = va_arg(args, int *);
- int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
- int remain = len, n;
+ va_list args;
+ unsigned long addr;
+ int len, is_write, size, remain, n;
+ int (*op)(unsigned long, int, void *);
+ void *arg;
+ int *res;
+
+ va_copy(args, *(va_list *)arg_ptr);
+ addr = va_arg(args, unsigned long);
+ len = va_arg(args, int);
+ is_write = va_arg(args, int);
+ op = va_arg(args, void *);
+ arg = va_arg(args, void *);
+ res = va_arg(args, int *);
+ va_end(args);
+ size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
+ remain = len;
current->thread.fault_catcher = jmpbuf;
n = do_op(addr, size, is_write, op, arg);
@@ -124,10 +132,10 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
return(0);
}
-int copy_from_user_skas(void *to, const void *from, int n)
+int copy_from_user_skas(void *to, const void __user *from, int n)
{
if(segment_eq(get_fs(), KERNEL_DS)){
- memcpy(to, from, n);
+ memcpy(to, (__force void*)from, n);
return(0);
}
@@ -145,10 +153,10 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
return(0);
}
-int copy_to_user_skas(void *to, const void *from, int n)
+int copy_to_user_skas(void __user *to, const void *from, int n)
{
if(segment_eq(get_fs(), KERNEL_DS)){
- memcpy(to, from, n);
+ memcpy((__force void*)to, from, n);
return(0);
}
@@ -171,13 +179,13 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
return(0);
}
-int strncpy_from_user_skas(char *dst, const char *src, int count)
+int strncpy_from_user_skas(char *dst, const char __user *src, int count)
{
int n;
char *ptr = dst;
if(segment_eq(get_fs(), KERNEL_DS)){
- strncpy(dst, src, count);
+ strncpy(dst, (__force void*)src, count);
return(strnlen(dst, count));
}
@@ -197,15 +205,15 @@ static int clear_chunk(unsigned long addr, int len, void *unused)
return(0);
}
-int __clear_user_skas(void *mem, int len)
+int __clear_user_skas(void __user *mem, int len)
{
return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
}
-int clear_user_skas(void *mem, int len)
+int clear_user_skas(void __user *mem, int len)
{
if(segment_eq(get_fs(), KERNEL_DS)){
- memset(mem, 0, len);
+ memset((__force void*)mem, 0, len);
return(0);
}
@@ -225,12 +233,12 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
return(0);
}
-int strnlen_user_skas(const void *str, int len)
+int strnlen_user_skas(const void __user *str, int len)
{
int count = 0, n;
if(segment_eq(get_fs(), KERNEL_DS))
- return(strnlen(str, len) + 1);
+ return(strnlen((__force char*)str, len) + 1);
n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
if(n == 0)
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
index a26e0c34a762bd..17f5909d60f7f4 100644
--- a/arch/um/kernel/skas/util/Makefile
+++ b/arch/um/kernel/skas/util/Makefile
@@ -1,2 +1,4 @@
hostprogs-y := mk_ptregs
always := $(hostprogs-y)
+
+mk_ptregs-objs := mk_ptregs-$(SUBARCH).o
diff --git a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c
index 116f74d2c334f0..0788dd05bcacd5 100644
--- a/arch/um/kernel/skas/util/mk_ptregs.c
+++ b/arch/um/kernel/skas/util/mk_ptregs-i386.c
@@ -13,9 +13,9 @@ int main(int argc, char **argv)
printf("#define __SKAS_PT_REGS_\n");
printf("\n");
printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE);
- printf("#define HOST_FP_SIZE %d\n",
+ printf("#define HOST_FP_SIZE %d\n",
sizeof(struct user_i387_struct) / sizeof(unsigned long));
- printf("#define HOST_XFP_SIZE %d\n",
+ printf("#define HOST_XFP_SIZE %d\n",
sizeof(struct user_fxsr_struct) / sizeof(unsigned long));
PRINT_REG("IP", EIP);
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
new file mode 100644
index 00000000000000..67aee92a70efa5
--- /dev/null
+++ b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#define __FRAME_OFFSETS
+#include <asm/ptrace.h>
+
+#define PRINT_REG(name, val) \
+ printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val))
+
+int main(int argc, char **argv)
+{
+ printf("/* Automatically generated by "
+ "arch/um/kernel/skas/util/mk_ptregs */\n");
+ printf("\n");
+ printf("#ifndef __SKAS_PT_REGS_\n");
+ printf("#define __SKAS_PT_REGS_\n");
+ printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n",
+ FRAME_SIZE);
+ PRINT_REG("RBX", RBX);
+ PRINT_REG("RCX", RCX);
+ PRINT_REG("RDI", RDI);
+ PRINT_REG("RSI", RSI);
+ PRINT_REG("RDX", RDX);
+ PRINT_REG("RBP", RBP);
+ PRINT_REG("RAX", RAX);
+ PRINT_REG("R8", R8);
+ PRINT_REG("R9", R9);
+ PRINT_REG("R10", R10);
+ PRINT_REG("R11", R11);
+ PRINT_REG("R12", R12);
+ PRINT_REG("R13", R13);
+ PRINT_REG("R14", R14);
+ PRINT_REG("R15", R15);
+ PRINT_REG("ORIG_RAX", ORIG_RAX);
+ PRINT_REG("CS", CS);
+ PRINT_REG("SS", SS);
+ PRINT_REG("EFLAGS", EFLAGS);
+#if 0
+ PRINT_REG("FS", FS);
+ PRINT_REG("GS", GS);
+ PRINT_REG("DS", DS);
+ PRINT_REG("ES", ES);
+#endif
+
+ PRINT_REG("IP", RIP);
+ PRINT_REG("SP", RSP);
+ printf("#define HOST_FP_SIZE 0\n");
+ printf("#define HOST_XFP_SIZE 0\n");
+ printf("\n");
+ printf("\n");
+ printf("#endif\n");
+ return(0);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index b5e66b291cc32f..abe892be6cfe4a 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -247,10 +247,8 @@ int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic,
func = _func;
info = _info;
- for (i=0;i<NR_CPUS;i++)
- if((i != current_thread->cpu) &&
- cpu_isset(i, cpu_online_map))
- os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
+ for_each_cpu(i)
+ os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
while (atomic_read(&scf_started) != cpus)
barrier();
diff --git a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
index 314925365cf52b..b09266a012c152 100644
--- a/arch/um/kernel/sys_call_table.c
+++ b/arch/um/kernel/sys_call_table.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
* Licensed under the GPL
*/
@@ -19,7 +20,7 @@
#define NFSSERVCTL sys_ni_syscall
#endif
-#define LAST_GENERIC_SYSCALL __NR_vserver
+#define LAST_GENERIC_SYSCALL __NR_vperfctr_read
#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
#define LAST_SYSCALL LAST_GENERIC_SYSCALL
@@ -32,7 +33,6 @@ extern syscall_handler_t sys_execve;
extern syscall_handler_t um_time;
extern syscall_handler_t um_mount;
extern syscall_handler_t um_stime;
-extern syscall_handler_t sys_ptrace;
extern syscall_handler_t sys_pipe;
extern syscall_handler_t sys_olduname;
extern syscall_handler_t sys_sigaction;
@@ -43,269 +43,249 @@ extern syscall_handler_t sys_ipc;
extern syscall_handler_t sys_sigreturn;
extern syscall_handler_t sys_clone;
extern syscall_handler_t sys_rt_sigreturn;
-extern syscall_handler_t sys_rt_sigaction;
extern syscall_handler_t sys_sigaltstack;
extern syscall_handler_t sys_vfork;
-extern syscall_handler_t sys_mmap2;
-extern syscall_handler_t old_mmap_i386;
extern syscall_handler_t old_select;
extern syscall_handler_t sys_modify_ldt;
extern syscall_handler_t sys_rt_sigsuspend;
+extern syscall_handler_t sys_vserver;
+extern syscall_handler_t sys_mbind;
+extern syscall_handler_t sys_get_mempolicy;
+extern syscall_handler_t sys_set_mempolicy;
+extern syscall_handler_t sys_sys_kexec_load;
+extern syscall_handler_t sys_sys_setaltroot;
+extern syscall_handler_t sys_vperfctr_open;
+extern syscall_handler_t sys_vperfctr_control;
+extern syscall_handler_t sys_vperfctr_unlink;
+extern syscall_handler_t sys_vperfctr_iresume;
+extern syscall_handler_t sys_vperfctr_read;
syscall_handler_t *sys_call_table[] = {
[ __NR_restart_syscall ] = (syscall_handler_t *) sys_restart_syscall,
- [ __NR_exit ] (syscall_handler_t *) sys_exit,
- [ __NR_fork ] (syscall_handler_t *) sys_fork,
+ [ __NR_exit ] = (syscall_handler_t *) sys_exit,
+ [ __NR_fork ] = (syscall_handler_t *) sys_fork,
[ __NR_read ] = (syscall_handler_t *) sys_read,
[ __NR_write ] = (syscall_handler_t *) sys_write,
/* These three are declared differently in asm/unistd.h */
[ __NR_open ] = (syscall_handler_t *) sys_open,
[ __NR_close ] = (syscall_handler_t *) sys_close,
- [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid,
- [ __NR_creat ] (syscall_handler_t *) sys_creat,
- [ __NR_link ] (syscall_handler_t *) sys_link,
- [ __NR_unlink ] (syscall_handler_t *) sys_unlink,
+ [ __NR_creat ] = (syscall_handler_t *) sys_creat,
+ [ __NR_link ] = (syscall_handler_t *) sys_link,
+ [ __NR_unlink ] = (syscall_handler_t *) sys_unlink,
[ __NR_execve ] = (syscall_handler_t *) sys_execve,
/* declared differently in kern_util.h */
- [ __NR_chdir ] (syscall_handler_t *) sys_chdir,
+ [ __NR_chdir ] = (syscall_handler_t *) sys_chdir,
[ __NR_time ] = um_time,
- [ __NR_mknod ] (syscall_handler_t *) sys_mknod,
- [ __NR_chmod ] (syscall_handler_t *) sys_chmod,
- [ __NR_lchown ] (syscall_handler_t *) sys_lchown16,
- [ __NR_break ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_oldstat ] (syscall_handler_t *) sys_stat,
+ [ __NR_mknod ] = (syscall_handler_t *) sys_mknod,
+ [ __NR_chmod ] = (syscall_handler_t *) sys_chmod,
+ [ __NR_lchown ] = (syscall_handler_t *) sys_lchown16,
[ __NR_lseek ] = (syscall_handler_t *) sys_lseek,
- [ __NR_getpid ] (syscall_handler_t *) sys_getpid,
+ [ __NR_getpid ] = (syscall_handler_t *) sys_getpid,
[ __NR_mount ] = um_mount,
- [ __NR_umount ] (syscall_handler_t *) sys_oldumount,
- [ __NR_setuid ] (syscall_handler_t *) sys_setuid16,
- [ __NR_getuid ] (syscall_handler_t *) sys_getuid16,
- [ __NR_stime ] = um_stime,
- [ __NR_ptrace ] (syscall_handler_t *) sys_ptrace,
- [ __NR_alarm ] (syscall_handler_t *) sys_alarm,
- [ __NR_oldfstat ] (syscall_handler_t *) sys_fstat,
- [ __NR_pause ] (syscall_handler_t *) sys_pause,
- [ __NR_utime ] (syscall_handler_t *) sys_utime,
- [ __NR_stty ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_gtty ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_access ] (syscall_handler_t *) sys_access,
- [ __NR_nice ] (syscall_handler_t *) sys_nice,
- [ __NR_ftime ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_sync ] (syscall_handler_t *) sys_sync,
- [ __NR_kill ] (syscall_handler_t *) sys_kill,
- [ __NR_rename ] (syscall_handler_t *) sys_rename,
- [ __NR_mkdir ] (syscall_handler_t *) sys_mkdir,
- [ __NR_rmdir ] (syscall_handler_t *) sys_rmdir,
+ [ __NR_setuid ] = (syscall_handler_t *) sys_setuid16,
+ [ __NR_getuid ] = (syscall_handler_t *) sys_getuid16,
+ [ __NR_ptrace ] = (syscall_handler_t *) sys_ptrace,
+ [ __NR_alarm ] = (syscall_handler_t *) sys_alarm,
+ [ __NR_pause ] = (syscall_handler_t *) sys_pause,
+ [ __NR_utime ] = (syscall_handler_t *) sys_utime,
+ [ __NR_access ] = (syscall_handler_t *) sys_access,
+ [ __NR_sync ] = (syscall_handler_t *) sys_sync,
+ [ __NR_kill ] = (syscall_handler_t *) sys_kill,
+ [ __NR_rename ] = (syscall_handler_t *) sys_rename,
+ [ __NR_mkdir ] = (syscall_handler_t *) sys_mkdir,
+ [ __NR_rmdir ] = (syscall_handler_t *) sys_rmdir,
/* Declared differently in asm/unistd.h */
[ __NR_dup ] = (syscall_handler_t *) sys_dup,
- [ __NR_pipe ] (syscall_handler_t *) sys_pipe,
- [ __NR_times ] (syscall_handler_t *) sys_times,
- [ __NR_prof ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_brk ] (syscall_handler_t *) sys_brk,
- [ __NR_setgid ] (syscall_handler_t *) sys_setgid16,
- [ __NR_getgid ] (syscall_handler_t *) sys_getgid16,
- [ __NR_signal ] (syscall_handler_t *) sys_signal,
- [ __NR_geteuid ] (syscall_handler_t *) sys_geteuid16,
- [ __NR_getegid ] (syscall_handler_t *) sys_getegid16,
- [ __NR_acct ] (syscall_handler_t *) sys_acct,
- [ __NR_umount2 ] (syscall_handler_t *) sys_umount,
- [ __NR_lock ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_ioctl ] (syscall_handler_t *) sys_ioctl,
- [ __NR_fcntl ] (syscall_handler_t *) sys_fcntl,
- [ __NR_mpx ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_setpgid ] (syscall_handler_t *) sys_setpgid,
- [ __NR_ulimit ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_oldolduname ] (syscall_handler_t *) sys_olduname,
- [ __NR_umask ] (syscall_handler_t *) sys_umask,
- [ __NR_chroot ] (syscall_handler_t *) sys_chroot,
- [ __NR_ustat ] (syscall_handler_t *) sys_ustat,
- [ __NR_dup2 ] (syscall_handler_t *) sys_dup2,
- [ __NR_getppid ] (syscall_handler_t *) sys_getppid,
- [ __NR_getpgrp ] (syscall_handler_t *) sys_getpgrp,
+ [ __NR_pipe ] = (syscall_handler_t *) sys_pipe,
+ [ __NR_times ] = (syscall_handler_t *) sys_times,
+ [ __NR_brk ] = (syscall_handler_t *) sys_brk,
+ [ __NR_setgid ] = (syscall_handler_t *) sys_setgid16,
+ [ __NR_getgid ] = (syscall_handler_t *) sys_getgid16,
+ [ __NR_geteuid ] = (syscall_handler_t *) sys_geteuid16,
+ [ __NR_getegid ] = (syscall_handler_t *) sys_getegid16,
+ [ __NR_acct ] = (syscall_handler_t *) sys_acct,
+ [ __NR_umount2 ] = (syscall_handler_t *) sys_umount,
+ [ __NR_ioctl ] = (syscall_handler_t *) sys_ioctl,
+ [ __NR_fcntl ] = (syscall_handler_t *) sys_fcntl,
+ [ __NR_setpgid ] = (syscall_handler_t *) sys_setpgid,
+ [ __NR_umask ] = (syscall_handler_t *) sys_umask,
+ [ __NR_chroot ] = (syscall_handler_t *) sys_chroot,
+ [ __NR_ustat ] = (syscall_handler_t *) sys_ustat,
+ [ __NR_dup2 ] = (syscall_handler_t *) sys_dup2,
+ [ __NR_getppid ] = (syscall_handler_t *) sys_getppid,
+ [ __NR_getpgrp ] = (syscall_handler_t *) sys_getpgrp,
[ __NR_setsid ] = (syscall_handler_t *) sys_setsid,
- [ __NR_sigaction ] (syscall_handler_t *) sys_sigaction,
- [ __NR_sgetmask ] (syscall_handler_t *) sys_sgetmask,
- [ __NR_ssetmask ] (syscall_handler_t *) sys_ssetmask,
- [ __NR_setreuid ] (syscall_handler_t *) sys_setreuid16,
- [ __NR_setregid ] (syscall_handler_t *) sys_setregid16,
- [ __NR_sigsuspend ] (syscall_handler_t *) sys_sigsuspend,
- [ __NR_sigpending ] (syscall_handler_t *) sys_sigpending,
- [ __NR_sethostname ] (syscall_handler_t *) sys_sethostname,
- [ __NR_setrlimit ] (syscall_handler_t *) sys_setrlimit,
- [ __NR_getrlimit ] (syscall_handler_t *) sys_old_getrlimit,
- [ __NR_getrusage ] (syscall_handler_t *) sys_getrusage,
- [ __NR_gettimeofday ] (syscall_handler_t *) sys_gettimeofday,
- [ __NR_settimeofday ] (syscall_handler_t *) sys_settimeofday,
- [ __NR_getgroups ] (syscall_handler_t *) sys_getgroups16,
- [ __NR_setgroups ] (syscall_handler_t *) sys_setgroups16,
- [ __NR_symlink ] (syscall_handler_t *) sys_symlink,
- [ __NR_oldlstat ] (syscall_handler_t *) sys_lstat,
- [ __NR_readlink ] (syscall_handler_t *) sys_readlink,
- [ __NR_uselib ] (syscall_handler_t *) sys_uselib,
+ [ __NR_setreuid ] = (syscall_handler_t *) sys_setreuid16,
+ [ __NR_setregid ] = (syscall_handler_t *) sys_setregid16,
+ [ __NR_sethostname ] = (syscall_handler_t *) sys_sethostname,
+ [ __NR_setrlimit ] = (syscall_handler_t *) sys_setrlimit,
+ [ __NR_getrlimit ] = (syscall_handler_t *) sys_old_getrlimit,
+ [ __NR_getrusage ] = (syscall_handler_t *) sys_getrusage,
+ [ __NR_gettimeofday ] = (syscall_handler_t *) sys_gettimeofday,
+ [ __NR_settimeofday ] = (syscall_handler_t *) sys_settimeofday,
+ [ __NR_getgroups ] = (syscall_handler_t *) sys_getgroups16,
+ [ __NR_setgroups ] = (syscall_handler_t *) sys_setgroups16,
+ [ __NR_symlink ] = (syscall_handler_t *) sys_symlink,
+ [ __NR_readlink ] = (syscall_handler_t *) sys_readlink,
+ [ __NR_uselib ] = (syscall_handler_t *) sys_uselib,
[ __NR_swapon ] = (syscall_handler_t *) sys_swapon,
- [ __NR_reboot ] (syscall_handler_t *) sys_reboot,
- [ __NR_readdir ] = old_readdir,
- [ __NR_munmap ] (syscall_handler_t *) sys_munmap,
- [ __NR_truncate ] (syscall_handler_t *) sys_truncate,
- [ __NR_ftruncate ] (syscall_handler_t *) sys_ftruncate,
- [ __NR_fchmod ] (syscall_handler_t *) sys_fchmod,
- [ __NR_fchown ] (syscall_handler_t *) sys_fchown16,
- [ __NR_getpriority ] (syscall_handler_t *) sys_getpriority,
- [ __NR_setpriority ] (syscall_handler_t *) sys_setpriority,
- [ __NR_profil ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_statfs ] (syscall_handler_t *) sys_statfs,
- [ __NR_fstatfs ] (syscall_handler_t *) sys_fstatfs,
- [ __NR_ioperm ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_socketcall ] (syscall_handler_t *) sys_socketcall,
- [ __NR_syslog ] (syscall_handler_t *) sys_syslog,
- [ __NR_setitimer ] (syscall_handler_t *) sys_setitimer,
- [ __NR_getitimer ] (syscall_handler_t *) sys_getitimer,
- [ __NR_stat ] (syscall_handler_t *) sys_newstat,
- [ __NR_lstat ] (syscall_handler_t *) sys_newlstat,
- [ __NR_fstat ] (syscall_handler_t *) sys_newfstat,
- [ __NR_olduname ] (syscall_handler_t *) sys_uname,
- [ __NR_iopl ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_vhangup ] (syscall_handler_t *) sys_vhangup,
- [ __NR_idle ] (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_reboot ] = (syscall_handler_t *) sys_reboot,
+ [ __NR_munmap ] = (syscall_handler_t *) sys_munmap,
+ [ __NR_truncate ] = (syscall_handler_t *) sys_truncate,
+ [ __NR_ftruncate ] = (syscall_handler_t *) sys_ftruncate,
+ [ __NR_fchmod ] = (syscall_handler_t *) sys_fchmod,
+ [ __NR_fchown ] = (syscall_handler_t *) sys_fchown16,
+ [ __NR_getpriority ] = (syscall_handler_t *) sys_getpriority,
+ [ __NR_setpriority ] = (syscall_handler_t *) sys_setpriority,
+ [ __NR_statfs ] = (syscall_handler_t *) sys_statfs,
+ [ __NR_fstatfs ] = (syscall_handler_t *) sys_fstatfs,
+ [ __NR_ioperm ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_syslog ] = (syscall_handler_t *) sys_syslog,
+ [ __NR_setitimer ] = (syscall_handler_t *) sys_setitimer,
+ [ __NR_getitimer ] = (syscall_handler_t *) sys_getitimer,
+ [ __NR_stat ] = (syscall_handler_t *) sys_newstat,
+ [ __NR_lstat ] = (syscall_handler_t *) sys_newlstat,
+ [ __NR_fstat ] = (syscall_handler_t *) sys_newfstat,
+ [ __NR_vhangup ] = (syscall_handler_t *) sys_vhangup,
[ __NR_wait4 ] = (syscall_handler_t *) sys_wait4,
[ __NR_swapoff ] = (syscall_handler_t *) sys_swapoff,
- [ __NR_sysinfo ] (syscall_handler_t *) sys_sysinfo,
- [ __NR_ipc ] (syscall_handler_t *) sys_ipc,
- [ __NR_fsync ] (syscall_handler_t *) sys_fsync,
- [ __NR_sigreturn ] (syscall_handler_t *) sys_sigreturn,
- [ __NR_clone ] (syscall_handler_t *) sys_clone,
- [ __NR_setdomainname ] (syscall_handler_t *) sys_setdomainname,
- [ __NR_uname ] (syscall_handler_t *) sys_newuname,
- [ __NR_adjtimex ] (syscall_handler_t *) sys_adjtimex,
- [ __NR_mprotect ] (syscall_handler_t *) sys_mprotect,
- [ __NR_sigprocmask ] (syscall_handler_t *) sys_sigprocmask,
- [ __NR_create_module ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_init_module ] (syscall_handler_t *) sys_init_module,
- [ __NR_delete_module ] (syscall_handler_t *) sys_delete_module,
- [ __NR_get_kernel_syms ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_quotactl ] (syscall_handler_t *) sys_quotactl,
- [ __NR_getpgid ] (syscall_handler_t *) sys_getpgid,
- [ __NR_fchdir ] (syscall_handler_t *) sys_fchdir,
- [ __NR_bdflush ] (syscall_handler_t *) sys_bdflush,
- [ __NR_sysfs ] (syscall_handler_t *) sys_sysfs,
- [ __NR_personality ] (syscall_handler_t *) sys_personality,
- [ __NR_afs_syscall ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_setfsuid ] (syscall_handler_t *) sys_setfsuid16,
- [ __NR_setfsgid ] (syscall_handler_t *) sys_setfsgid16,
- [ __NR__llseek ] (syscall_handler_t *) sys_llseek,
- [ __NR_getdents ] (syscall_handler_t *) sys_getdents,
- [ __NR__newselect ] = (syscall_handler_t *) sys_select,
- [ __NR_flock ] (syscall_handler_t *) sys_flock,
- [ __NR_msync ] (syscall_handler_t *) sys_msync,
- [ __NR_readv ] (syscall_handler_t *) sys_readv,
- [ __NR_writev ] (syscall_handler_t *) sys_writev,
- [ __NR_getsid ] (syscall_handler_t *) sys_getsid,
- [ __NR_fdatasync ] (syscall_handler_t *) sys_fdatasync,
+ [ __NR_sysinfo ] = (syscall_handler_t *) sys_sysinfo,
+ [ __NR_fsync ] = (syscall_handler_t *) sys_fsync,
+ [ __NR_clone ] = (syscall_handler_t *) sys_clone,
+ [ __NR_setdomainname ] = (syscall_handler_t *) sys_setdomainname,
+ [ __NR_uname ] = (syscall_handler_t *) sys_newuname,
+ [ __NR_adjtimex ] = (syscall_handler_t *) sys_adjtimex,
+ [ __NR_mprotect ] = (syscall_handler_t *) sys_mprotect,
+ [ __NR_create_module ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_init_module ] = (syscall_handler_t *) sys_init_module,
+ [ __NR_delete_module ] = (syscall_handler_t *) sys_delete_module,
+ [ __NR_get_kernel_syms ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_quotactl ] = (syscall_handler_t *) sys_quotactl,
+ [ __NR_getpgid ] = (syscall_handler_t *) sys_getpgid,
+ [ __NR_fchdir ] = (syscall_handler_t *) sys_fchdir,
+ [ __NR_sysfs ] = (syscall_handler_t *) sys_sysfs,
+ [ __NR_personality ] = (syscall_handler_t *) sys_personality,
+ [ __NR_afs_syscall ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_setfsuid ] = (syscall_handler_t *) sys_setfsuid16,
+ [ __NR_setfsgid ] = (syscall_handler_t *) sys_setfsgid16,
+ [ __NR_getdents ] = (syscall_handler_t *) sys_getdents,
+ [ __NR_flock ] = (syscall_handler_t *) sys_flock,
+ [ __NR_msync ] = (syscall_handler_t *) sys_msync,
+ [ __NR_readv ] = (syscall_handler_t *) sys_readv,
+ [ __NR_writev ] = (syscall_handler_t *) sys_writev,
+ [ __NR_getsid ] = (syscall_handler_t *) sys_getsid,
+ [ __NR_fdatasync ] = (syscall_handler_t *) sys_fdatasync,
[ __NR__sysctl ] = (syscall_handler_t *) sys_sysctl,
- [ __NR_mlock ] (syscall_handler_t *) sys_mlock,
- [ __NR_munlock ] (syscall_handler_t *) sys_munlock,
- [ __NR_mlockall ] (syscall_handler_t *) sys_mlockall,
- [ __NR_munlockall ] (syscall_handler_t *) sys_munlockall,
- [ __NR_sched_setparam ] (syscall_handler_t *) sys_sched_setparam,
- [ __NR_sched_getparam ] (syscall_handler_t *) sys_sched_getparam,
- [ __NR_sched_setscheduler ] (syscall_handler_t *) sys_sched_setscheduler,
- [ __NR_sched_getscheduler ] (syscall_handler_t *) sys_sched_getscheduler,
+ [ __NR_mlock ] = (syscall_handler_t *) sys_mlock,
+ [ __NR_munlock ] = (syscall_handler_t *) sys_munlock,
+ [ __NR_mlockall ] = (syscall_handler_t *) sys_mlockall,
+ [ __NR_munlockall ] = (syscall_handler_t *) sys_munlockall,
+ [ __NR_sched_setparam ] = (syscall_handler_t *) sys_sched_setparam,
+ [ __NR_sched_getparam ] = (syscall_handler_t *) sys_sched_getparam,
+ [ __NR_sched_setscheduler ] = (syscall_handler_t *) sys_sched_setscheduler,
+ [ __NR_sched_getscheduler ] = (syscall_handler_t *) sys_sched_getscheduler,
[ __NR_sched_yield ] = (syscall_handler_t *) yield,
- [ __NR_sched_get_priority_max ] (syscall_handler_t *) sys_sched_get_priority_max,
- [ __NR_sched_get_priority_min ] (syscall_handler_t *) sys_sched_get_priority_min,
- [ __NR_sched_rr_get_interval ] (syscall_handler_t *) sys_sched_rr_get_interval,
- [ __NR_nanosleep ] (syscall_handler_t *) sys_nanosleep,
- [ __NR_mremap ] (syscall_handler_t *) sys_mremap,
- [ __NR_setresuid ] (syscall_handler_t *) sys_setresuid16,
- [ __NR_getresuid ] (syscall_handler_t *) sys_getresuid16,
- [ __NR_vm86 ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_query_module ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_poll ] (syscall_handler_t *) sys_poll,
+ [ __NR_sched_get_priority_max ] = (syscall_handler_t *) sys_sched_get_priority_max,
+ [ __NR_sched_get_priority_min ] = (syscall_handler_t *) sys_sched_get_priority_min,
+ [ __NR_sched_rr_get_interval ] = (syscall_handler_t *) sys_sched_rr_get_interval,
+ [ __NR_nanosleep ] = (syscall_handler_t *) sys_nanosleep,
+ [ __NR_mremap ] = (syscall_handler_t *) sys_mremap,
+ [ __NR_setresuid ] = (syscall_handler_t *) sys_setresuid16,
+ [ __NR_getresuid ] = (syscall_handler_t *) sys_getresuid16,
+ [ __NR_query_module ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_poll ] = (syscall_handler_t *) sys_poll,
[ __NR_nfsservctl ] = (syscall_handler_t *) NFSSERVCTL,
- [ __NR_setresgid ] (syscall_handler_t *) sys_setresgid16,
- [ __NR_getresgid ] (syscall_handler_t *) sys_getresgid16,
- [ __NR_prctl ] (syscall_handler_t *) sys_prctl,
- [ __NR_rt_sigreturn ] (syscall_handler_t *) sys_rt_sigreturn,
- [ __NR_rt_sigaction ] (syscall_handler_t *) sys_rt_sigaction,
- [ __NR_rt_sigprocmask ] (syscall_handler_t *) sys_rt_sigprocmask,
- [ __NR_rt_sigpending ] (syscall_handler_t *) sys_rt_sigpending,
- [ __NR_rt_sigtimedwait ] (syscall_handler_t *) sys_rt_sigtimedwait,
- [ __NR_rt_sigqueueinfo ] (syscall_handler_t *) sys_rt_sigqueueinfo,
- [ __NR_rt_sigsuspend ] (syscall_handler_t *) sys_rt_sigsuspend,
- [ __NR_pread64 ] (syscall_handler_t *) sys_pread64,
- [ __NR_pwrite64 ] (syscall_handler_t *) sys_pwrite64,
- [ __NR_chown ] (syscall_handler_t *) sys_chown16,
- [ __NR_getcwd ] (syscall_handler_t *) sys_getcwd,
- [ __NR_capget ] (syscall_handler_t *) sys_capget,
- [ __NR_capset ] (syscall_handler_t *) sys_capset,
- [ __NR_sigaltstack ] (syscall_handler_t *) sys_sigaltstack,
- [ __NR_sendfile ] (syscall_handler_t *) sys_sendfile,
- [ __NR_getpmsg ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_putpmsg ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_vfork ] (syscall_handler_t *) sys_vfork,
- [ __NR_ugetrlimit ] (syscall_handler_t *) sys_getrlimit,
- [ __NR_mmap2 ] (syscall_handler_t *) sys_mmap2,
- [ __NR_truncate64 ] (syscall_handler_t *) sys_truncate64,
- [ __NR_ftruncate64 ] (syscall_handler_t *) sys_ftruncate64,
- [ __NR_stat64 ] (syscall_handler_t *) sys_stat64,
- [ __NR_lstat64 ] (syscall_handler_t *) sys_lstat64,
- [ __NR_fstat64 ] (syscall_handler_t *) sys_fstat64,
- [ __NR_getdents64 ] (syscall_handler_t *) sys_getdents64,
- [ __NR_fcntl64 ] (syscall_handler_t *) sys_fcntl64,
- [ 223 ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_gettid ] (syscall_handler_t *) sys_gettid,
- [ __NR_readahead ] (syscall_handler_t *) sys_readahead,
- [ __NR_setxattr ] (syscall_handler_t *) sys_setxattr,
- [ __NR_lsetxattr ] (syscall_handler_t *) sys_lsetxattr,
- [ __NR_fsetxattr ] (syscall_handler_t *) sys_fsetxattr,
- [ __NR_getxattr ] (syscall_handler_t *) sys_getxattr,
- [ __NR_lgetxattr ] (syscall_handler_t *) sys_lgetxattr,
- [ __NR_fgetxattr ] (syscall_handler_t *) sys_fgetxattr,
- [ __NR_listxattr ] (syscall_handler_t *) sys_listxattr,
- [ __NR_llistxattr ] (syscall_handler_t *) sys_llistxattr,
- [ __NR_flistxattr ] (syscall_handler_t *) sys_flistxattr,
- [ __NR_removexattr ] (syscall_handler_t *) sys_removexattr,
- [ __NR_lremovexattr ] (syscall_handler_t *) sys_lremovexattr,
- [ __NR_fremovexattr ] (syscall_handler_t *) sys_fremovexattr,
- [ __NR_tkill ] (syscall_handler_t *) sys_tkill,
- [ __NR_sendfile64 ] (syscall_handler_t *) sys_sendfile64,
- [ __NR_futex ] (syscall_handler_t *) sys_futex,
- [ __NR_sched_setaffinity ] (syscall_handler_t *) sys_sched_setaffinity,
- [ __NR_sched_getaffinity ] (syscall_handler_t *) sys_sched_getaffinity,
- [ __NR_set_thread_area ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_get_thread_area ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_io_setup ] (syscall_handler_t *) sys_io_setup,
- [ __NR_io_destroy ] (syscall_handler_t *) sys_io_destroy,
- [ __NR_io_getevents ] (syscall_handler_t *) sys_io_getevents,
- [ __NR_io_submit ] (syscall_handler_t *) sys_io_submit,
- [ __NR_io_cancel ] (syscall_handler_t *) sys_io_cancel,
- [ __NR_fadvise64 ] (syscall_handler_t *) sys_fadvise64,
- [ 251 ] (syscall_handler_t *) sys_ni_syscall,
- [ __NR_exit_group ] (syscall_handler_t *) sys_exit_group,
- [ __NR_lookup_dcookie ] (syscall_handler_t *) sys_lookup_dcookie,
- [ __NR_epoll_create ] (syscall_handler_t *) sys_epoll_create,
- [ __NR_epoll_ctl ] (syscall_handler_t *) sys_epoll_ctl,
- [ __NR_epoll_wait ] (syscall_handler_t *) sys_epoll_wait,
- [ __NR_remap_file_pages ] (syscall_handler_t *) sys_remap_file_pages,
- [ __NR_set_tid_address ] (syscall_handler_t *) sys_set_tid_address,
- [ __NR_timer_create ] (syscall_handler_t *) sys_timer_create,
- [ __NR_timer_settime ] (syscall_handler_t *) sys_timer_settime,
- [ __NR_timer_gettime ] (syscall_handler_t *) sys_timer_gettime,
- [ __NR_timer_getoverrun ] (syscall_handler_t *) sys_timer_getoverrun,
- [ __NR_timer_delete ] (syscall_handler_t *) sys_timer_delete,
- [ __NR_clock_settime ] (syscall_handler_t *) sys_clock_settime,
- [ __NR_clock_gettime ] (syscall_handler_t *) sys_clock_gettime,
- [ __NR_clock_getres ] (syscall_handler_t *) sys_clock_getres,
- [ __NR_clock_nanosleep ] (syscall_handler_t *) sys_clock_nanosleep,
- [ __NR_statfs64 ] (syscall_handler_t *) sys_statfs64,
- [ __NR_fstatfs64 ] (syscall_handler_t *) sys_fstatfs64,
- [ __NR_tgkill ] (syscall_handler_t *) sys_tgkill,
- [ __NR_utimes ] (syscall_handler_t *) sys_utimes,
- [ __NR_fadvise64_64 ] (syscall_handler_t *) sys_fadvise64_64,
- [ __NR_vserver ] (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_setresgid ] = (syscall_handler_t *) sys_setresgid16,
+ [ __NR_getresgid ] = (syscall_handler_t *) sys_getresgid16,
+ [ __NR_prctl ] = (syscall_handler_t *) sys_prctl,
+ [ __NR_rt_sigreturn ] = (syscall_handler_t *) sys_rt_sigreturn,
+ [ __NR_rt_sigaction ] = (syscall_handler_t *) sys_rt_sigaction,
+ [ __NR_rt_sigprocmask ] = (syscall_handler_t *) sys_rt_sigprocmask,
+ [ __NR_rt_sigpending ] = (syscall_handler_t *) sys_rt_sigpending,
+ [ __NR_rt_sigtimedwait ] = (syscall_handler_t *) sys_rt_sigtimedwait,
+ [ __NR_rt_sigqueueinfo ] = (syscall_handler_t *) sys_rt_sigqueueinfo,
+ [ __NR_rt_sigsuspend ] = (syscall_handler_t *) sys_rt_sigsuspend,
+ [ __NR_pread64 ] = (syscall_handler_t *) sys_pread64,
+ [ __NR_pwrite64 ] = (syscall_handler_t *) sys_pwrite64,
+ [ __NR_chown ] = (syscall_handler_t *) sys_chown16,
+ [ __NR_getcwd ] = (syscall_handler_t *) sys_getcwd,
+ [ __NR_capget ] = (syscall_handler_t *) sys_capget,
+ [ __NR_capset ] = (syscall_handler_t *) sys_capset,
+ [ __NR_sigaltstack ] = (syscall_handler_t *) sys_sigaltstack,
+ [ __NR_sendfile ] = (syscall_handler_t *) sys_sendfile,
+ [ __NR_getpmsg ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_putpmsg ] = (syscall_handler_t *) sys_ni_syscall,
+ [ __NR_vfork ] = (syscall_handler_t *) sys_vfork,
+ [ __NR_getdents64 ] = (syscall_handler_t *) sys_getdents64,
+ [ __NR_gettid ] = (syscall_handler_t *) sys_gettid,
+ [ __NR_readahead ] = (syscall_handler_t *) sys_readahead,
+ [ __NR_setxattr ] = (syscall_handler_t *) sys_setxattr,
+ [ __NR_lsetxattr ] = (syscall_handler_t *) sys_lsetxattr,
+ [ __NR_fsetxattr ] = (syscall_handler_t *) sys_fsetxattr,
+ [ __NR_getxattr ] = (syscall_handler_t *) sys_getxattr,
+ [ __NR_lgetxattr ] = (syscall_handler_t *) sys_lgetxattr,
+ [ __NR_fgetxattr ] = (syscall_handler_t *) sys_fgetxattr,
+ [ __NR_listxattr ] = (syscall_handler_t *) sys_listxattr,
+ [ __NR_llistxattr ] = (syscall_handler_t *) sys_llistxattr,
+ [ __NR_flistxattr ] = (syscall_handler_t *) sys_flistxattr,
+ [ __NR_removexattr ] = (syscall_handler_t *) sys_removexattr,
+ [ __NR_lremovexattr ] = (syscall_handler_t *) sys_lremovexattr,
+ [ __NR_fremovexattr ] = (syscall_handler_t *) sys_fremovexattr,
+ [ __NR_tkill ] = (syscall_handler_t *) sys_tkill,
+ [ __NR_futex ] = (syscall_handler_t *) sys_futex,
+ [ __NR_sched_setaffinity ] = (syscall_handler_t *) sys_sched_setaffinity,
+ [ __NR_sched_getaffinity ] = (syscall_handler_t *) sys_sched_getaffinity,
+ [ __NR_io_setup ] = (syscall_handler_t *) sys_io_setup,
+ [ __NR_io_destroy ] = (syscall_handler_t *) sys_io_destroy,
+ [ __NR_io_getevents ] = (syscall_handler_t *) sys_io_getevents,
+ [ __NR_io_submit ] = (syscall_handler_t *) sys_io_submit,
+ [ __NR_io_cancel ] = (syscall_handler_t *) sys_io_cancel,
+ [ __NR_exit_group ] = (syscall_handler_t *) sys_exit_group,
+ [ __NR_lookup_dcookie ] = (syscall_handler_t *) sys_lookup_dcookie,
+ [ __NR_epoll_create ] = (syscall_handler_t *) sys_epoll_create,
+ [ __NR_epoll_ctl ] = (syscall_handler_t *) sys_epoll_ctl,
+ [ __NR_epoll_wait ] = (syscall_handler_t *) sys_epoll_wait,
+ [ __NR_set_tid_address ] = (syscall_handler_t *) sys_set_tid_address,
+ [ __NR_timer_create ] = (syscall_handler_t *) sys_timer_create,
+ [ __NR_timer_settime ] = (syscall_handler_t *) sys_timer_settime,
+ [ __NR_timer_gettime ] = (syscall_handler_t *) sys_timer_gettime,
+ [ __NR_timer_getoverrun ] = (syscall_handler_t *) sys_timer_getoverrun,
+ [ __NR_timer_delete ] = (syscall_handler_t *) sys_timer_delete,
+ [ __NR_clock_settime ] = (syscall_handler_t *) sys_clock_settime,
+ [ __NR_clock_gettime ] = (syscall_handler_t *) sys_clock_gettime,
+ [ __NR_clock_getres ] = (syscall_handler_t *) sys_clock_getres,
+ [ __NR_clock_nanosleep ] = (syscall_handler_t *) sys_clock_nanosleep,
+ [ __NR_statfs64 ] = (syscall_handler_t *) sys_statfs64,
+ [ __NR_fstatfs64 ] = (syscall_handler_t *) sys_fstatfs64,
+ [ __NR_tgkill ] = (syscall_handler_t *) sys_tgkill,
+ [ __NR_utimes ] = (syscall_handler_t *) sys_utimes,
+ [ __NR_fadvise64_64 ] = (syscall_handler_t *) sys_fadvise64_64,
+ [ __NR_vserver ] = (syscall_handler_t *) sys_vserver,
+ [ __NR_mbind ] = (syscall_handler_t *) sys_mbind,
+ [ __NR_get_mempolicy ] = (syscall_handler_t *) sys_get_mempolicy,
+ [ __NR_set_mempolicy ] = (syscall_handler_t *) sys_set_mempolicy,
+ [ __NR_mq_open ] = (syscall_handler_t *) sys_mq_open,
+ [ __NR_mq_unlink ] = (syscall_handler_t *) sys_mq_unlink,
+ [ __NR_mq_timedsend ] = (syscall_handler_t *) sys_mq_timedsend,
+ [ __NR_mq_timedreceive ] = (syscall_handler_t *) sys_mq_timedreceive,
+ [ __NR_mq_notify ] = (syscall_handler_t *) sys_mq_notify,
+ [ __NR_mq_getsetattr ] = (syscall_handler_t *) sys_mq_getsetattr,
+ [ __NR_sys_kexec_load ] = (syscall_handler_t *) sys_kexec_load,
+ [ __NR_waitid ] = (syscall_handler_t *) sys_waitid,
+#if 0
+ [ __NR_sys_setaltroot ] = (syscall_handler_t *) sys_sys_setaltroot,
+#endif
+ [ __NR_add_key ] = (syscall_handler_t *) sys_add_key,
+ [ __NR_request_key ] = (syscall_handler_t *) sys_request_key,
+ [ __NR_keyctl ] = (syscall_handler_t *) sys_keyctl,
+ [ __NR_vperfctr_open ] = (syscall_handler_t *) sys_vperfctr_open,
+ [ __NR_vperfctr_control ] = (syscall_handler_t *) sys_vperfctr_control,
+ [ __NR_vperfctr_unlink ] = (syscall_handler_t *) sys_vperfctr_unlink,
+ [ __NR_vperfctr_iresume ] = (syscall_handler_t *) sys_vperfctr_iresume,
+ [ __NR_vperfctr_read ] = (syscall_handler_t *) sys_vperfctr_read,
ARCH_SYSCALLS
[ LAST_SYSCALL + 1 ... NR_syscalls ] =
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
index a549b3b1410f2b..a294e5071fe8f2 100644
--- a/arch/um/kernel/syscall_kern.c
+++ b/arch/um/kernel/syscall_kern.c
@@ -27,10 +27,9 @@
/* Unlocked, I don't care if this is a bit off */
int nsyscalls = 0;
-long um_mount(char * dev_name, char * dir_name, char * type,
- unsigned long new_flags, void * data)
+long um_mount(char __user * dev_name, char __user * dir_name,
+ char __user * type, unsigned long new_flags, void __user * data)
{
- if(type == NULL) type = "";
return(sys_mount(dev_name, dir_name, type, new_flags, data));
}
@@ -56,12 +55,11 @@ long sys_vfork(void)
}
/* common code for old and new mmaps */
-static inline long do_mmap2(
- unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
+long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
{
- int error = -EBADF;
+ long error = -EBADF;
struct file * file = NULL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
@@ -81,38 +79,15 @@ static inline long do_mmap2(
return error;
}
-long sys_mmap2(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long pgoff)
-{
- return do_mmap2(addr, len, prot, flags, fd, pgoff);
-}
-
-/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. Linux/i386 didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
- */
-
-struct mmap_arg_struct {
- unsigned long addr;
- unsigned long len;
- unsigned long prot;
- unsigned long flags;
- unsigned long fd;
- unsigned long offset;
-};
-
long old_mmap(unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, unsigned long offset)
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long offset)
{
long err = -EINVAL;
if (offset & ~PAGE_MASK)
goto out;
- err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+ err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
out:
return err;
}
@@ -120,7 +95,7 @@ long old_mmap(unsigned long addr, unsigned long len,
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way unix traditionally does this, though.
*/
-long sys_pipe(unsigned long * fildes)
+long sys_pipe(unsigned long __user * fildes)
{
int fd[2];
long error;
@@ -133,90 +108,6 @@ long sys_pipe(unsigned long * fildes)
return error;
}
-/*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
- */
-int sys_ipc (uint call, int first, int second,
- int third, void *ptr, long fifth)
-{
- int version, ret;
-
- version = call >> 16; /* hack for backward compatibility */
- call &= 0xffff;
-
- switch (call) {
- case SEMOP:
- return sys_semtimedop(first, (struct sembuf *) ptr, second,
- NULL);
- case SEMTIMEDOP:
- return sys_semtimedop(first, (struct sembuf *) ptr, second,
- (const struct timespec *) fifth);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
- if (!ptr)
- return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
- return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
-
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- panic("msgrcv with version != 0");
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second, (struct msqid_ds *) ptr);
-
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = do_shmat (first, (char *) ptr, second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return do_shmat (first, (char *) ptr, second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
- default:
- return -ENOSYS;
- }
-}
long sys_uname(struct old_utsname * name)
{
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
index 498344110eee03..df21b0529ae62a 100644
--- a/arch/um/kernel/time_kern.c
+++ b/arch/um/kernel/time_kern.c
@@ -111,19 +111,19 @@ irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
return(IRQ_HANDLED);
}
-long um_time(int * tloc)
+long um_time(int __user *tloc)
{
struct timeval now;
do_gettimeofday(&now);
if (tloc) {
- if (put_user(now.tv_sec,tloc))
+ if (put_user(now.tv_sec, tloc))
now.tv_sec = -EFAULT;
}
return now.tv_sec;
}
-long um_stime(int * tptr)
+long um_stime(int __user *tptr)
{
int value;
struct timespec new;
@@ -136,22 +136,7 @@ long um_stime(int * tptr)
return 0;
}
-/* XXX Needs to be moved under sys-i386 */
-void __delay(um_udelay_t time)
-{
- /* Stolen from the i386 __loop_delay */
- int d0;
- __asm__ __volatile__(
- "\tjmp 1f\n"
- ".align 16\n"
- "1:\tjmp 2f\n"
- ".align 16\n"
- "2:\tdecl %0\n\tjns 2b"
- :"=&a" (d0)
- :"0" (time));
-}
-
-void __udelay(um_udelay_t usecs)
+void __udelay(unsigned long usecs)
{
int i, n;
@@ -159,7 +144,7 @@ void __udelay(um_udelay_t usecs)
for(i=0;i<n;i++) ;
}
-void __const_udelay(um_udelay_t usecs)
+void __const_udelay(unsigned long usecs)
{
int i, n;
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index c42053140e2b91..26f5d12d81f340 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -59,9 +59,14 @@ pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
return(pgd_offset(mm, address));
}
-pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address)
+pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
{
- return(pmd_offset(pgd, address));
+ return(pud_offset(pgd, address));
+}
+
+pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
+{
+ return(pmd_offset(pud, address));
}
pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
@@ -71,8 +76,11 @@ pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
pte_t *addr_pte(struct task_struct *task, unsigned long addr)
{
- return(pte_offset_kernel(pmd_offset(pgd_offset(task->mm, addr), addr),
- addr));
+ pgd_t *pgd = pgd_offset(task->mm, addr);
+ pud_t *pud = pud_offset(pgd, addr);
+ pmd_t *pmd = pmd_offset(pud, addr);
+
+ return(pte_offset_map(pmd, addr));
}
/*
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
index cba33ef6da5d8c..80d07fe6b97923 100644
--- a/arch/um/kernel/trap_kern.c
+++ b/arch/um/kernel/trap_kern.c
@@ -13,6 +13,7 @@
#include "linux/ptrace.h"
#include "asm/semaphore.h"
#include "asm/pgtable.h"
+#include "asm/pgalloc.h"
#include "asm/tlbflush.h"
#include "asm/a.out.h"
#include "asm/current.h"
@@ -32,6 +33,7 @@ int handle_page_fault(unsigned long address, unsigned long ip,
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long page;
@@ -55,7 +57,8 @@ int handle_page_fault(unsigned long address, unsigned long ip,
goto out;
page = address & PAGE_MASK;
pgd = pgd_offset(mm, page);
- pmd = pmd_offset(pgd, page);
+ pud = pud_offset(pgd, page);
+ pmd = pmd_offset(pud, page);
do {
survive:
switch (handle_mm_fault(mm, vma, address, is_write)){
@@ -74,6 +77,9 @@ int handle_page_fault(unsigned long address, unsigned long ip,
default:
BUG();
}
+ pgd = pgd_offset(mm, page);
+ pud = pud_offset(pgd, page);
+ pmd = pmd_offset(pud, page);
pte = pte_offset_kernel(pmd, page);
} while(!pte_present(*pte));
err = 0;
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
index 73103c29aff715..0a3d279ce64f0c 100644
--- a/arch/um/kernel/trap_user.c
+++ b/arch/um/kernel/trap_user.c
@@ -102,28 +102,6 @@ struct signal_info sig_info[] = {
.is_irq = 0 },
};
-void sig_handler(int sig, struct sigcontext sc)
-{
- CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
- sig, &sc);
-}
-
-extern int timer_irq_inited;
-
-void alarm_handler(int sig, struct sigcontext sc)
-{
- if(!timer_irq_inited) return;
-
- if(sig == SIGALRM)
- switch_timers(0);
-
- CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
- sig, &sc);
-
- if(sig == SIGALRM)
- switch_timers(1);
-}
-
void do_longjmp(void *b, int val)
{
sigjmp_buf *buf = b;
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
index 17f4594dc2314b..7c9eec5fded52c 100644
--- a/arch/um/kernel/tt/Makefile
+++ b/arch/um/kernel/tt/Makefile
@@ -24,6 +24,9 @@ $(USER_OBJS) : %.o: %.c
$(obj)/unmap.o: $(src)/unmap.c
$(CC) $(UNMAP_CFLAGS) -c -o $@ $<
+LIBC_DIR ?= /usr/lib
+
$(obj)/unmap_fin.o : $(obj)/unmap.o
- ld -r -o $(obj)/unmap_tmp.o $< -lc -L/usr/lib
+ ld -r -o $(obj)/unmap_tmp.o $< -lc -L$(LIBC_DIR)
objcopy $(obj)/unmap_tmp.o $@ -G switcheroo
+
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
index 10db6d6ab7ea65..22cbdbffbe3e65 100644
--- a/arch/um/kernel/tt/gdb.c
+++ b/arch/um/kernel/tt/gdb.c
@@ -162,7 +162,7 @@ int gdb_remove(char *unused)
void signal_usr1(int sig)
{
if(debugger_pid != -1){
- printk(UM_KERN_ERR "The debugger is already running\n");
+ printf("The debugger is already running\n");
return;
}
debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
@@ -228,19 +228,19 @@ int debugger_signal(int status, pid_t pid){ return(0); }
void child_signal(pid_t pid, int status){ }
int init_ptrace_proxy(int idle_pid, int startup, int stop)
{
- printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
+ printf("debug requested when CONFIG_PT_PROXY is off\n");
kill_child_dead(idle_pid);
exit(1);
}
void signal_usr1(int sig)
{
- printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n");
+ printf("debug requested when CONFIG_PT_PROXY is off\n");
}
int attach_debugger(int idle_pid, int pid, int stop)
{
- printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY "
+ printf("attach_debugger called when CONFIG_PT_PROXY "
"is off\n");
return(-1);
}
diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
index 458ecf9a45f182..f41832c79f364d 100644
--- a/arch/um/kernel/tt/ptproxy/proxy.c
+++ b/arch/um/kernel/tt/ptproxy/proxy.c
@@ -94,7 +94,9 @@ int debugger_syscall(debugger_state *debugger, pid_t child)
debugger->handle_trace = debugger_syscall;
return(ret);
+#ifdef __NR_waitpid
case __NR_waitpid:
+#endif
case __NR_wait4:
if(!debugger_wait(debugger, (int *) arg2, arg3,
debugger_syscall, debugger_normal_return,
@@ -153,7 +155,11 @@ static int parent_syscall(debugger_state *debugger, int pid)
syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
- if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){
+ if((syscall == __NR_wait4)
+#ifdef __NR_waitpid
+ || (syscall == __NR_waitpid)
+#endif
+ ){
debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
parent_normal_return, parent_wait_return);
}
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
index c42855aeda6052..4545ea4f27e164 100644
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ b/arch/um/kernel/tt/ptproxy/sysdep.c
@@ -12,7 +12,6 @@ terms and conditions.
#include <errno.h>
#include <sys/types.h>
#include <sys/ptrace.h>
-#include <asm/ptrace.h>
#include <linux/unistd.h>
#include "ptrace_user.h"
#include "user_util.h"
diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
index 86ef67653e7261..fcb7ea50fc7e60 100644
--- a/arch/um/kernel/tt/ptproxy/wait.c
+++ b/arch/um/kernel/tt/ptproxy/wait.c
@@ -10,7 +10,6 @@ terms and conditions.
#include <signal.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
-#include <asm/ptrace.h>
#include "ptproxy.h"
#include "sysdep.h"
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
index 891045bb966a5c..c02e504e54c1b3 100644
--- a/arch/um/kernel/tt/syscall_kern.c
+++ b/arch/um/kernel/tt/syscall_kern.c
@@ -14,95 +14,6 @@
#include "sysdep/syscalls.h"
#include "kern_util.h"
-static inline int check_area(void *ptr, int size)
-{
- return(verify_area(VERIFY_WRITE, ptr, size));
-}
-
-static int check_readlink(struct pt_regs *regs)
-{
- return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
- UPT_SYSCALL_ARG2(&regs->regs)));
-}
-
-static int check_utime(struct pt_regs *regs)
-{
- return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
- sizeof(struct utimbuf)));
-}
-
-static int check_oldstat(struct pt_regs *regs)
-{
- return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
- sizeof(struct __old_kernel_stat)));
-}
-
-static int check_stat(struct pt_regs *regs)
-{
- return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
- sizeof(struct stat)));
-}
-
-static int check_stat64(struct pt_regs *regs)
-{
- return(check_area((void *) UPT_SYSCALL_ARG1(&regs->regs),
- sizeof(struct stat64)));
-}
-
-struct bogus {
- int kernel_ds;
- int (*check_params)(struct pt_regs *);
-};
-
-struct bogus this_is_bogus[256] = {
- [ __NR_mknod ] = { 1, NULL },
- [ __NR_mkdir ] = { 1, NULL },
- [ __NR_rmdir ] = { 1, NULL },
- [ __NR_unlink ] = { 1, NULL },
- [ __NR_symlink ] = { 1, NULL },
- [ __NR_link ] = { 1, NULL },
- [ __NR_rename ] = { 1, NULL },
- [ __NR_umount ] = { 1, NULL },
- [ __NR_mount ] = { 1, NULL },
- [ __NR_pivot_root ] = { 1, NULL },
- [ __NR_chdir ] = { 1, NULL },
- [ __NR_chroot ] = { 1, NULL },
- [ __NR_open ] = { 1, NULL },
- [ __NR_quotactl ] = { 1, NULL },
- [ __NR_sysfs ] = { 1, NULL },
- [ __NR_readlink ] = { 1, check_readlink },
- [ __NR_acct ] = { 1, NULL },
- [ __NR_execve ] = { 1, NULL },
- [ __NR_uselib ] = { 1, NULL },
- [ __NR_statfs ] = { 1, NULL },
- [ __NR_truncate ] = { 1, NULL },
- [ __NR_access ] = { 1, NULL },
- [ __NR_chmod ] = { 1, NULL },
- [ __NR_chown ] = { 1, NULL },
- [ __NR_lchown ] = { 1, NULL },
- [ __NR_utime ] = { 1, check_utime },
- [ __NR_oldlstat ] = { 1, check_oldstat },
- [ __NR_oldstat ] = { 1, check_oldstat },
- [ __NR_stat ] = { 1, check_stat },
- [ __NR_lstat ] = { 1, check_stat },
- [ __NR_stat64 ] = { 1, check_stat64 },
- [ __NR_lstat64 ] = { 1, check_stat64 },
- [ __NR_chown32 ] = { 1, NULL },
-};
-
-/* sys_utimes */
-
-static int check_bogosity(struct pt_regs *regs)
-{
- struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(&regs->regs)];
-
- if(!bogon->kernel_ds) return(0);
- if(bogon->check_params && (*bogon->check_params)(regs))
- return(-EFAULT);
- set_fs(KERNEL_DS);
- return(0);
-}
-
extern syscall_handler_t *sys_call_table[];
long execute_syscall_tt(void *r)
@@ -117,12 +28,8 @@ long execute_syscall_tt(void *r)
if((syscall >= NR_syscalls) || (syscall < 0))
res = -ENOSYS;
- else if(honeypot && check_bogosity(regs))
- res = -EFAULT;
else res = EXECUTE_SYSCALL(syscall, regs);
- set_fs(USER_DS);
-
return(res);
}
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
index d8ad334cfac933..3bc35eea1da4ad 100644
--- a/arch/um/kernel/tt/tlb.c
+++ b/arch/um/kernel/tt/tlb.c
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright 2003 PathScale, Inc.
* Licensed under the GPL
*/
@@ -19,9 +20,10 @@ static void fix_range(struct mm_struct *mm, unsigned long start_addr,
unsigned long end_addr, int force)
{
pgd_t *npgd;
+ pud_t *npud;
pmd_t *npmd;
pte_t *npte;
- unsigned long addr;
+ unsigned long addr, end;
int r, w, x, err;
if((current->thread.mode.tt.extern_pid != -1) &&
@@ -41,45 +43,81 @@ static void fix_range(struct mm_struct *mm, unsigned long start_addr,
addr = STACK_TOP - ABOVE_KMEM;
continue;
}
+
npgd = pgd_offset(mm, addr);
- npmd = pmd_offset(npgd, addr);
- if(pmd_present(*npmd)){
- npte = pte_offset_kernel(npmd, addr);
- r = pte_read(*npte);
- w = pte_write(*npte);
- x = pte_exec(*npte);
- if(!pte_dirty(*npte)) w = 0;
- if(!pte_young(*npte)){
- r = 0;
- w = 0;
- }
- if(force || pte_newpage(*npte)){
+ if(!pgd_present(*npgd)){
+ if(force || pgd_newpage(*npgd)){
+ end = addr + PGDIR_SIZE;
+ if(end > end_addr)
+ end = end_addr;
+ err = os_unmap_memory((void *) addr,
+ end - addr);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
+ pgd_mkuptodate(*npgd);
+ }
+ addr += PGDIR_SIZE;
+ continue;
+ }
+
+ npud = pud_offset(npgd, addr);
+ if(!pud_present(*npud)){
+ if(force || pud_newpage(*npud)){
+ end = addr + PUD_SIZE;
+ if(end > end_addr)
+ end = end_addr;
err = os_unmap_memory((void *) addr,
- PAGE_SIZE);
+ end - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
- if(pte_present(*npte))
- map_memory(addr,
- pte_val(*npte) & PAGE_MASK,
- PAGE_SIZE, r, w, x);
- }
- else if(pte_newprot(*npte)){
- protect_memory(addr, PAGE_SIZE, r, w, x, 1);
+ pud_mkuptodate(*npud);
}
- *npte = pte_mkuptodate(*npte);
- addr += PAGE_SIZE;
+ addr += PUD_SIZE;
+ continue;
}
- else {
+
+ npmd = pmd_offset(npud, addr);
+ if(!pmd_present(*npmd)){
if(force || pmd_newpage(*npmd)){
- err = os_unmap_memory((void *) addr, PMD_SIZE);
+ end = addr + PMD_SIZE;
+ if(end > end_addr)
+ end = end_addr;
+ err = os_unmap_memory((void *) addr,
+ end - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
pmd_mkuptodate(*npmd);
}
addr += PMD_SIZE;
+ continue;
}
+
+ npte = pte_offset_kernel(npmd, addr);
+ r = pte_read(*npte);
+ w = pte_write(*npte);
+ x = pte_exec(*npte);
+ if(!pte_dirty(*npte))
+ w = 0;
+ if(!pte_young(*npte)){
+ r = 0;
+ w = 0;
+ }
+ if(force || pte_newpage(*npte)){
+ err = os_unmap_memory((void *) addr, PAGE_SIZE);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n", -err);
+ if(pte_present(*npte))
+ map_memory(addr, pte_val(*npte) & PAGE_MASK,
+ PAGE_SIZE, r, w, x);
+ }
+ else if(pte_newprot(*npte))
+ protect_memory(addr, PAGE_SIZE, r, w, x, 1);
+
+ *npte = pte_mkuptodate(*npte);
+ addr += PAGE_SIZE;
}
}
@@ -90,45 +128,83 @@ static void flush_kernel_vm_range(unsigned long start, unsigned long end,
{
struct mm_struct *mm;
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
- unsigned long addr;
+ unsigned long addr, last;
int updated = 0, err;
mm = &init_mm;
for(addr = start; addr < end;){
pgd = pgd_offset(mm, addr);
- pmd = pmd_offset(pgd, addr);
- if(pmd_present(*pmd)){
- pte = pte_offset_kernel(pmd, addr);
- if(!pte_present(*pte) || pte_newpage(*pte)){
+ if(!pgd_present(*pgd)){
+ if(pgd_newpage(*pgd)){
updated = 1;
+ last = addr + PGDIR_SIZE;
+ if(last > end)
+ last = end;
err = os_unmap_memory((void *) addr,
- PAGE_SIZE);
+ last - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
- if(pte_present(*pte))
- map_memory(addr,
- pte_val(*pte) & PAGE_MASK,
- PAGE_SIZE, 1, 1, 1);
}
- else if(pte_newprot(*pte)){
+ addr += PGDIR_SIZE;
+ continue;
+ }
+
+ pud = pud_offset(pgd, addr);
+ if(!pud_present(*pud)){
+ if(pud_newpage(*pud)){
updated = 1;
- protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
+ last = addr + PUD_SIZE;
+ if(last > end)
+ last = end;
+ err = os_unmap_memory((void *) addr,
+ last - addr);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
}
- addr += PAGE_SIZE;
+ addr += PUD_SIZE;
+ continue;
}
- else {
+
+ pmd = pmd_offset(pud, addr);
+ if(!pmd_present(*pmd)){
if(pmd_newpage(*pmd)){
updated = 1;
- err = os_unmap_memory((void *) addr, PMD_SIZE);
+ last = addr + PMD_SIZE;
+ if(last > end)
+ last = end;
+ err = os_unmap_memory((void *) addr,
+ last - addr);
if(err < 0)
panic("munmap failed, errno = %d\n",
-err);
}
addr += PMD_SIZE;
+ continue;
+ }
+
+ pte = pte_offset_kernel(pmd, addr);
+ if(!pte_present(*pte) || pte_newpage(*pte)){
+ updated = 1;
+ err = os_unmap_memory((void *) addr,
+ PAGE_SIZE);
+ if(err < 0)
+ panic("munmap failed, errno = %d\n",
+ -err);
+ if(pte_present(*pte))
+ map_memory(addr,
+ pte_val(*pte) & PAGE_MASK,
+ PAGE_SIZE, 1, 1, 1);
+ }
+ else if(pte_newprot(*pte)){
+ updated = 1;
+ protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
}
+ addr += PAGE_SIZE;
}
if(updated && update_seq) atomic_inc(&vmchange_seq);
}
@@ -155,6 +231,7 @@ void mprotect_kernel_vm(int w)
{
struct mm_struct *mm;
pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
pte_t *pte;
unsigned long addr;
@@ -162,7 +239,8 @@ void mprotect_kernel_vm(int w)
mm = &init_mm;
for(addr = start_vm; addr < end_vm;){
pgd = pgd_offset(mm, addr);
- pmd = pmd_offset(pgd, addr);
+ pud = pud_offset(pgd, addr);
+ pmd = pmd_offset(pud, addr);
if(pmd_present(*pmd)){
pte = pte_offset_kernel(pmd, addr);
if(pte_present(*pte)) protect_vm_page(addr, w, 0);
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
index e1f3506e9d1d73..de5dcd2504256e 100644
--- a/arch/um/kernel/tt/tracer.c
+++ b/arch/um/kernel/tt/tracer.c
@@ -84,6 +84,7 @@ void tracer_panic(char *format, ...)
va_start(ap, format);
vprintf(format, ap);
+ va_end(ap);
printf("\n");
while(1) pause();
}
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
index 00bacacfcc3529..67fdef69d54eed 100644
--- a/arch/um/kernel/tt/trap_user.c
+++ b/arch/um/kernel/tt/trap_user.c
@@ -6,7 +6,6 @@
#include <stdlib.h>
#include <errno.h>
#include <signal.h>
-#include <asm/sigcontext.h>
#include "sysdep/ptrace.h"
#include "signal_user.h"
#include "user_util.h"
diff --git a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
index 0409718935f71e..a72aa632972f4e 100644
--- a/arch/um/kernel/tt/uaccess.c
+++ b/arch/um/kernel/tt/uaccess.c
@@ -6,7 +6,7 @@
#include "linux/sched.h"
#include "asm/uaccess.h"
-int copy_from_user_tt(void *to, const void *from, int n)
+int copy_from_user_tt(void *to, const void __user *from, int n)
{
if(!access_ok_tt(VERIFY_READ, from, n))
return(n);
@@ -15,7 +15,7 @@ int copy_from_user_tt(void *to, const void *from, int n)
&current->thread.fault_catcher));
}
-int copy_to_user_tt(void *to, const void *from, int n)
+int copy_to_user_tt(void __user *to, const void *from, int n)
{
if(!access_ok_tt(VERIFY_WRITE, to, n))
return(n);
@@ -24,7 +24,7 @@ int copy_to_user_tt(void *to, const void *from, int n)
&current->thread.fault_catcher));
}
-int strncpy_from_user_tt(char *dst, const char *src, int count)
+int strncpy_from_user_tt(char *dst, const char __user *src, int count)
{
int n;
@@ -38,14 +38,14 @@ int strncpy_from_user_tt(char *dst, const char *src, int count)
return(n);
}
-int __clear_user_tt(void *mem, int len)
+int __clear_user_tt(void __user *mem, int len)
{
return(__do_clear_user(mem, len,
&current->thread.fault_addr,
&current->thread.fault_catcher));
}
-int clear_user_tt(void *mem, int len)
+int clear_user_tt(void __user *mem, int len)
{
if(!access_ok_tt(VERIFY_WRITE, mem, len))
return(len);
@@ -54,7 +54,7 @@ int clear_user_tt(void *mem, int len)
&current->thread.fault_catcher));
}
-int strnlen_user_tt(const void *str, int len)
+int strnlen_user_tt(const void __user *str, int len)
{
return(__do_strnlen_user(str, len,
&current->thread.fault_addr,
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index 1ce25f89f8acf3..8096843e4d4cba 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -17,6 +17,7 @@
#include "linux/sysrq.h"
#include "linux/seq_file.h"
#include "linux/delay.h"
+#include "linux/module.h"
#include "asm/page.h"
#include "asm/pgtable.h"
#include "asm/ptrace.h"
@@ -156,6 +157,8 @@ static int __init uml_version_setup(char *line, int *add)
{
printf("%s\n", system_utsname.release);
exit(0);
+
+ return 0;
}
__uml_setup("--version", uml_version_setup,
@@ -256,6 +259,8 @@ static int __init Usage(char *line, int *add)
p++;
}
exit(0);
+
+ return 0;
}
__uml_setup("--help", Usage,
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 3521466db282a7..f8378124be1357 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -3,10 +3,13 @@
# Licensed under the GPL
#
-obj-y = elf_aux.o file.o process.o time.o tty.o user_syms.o drivers/
+obj-y = elf_aux.o file.o process.o signal.o time.o tty.o user_syms.o drivers/ \
+ sys-$(SUBARCH)/
-USER_OBJS := elf_aux.o file.o process.o time.o tty.o
+USER_OBJS := elf_aux.o file.o process.o signal.o time.o tty.o
USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
$(USER_OBJS) : %.o: %.c
$(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+
+CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c
index 36575ff8bfac7e..9aee0b62ebca19 100644
--- a/arch/um/os-Linux/elf_aux.c
+++ b/arch/um/os-Linux/elf_aux.c
@@ -26,7 +26,6 @@ unsigned long vsyscall_end;
unsigned long __kernel_vsyscall;
-
__init void scan_elf_aux( char **envp)
{
long page_size = 0;
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
new file mode 100644
index 00000000000000..7eac1baf597568
--- /dev/null
+++ b/arch/um/os-Linux/signal.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#include <signal.h>
+#include "time_user.h"
+#include "mode.h"
+#include "sysdep/signal.h"
+
+void sig_handler(int sig)
+{
+ struct sigcontext *sc;
+
+ ARCH_GET_SIGCONTEXT(sc, sig);
+ CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
+ sig, sc);
+}
+
+extern int timer_irq_inited;
+
+void alarm_handler(int sig)
+{
+ struct sigcontext *sc;
+
+ ARCH_GET_SIGCONTEXT(sc, sig);
+ if(!timer_irq_inited) return;
+
+ if(sig == SIGALRM)
+ switch_timers(0);
+
+ CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas,
+ sig, sc);
+
+ if(sig == SIGALRM)
+ switch_timers(1);
+}
+
+/*
+ * 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/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
new file mode 100644
index 00000000000000..bdfa841fca165d
--- /dev/null
+++ b/arch/um/os-Linux/sys-i386/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+# Licensed under the GPL
+#
+
+obj-$(CONFIG_MODE_SKAS) = registers.o
+
+USER_OBJS := $(foreach file,$(obj-y),$(obj)/$(file))
+
+$(USER_OBJS) : %.o: %.c
+ $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
new file mode 100644
index 00000000000000..cbfbaf2ab78d81
--- /dev/null
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/ptrace.h>
+#include "sysdep/ptrace.h"
+#include "uml-config.h"
+#include "skas_ptregs.h"
+#include "registers.h"
+#include "user.h"
+
+/* These are set once at boot time and not changed thereafter */
+
+static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_fp_regs[HOST_FP_SIZE];
+static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
+static int have_fpx_regs = 1;
+
+void init_thread_registers(union uml_pt_regs *to)
+{
+ memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
+ memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
+ if(have_fpx_regs)
+ memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp));
+}
+
+static int move_registers(int pid, int int_op, union uml_pt_regs *regs,
+ int fp_op, unsigned long *fp_regs)
+{
+ if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
+ return(-errno);
+
+ if(ptrace(fp_op, pid, 0, fp_regs) < 0)
+ return(-errno);
+
+ return(0);
+}
+
+void save_registers(int pid, union uml_pt_regs *regs)
+{
+ unsigned long *fp_regs;
+ int err, fp_op;
+
+ if(have_fpx_regs){
+ fp_op = PTRACE_GETFPXREGS;
+ fp_regs = regs->skas.xfp;
+ }
+ else {
+ fp_op = PTRACE_GETFPREGS;
+ fp_regs = regs->skas.fp;
+ }
+
+ err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs);
+ if(err)
+ panic("save_registers - saving registers failed, errno = %d\n",
+ -err);
+}
+
+void restore_registers(int pid, union uml_pt_regs *regs)
+{
+ unsigned long *fp_regs;
+ int err, fp_op;
+
+ if(have_fpx_regs){
+ fp_op = PTRACE_SETFPXREGS;
+ fp_regs = regs->skas.xfp;
+ }
+ else {
+ fp_op = PTRACE_SETFPREGS;
+ fp_regs = regs->skas.fp;
+ }
+
+ err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs);
+ if(err)
+ panic("restore_registers - saving registers failed, "
+ "errno = %d\n", -err);
+}
+
+void init_registers(int pid)
+{
+ int err;
+
+ err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
+ if(err)
+ panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
+ err);
+
+ err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
+ if(!err)
+ return;
+
+ have_fpx_regs = 0;
+ if(err != EIO)
+ panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
+ err);
+
+ err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
+ if(err)
+ panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
+ err);
+}
+
+/*
+ * 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/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile
new file mode 100644
index 00000000000000..bdfa841fca165d
--- /dev/null
+++ b/arch/um/os-Linux/sys-x86_64/Makefile
@@ -0,0 +1,11 @@
+#
+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+# Licensed under the GPL
+#
+
+obj-$(CONFIG_MODE_SKAS) = registers.o
+
+USER_OBJS := $(foreach file,$(obj-y),$(obj)/$(file))
+
+$(USER_OBJS) : %.o: %.c
+ $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
new file mode 100644
index 00000000000000..31b1f4fa67e0e0
--- /dev/null
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (C) 2004 PathScale, Inc
+ * Licensed under the GPL
+ */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/ptrace.h>
+#include "sysdep/ptrace.h"
+#include "uml-config.h"
+#include "skas_ptregs.h"
+#include "registers.h"
+#include "user.h"
+
+/* These are set once at boot time and not changed thereafter */
+
+static unsigned long exec_regs[HOST_FRAME_SIZE];
+static unsigned long exec_fp_regs[HOST_FP_SIZE];
+
+void init_thread_registers(union uml_pt_regs *to)
+{
+ memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
+ memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
+}
+
+static int move_registers(int pid, int int_op, int fp_op,
+ union uml_pt_regs *regs)
+{
+ if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
+ return(-errno);
+
+ if(ptrace(fp_op, pid, 0, regs->skas.fp) < 0)
+ return(-errno);
+
+ return(0);
+}
+
+void save_registers(int pid, union uml_pt_regs *regs)
+{
+ int err;
+
+ err = move_registers(pid, PTRACE_GETREGS, PTRACE_GETFPREGS, regs);
+ if(err)
+ panic("save_registers - saving registers failed, errno = %d\n",
+ -err);
+}
+
+void restore_registers(int pid, union uml_pt_regs *regs)
+{
+ int err;
+
+ err = move_registers(pid, PTRACE_SETREGS, PTRACE_SETFPREGS, regs);
+ if(err)
+ panic("restore_registers - saving registers failed, "
+ "errno = %d\n", -err);
+}
+
+void init_registers(int pid)
+{
+ int err;
+
+ err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
+ if(err)
+ panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
+ err);
+
+ err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
+ if(err)
+ panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
+ err);
+}
+
+/*
+ * 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/os-Linux/user_syms.c b/arch/um/os-Linux/user_syms.c
index 383ac7b52beb0a..75d7af9ae1d226 100644
--- a/arch/um/os-Linux/user_syms.c
+++ b/arch/um/os-Linux/user_syms.c
@@ -26,9 +26,6 @@ EXPORT_SYMBOL(printf);
EXPORT_SYMBOL(strstr);
-EXPORT_SYMBOL(vsyscall_ehdr);
-EXPORT_SYMBOL(vsyscall_end);
-
/* Here, instead, I can provide a fake prototype. Yes, someone cares: genksyms.
* However, the modules will use the CRC defined *here*, no matter if it is
* good; so the versions of these symbols will always match
@@ -37,6 +34,11 @@ EXPORT_SYMBOL(vsyscall_end);
int sym(void); \
EXPORT_SYMBOL(sym);
+#ifdef SUBARCH_i386
+EXPORT_SYMBOL(vsyscall_ehdr);
+EXPORT_SYMBOL(vsyscall_end);
+#endif
+
EXPORT_SYMBOL_PROTO(__errno_location);
EXPORT_SYMBOL_PROTO(access);
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index 45cc75f63a756f..8a0994b696b00f 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,4 +1,4 @@
-obj-y = bitops.o bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o \
+obj-y = bitops.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
ptrace_user.o semaphore.o signal.o sigcontext.o syscalls.o sysrq.o
obj-$(CONFIG_HIGHMEM) += highmem.o
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c
new file mode 100644
index 00000000000000..20d37dbbaf08be
--- /dev/null
+++ b/arch/um/sys-i386/delay.c
@@ -0,0 +1,14 @@
+void __delay(unsigned long time)
+{
+ /* Stolen from the i386 __loop_delay */
+ int d0;
+ __asm__ __volatile__(
+ "\tjmp 1f\n"
+ ".align 16\n"
+ "1:\tjmp 2f\n"
+ ".align 16\n"
+ "2:\tdecl %0\n\tjns 2b"
+ :"=&a" (d0)
+ :"0" (time));
+}
+
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index ba77ccaa836122..e97b98806af797 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -15,17 +15,21 @@ extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
/* XXX this needs copy_to_user and copy_from_user */
-int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
+int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)
{
- if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT);
- return(modify_ldt(func, ptr, bytecount));
+ if (verify_area(VERIFY_READ, ptr, bytecount))
+ return -EFAULT;
+
+ return modify_ldt(func, ptr, bytecount);
}
#endif
#ifdef CONFIG_MODE_SKAS
extern int userspace_pid;
-int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
+#include "skas_ptrace.h"
+
+int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)
{
struct ptrace_ldt ldt;
void *buf;
@@ -74,7 +78,7 @@ int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
}
#endif
-int sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
{
return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
ptr, bytecount));
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 42322d88850349..c6a1bba337eacb 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -3,6 +3,8 @@
* Licensed under the GPL
*/
+#include <linux/config.h>
+#include <linux/compiler.h>
#include "linux/sched.h"
#include "asm/elf.h"
#include "asm/ptrace.h"
@@ -22,7 +24,7 @@ int is_syscall(unsigned long addr)
unsigned short instr;
int n;
- n = copy_from_user(&instr, (void *) addr, sizeof(instr));
+ n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
if(n){
printk("is_syscall : failed to read instruction from 0x%lx\n",
addr);
@@ -175,12 +177,12 @@ static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave
*/
#ifdef CONFIG_MODE_TT
-static inline int convert_fxsr_to_user_tt(struct _fpstate *buf,
+static inline int convert_fxsr_to_user_tt(struct _fpstate __user *buf,
struct pt_regs *regs)
{
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
unsigned long env[7];
- struct _fpreg *to;
+ struct _fpreg __user *to;
struct _fpxreg *from;
int i;
@@ -205,7 +207,7 @@ static inline int convert_fxsr_to_user_tt(struct _fpstate *buf,
}
#endif
-static inline int convert_fxsr_to_user(struct _fpstate *buf,
+static inline int convert_fxsr_to_user(struct _fpstate __user *buf,
struct pt_regs *regs)
{
return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0));
@@ -213,12 +215,12 @@ static inline int convert_fxsr_to_user(struct _fpstate *buf,
#ifdef CONFIG_MODE_TT
static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
- struct _fpstate *buf)
+ struct _fpstate __user *buf)
{
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
unsigned long env[7];
struct _fpxreg *to;
- struct _fpreg *from;
+ struct _fpreg __user *from;
int i;
if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
@@ -244,7 +246,7 @@ static inline int convert_fxsr_from_user_tt(struct pt_regs *regs,
#endif
static inline int convert_fxsr_from_user(struct pt_regs *regs,
- struct _fpstate *buf)
+ struct _fpstate __user *buf)
{
return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
}
@@ -253,7 +255,7 @@ int get_fpregs(unsigned long buf, struct task_struct *child)
{
int err;
- err = convert_fxsr_to_user((struct _fpstate *) buf,
+ err = convert_fxsr_to_user((struct _fpstate __user *) buf,
&child->thread.regs);
if(err) return(-EFAULT);
else return(0);
@@ -264,7 +266,7 @@ int set_fpregs(unsigned long buf, struct task_struct *child)
int err;
err = convert_fxsr_from_user(&child->thread.regs,
- (struct _fpstate *) buf);
+ (struct _fpstate __user *) buf);
if(err) return(-EFAULT);
else return(0);
}
@@ -276,7 +278,7 @@ int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
int err;
- err = __copy_to_user((void *) buf, fxsave,
+ err = __copy_to_user((void __user *) buf, fxsave,
sizeof(struct user_fxsr_struct));
if(err) return -EFAULT;
else return 0;
@@ -295,7 +297,7 @@ int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
int err;
- err = __copy_from_user(fxsave, (void *) buf,
+ err = __copy_from_user(fxsave, (void __user *) buf,
sizeof(struct user_fxsr_struct) );
if(err) return -EFAULT;
else return 0;
diff --git a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c
index a30140331cf7f9..467d489c31cd00 100644
--- a/arch/um/sys-i386/sigcontext.c
+++ b/arch/um/sys-i386/sigcontext.c
@@ -22,8 +22,7 @@ void sc_to_sc(void *to_ptr, void *from_ptr)
unsigned long *sc_sigmask(void *sc_ptr)
{
struct sigcontext *sc = sc_ptr;
-
- return(&sc->oldmask);
+ return &sc->oldmask;
}
int sc_get_fpregs(unsigned long buf, void *sc_ptr)
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 6794671be7a36b..0cb4c86b5c2b5b 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -146,7 +146,7 @@ int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
}
#endif
-static int copy_sc_from_user(struct pt_regs *to, void *from)
+static int copy_sc_from_user(struct pt_regs *to, void __user *from)
{
int ret;
diff --git a/arch/um/sys-i386/syscalls.c b/arch/um/sys-i386/syscalls.c
index 6ad31749bfe721..dd58b5511e9b6e 100644
--- a/arch/um/sys-i386/syscalls.c
+++ b/arch/um/sys-i386/syscalls.c
@@ -1,9 +1,11 @@
/*
- * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
* Licensed under the GPL
*/
#include "linux/sched.h"
+#include "linux/shm.h"
+#include "asm/ipc.h"
#include "asm/mman.h"
#include "asm/uaccess.h"
#include "asm/unistd.h"
@@ -28,7 +30,7 @@ extern int old_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
unsigned long fd, unsigned long offset);
-int old_mmap_i386(struct mmap_arg_struct *arg)
+long old_mmap_i386(struct mmap_arg_struct __user *arg)
{
struct mmap_arg_struct a;
int err = -EFAULT;
@@ -43,11 +45,13 @@ int old_mmap_i386(struct mmap_arg_struct *arg)
struct sel_arg_struct {
unsigned long n;
- fd_set *inp, *outp, *exp;
- struct timeval *tvp;
+ fd_set __user *inp;
+ fd_set __user *outp;
+ fd_set __user *exp;
+ struct timeval __user *tvp;
};
-int old_select(struct sel_arg_struct *arg)
+long old_select(struct sel_arg_struct __user *arg)
{
struct sel_arg_struct a;
@@ -60,8 +64,8 @@ int old_select(struct sel_arg_struct *arg)
/* The i386 version skips reading from %esi, the fourth argument. So we must do
* this, too.
*/
-int sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tid,
- int unused, int *child_tid)
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+ int __user *parent_tid, int unused, int __user *child_tid)
{
long ret;
@@ -79,6 +83,122 @@ int sys_clone(unsigned long clone_flags, unsigned long newsp, int *parent_tid,
}
/*
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls..
+ *
+ * This is really horribly ugly.
+ */
+long sys_ipc (uint call, int first, int second,
+ int third, void *__user ptr, long fifth)
+{
+ int version, ret;
+
+ version = call >> 16; /* hack for backward compatibility */
+ call &= 0xffff;
+
+ switch (call) {
+ case SEMOP:
+ return sys_semtimedop(first, (struct sembuf *) ptr, second,
+ NULL);
+ case SEMTIMEDOP:
+ return sys_semtimedop(first, (struct sembuf *) ptr, second,
+ (const struct timespec *) fifth);
+ case SEMGET:
+ return sys_semget (first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ if (!ptr)
+ return -EINVAL;
+ if (get_user(fourth.__pad, (void **) ptr))
+ return -EFAULT;
+ return sys_semctl (first, second, third, fourth);
+ }
+
+ case MSGSND:
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
+ if (!ptr)
+ return -EINVAL;
+
+ if (copy_from_user(&tmp,
+ (struct ipc_kludge *) ptr,
+ sizeof (tmp)))
+ return -EFAULT;
+ return sys_msgrcv (first, tmp.msgp, second,
+ tmp.msgtyp, third);
+ }
+ default:
+ panic("msgrcv with version != 0");
+ return sys_msgrcv (first,
+ (struct msgbuf *) ptr,
+ second, fifth, third);
+ }
+ case MSGGET:
+ return sys_msgget ((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+ case SHMAT:
+ switch (version) {
+ default: {
+ ulong raddr;
+ ret = do_shmat (first, (char *) ptr, second, &raddr);
+ if (ret)
+ return ret;
+ return put_user (raddr, (ulong *) third);
+ }
+ case 1: /* iBCS2 emulator entry point */
+ if (!segment_eq(get_fs(), get_ds()))
+ return -EINVAL;
+ return do_shmat (first, (char *) ptr, second, (ulong *) third);
+ }
+ case SHMDT:
+ return sys_shmdt ((char *)ptr);
+ case SHMGET:
+ return sys_shmget (first, second, third);
+ case SHMCTL:
+ return sys_shmctl (first, second,
+ (struct shmid_ds *) ptr);
+ default:
+ return -ENOSYS;
+ }
+}
+
+long sys_sigaction(int sig, const struct old_sigaction __user *act,
+ struct old_sigaction __user *oact)
+{
+ struct k_sigaction new_ka, old_ka;
+ int ret;
+
+ if (act) {
+ old_sigset_t mask;
+ if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+ return -EFAULT;
+ __get_user(new_ka.sa.sa_flags, &act->sa_flags);
+ __get_user(mask, &act->sa_mask);
+ siginitset(&new_ka.sa.sa_mask, mask);
+ }
+
+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
+
+ if (!ret && oact) {
+ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+ return -EFAULT;
+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
+ }
+
+ return ret;
+}
+
+/*
* 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
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
new file mode 100644
index 00000000000000..1ec504b7681091
--- /dev/null
+++ b/arch/um/sys-x86_64/Makefile
@@ -0,0 +1,39 @@
+#
+# Copyright 2003 PathScale, Inc.
+#
+# Licensed under the GPL
+#
+
+lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \
+ ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \
+ syscalls.o sysrq.o thunk.o
+
+USER_OBJS := ptrace_user.o sigcontext.o
+USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
+
+SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \
+ semaphore.c thunk.S
+SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
+
+clean-files := $(SYMLINKS)
+
+bitops.c-dir = lib
+csum-copy.S-dir = lib
+csum-partial.c-dir = lib
+csum-wrappers.c-dir = lib
+memcpy.S-dir = lib
+semaphore.c-dir = kernel
+thunk.S-dir = lib
+
+define make_link
+ -rm -f $1
+ ln -sf $(TOPDIR)/arch/x86_64/$($(notdir $1)-dir)/$(notdir $1) $1
+endef
+
+$(SYMLINKS):
+ $(call make_link,$@)
+
+$(USER_OBJS) : %.o: %.c
+ $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
+
+CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial
diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c
new file mode 100644
index 00000000000000..fdce7ea98ca79c
--- /dev/null
+++ b/arch/um/sys-x86_64/bugs.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/sched.h"
+#include "linux/errno.h"
+#include "asm/system.h"
+#include "asm/pda.h"
+#include "sysdep/ptrace.h"
+#include "os.h"
+
+void arch_init_thread(void)
+{
+}
+
+void arch_check_bugs(void)
+{
+}
+
+int arch_handle_signal(int sig, union uml_pt_regs *regs)
+{
+ return(0);
+}
+
+#define MAXTOKEN 64
+
+/* Set during early boot */
+int host_has_cmov = 1;
+int host_has_xmm = 0;
+
+static char token(int fd, char *buf, int len, char stop)
+{
+ int n;
+ char *ptr, *end, c;
+
+ ptr = buf;
+ end = &buf[len];
+ do {
+ n = os_read_file(fd, ptr, sizeof(*ptr));
+ c = *ptr++;
+ if(n != sizeof(*ptr)){
+ if(n == 0) return(0);
+ printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
+ if(n < 0)
+ return(n);
+ else
+ return(-EIO);
+ }
+ } while((c != '\n') && (c != stop) && (ptr < end));
+
+ if(ptr == end){
+ printk("Failed to find '%c' in /proc/cpuinfo\n", stop);
+ return(-1);
+ }
+ *(ptr - 1) = '\0';
+ return(c);
+}
+
+static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
+{
+ int n;
+ char c;
+
+ scratch[len - 1] = '\0';
+ while(1){
+ c = token(fd, scratch, len - 1, ':');
+ if(c <= 0)
+ return(0);
+ else if(c != ':'){
+ printk("Failed to find ':' in /proc/cpuinfo\n");
+ return(0);
+ }
+
+ if(!strncmp(scratch, key, strlen(key)))
+ return(1);
+
+ do {
+ n = os_read_file(fd, &c, sizeof(c));
+ if(n != sizeof(c)){
+ printk("Failed to find newline in "
+ "/proc/cpuinfo, err = %d\n", -n);
+ return(0);
+ }
+ } while(c != '\n');
+ }
+ return(0);
+}
+
+int cpu_feature(char *what, char *buf, int len)
+{
+ int fd, ret = 0;
+
+ fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
+ if(fd < 0){
+ printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
+ return(0);
+ }
+
+ if(!find_cpuinfo_line(fd, what, buf, len)){
+ printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
+ goto out_close;
+ }
+
+ token(fd, buf, len, '\n');
+ ret = 1;
+
+ out_close:
+ os_close_file(fd);
+ return(ret);
+}
+
+/* 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/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c
new file mode 100644
index 00000000000000..f3b5187942b4e6
--- /dev/null
+++ b/arch/um/sys-x86_64/delay.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ * Copied from arch/x86_64
+ *
+ * Licensed under the GPL
+ */
+
+#include "asm/processor.h"
+
+void __delay(unsigned long loops)
+{
+ unsigned long i;
+
+ for(i = 0; i < loops; i++) ;
+}
+
+/*
+ * 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/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c
new file mode 100644
index 00000000000000..cee1513c5c3163
--- /dev/null
+++ b/arch/um/sys-x86_64/fault.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "user.h"
+
+int arch_fixup(unsigned long address, void *sc_ptr)
+{
+ /* XXX search_exception_tables() */
+ return(0);
+}
+
+/* Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/sys-x86_64/mem.c b/arch/um/sys-x86_64/mem.c
new file mode 100644
index 00000000000000..3f59a0a4f15604
--- /dev/null
+++ b/arch/um/sys-x86_64/mem.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/mm.h"
+#include "asm/page.h"
+#include "asm/mman.h"
+
+unsigned long vm_stack_flags = __VM_STACK_FLAGS;
+unsigned long vm_stack_flags32 = __VM_STACK_FLAGS;
+unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS;
+unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS;
+unsigned long vm_force_exec32 = PROT_EXEC;
+
+/* 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/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
new file mode 100644
index 00000000000000..8c146b2a1e00ae
--- /dev/null
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#define __FRAME_OFFSETS
+#include "asm/ptrace.h"
+#include "linux/sched.h"
+#include "linux/errno.h"
+#include "asm/elf.h"
+
+/* XXX x86_64 */
+unsigned long not_ss;
+unsigned long not_ds;
+unsigned long not_es;
+
+#define SC_SS(r) (not_ss)
+#define SC_DS(r) (not_ds)
+#define SC_ES(r) (not_es)
+
+/* determines which flags the user has access to. */
+/* 1 = access 0 = no access */
+#define FLAG_MASK 0x44dd5UL
+
+int putreg(struct task_struct *child, int regno, unsigned long value)
+{
+ unsigned long tmp;
+
+#ifdef TIF_IA32
+ /* Some code in the 64bit emulation may not be 64bit clean.
+ Don't take any chances. */
+ if (test_tsk_thread_flag(child, TIF_IA32))
+ value &= 0xffffffff;
+#endif
+ switch (regno){
+ case FS:
+ case GS:
+ case DS:
+ case ES:
+ case SS:
+ case CS:
+ if (value && (value & 3) != 3)
+ return -EIO;
+ value &= 0xffff;
+ break;
+
+ case FS_BASE:
+ case GS_BASE:
+ if (!((value >> 48) == 0 || (value >> 48) == 0xffff))
+ return -EIO;
+ break;
+
+ case EFLAGS:
+ value &= FLAG_MASK;
+ tmp = PT_REGS_EFLAGS(&child->thread.regs) & ~FLAG_MASK;
+ value |= tmp;
+ break;
+ }
+
+ PT_REGS_SET(&child->thread.regs, regno, value);
+ return 0;
+}
+
+unsigned long getreg(struct task_struct *child, int regno)
+{
+ unsigned long retval = ~0UL;
+ switch (regno) {
+ case FS:
+ case GS:
+ case DS:
+ case ES:
+ case SS:
+ case CS:
+ retval = 0xffff;
+ /* fall through */
+ default:
+ retval &= PT_REG(&child->thread.regs, regno);
+#ifdef TIF_IA32
+ if (test_tsk_thread_flag(child, TIF_IA32))
+ retval &= 0xffffffff;
+#endif
+ }
+ return retval;
+}
+
+void arch_switch(void)
+{
+/* XXX
+ printk("arch_switch\n");
+*/
+}
+
+int is_syscall(unsigned long addr)
+{
+ panic("is_syscall");
+}
+
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
+{
+ panic("dump_fpu");
+ return(1);
+}
+
+int get_fpregs(unsigned long buf, struct task_struct *child)
+{
+ panic("get_fpregs");
+ return(0);
+}
+
+int set_fpregs(unsigned long buf, struct task_struct *child)
+{
+ panic("set_fpregs");
+ return(0);
+}
+
+int get_fpxregs(unsigned long buf, struct task_struct *tsk)
+{
+ panic("get_fpxregs");
+ return(0);
+}
+
+int set_fpxregs(unsigned long buf, struct task_struct *tsk)
+{
+ panic("set_fxpregs");
+ return(0);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/sys-x86_64/ptrace_user.c b/arch/um/sys-x86_64/ptrace_user.c
new file mode 100644
index 00000000000000..e1f8bacc5f1ae6
--- /dev/null
+++ b/arch/um/sys-x86_64/ptrace_user.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include <stddef.h>
+#include <errno.h>
+#define __FRAME_OFFSETS
+#include <sys/ptrace.h>
+#include <asm/ptrace.h>
+#include "user.h"
+#include "kern_constants.h"
+
+int ptrace_getregs(long pid, unsigned long *regs_out)
+{
+ if(ptrace(PTRACE_GETREGS, pid, 0, regs_out) < 0)
+ return(-errno);
+ return(0);
+}
+
+int ptrace_setregs(long pid, unsigned long *regs)
+{
+ if(ptrace(PTRACE_SETREGS, pid, 0, regs) < 0)
+ return(-errno);
+ return(0);
+}
+
+void ptrace_pokeuser(unsigned long addr, unsigned long data)
+{
+ panic("ptrace_pokeuser");
+}
+
+#define DS 184
+#define ES 192
+#define __USER_DS 0x2b
+
+void arch_enter_kernel(void *task, int pid)
+{
+}
+
+void arch_leave_kernel(void *task, int pid)
+{
+#ifdef UM_USER_CS
+ if(ptrace(PTRACE_POKEUSER, pid, CS, UM_USER_CS) < 0)
+ tracer_panic("POKEUSER CS failed");
+#endif
+
+ if(ptrace(PTRACE_POKEUSER, pid, DS, __USER_DS) < 0)
+ tracer_panic("POKEUSER DS failed");
+ if(ptrace(PTRACE_POKEUSER, pid, ES, __USER_DS) < 0)
+ tracer_panic("POKEUSER ES failed");
+}
+
+/*
+ * 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/sys-x86_64/sigcontext.c b/arch/um/sys-x86_64/sigcontext.c
new file mode 100644
index 00000000000000..c88e64def6f242
--- /dev/null
+++ b/arch/um/sys-x86_64/sigcontext.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <signal.h>
+#include "user.h"
+
+void sc_to_sc(void *to_ptr, void *from_ptr)
+{
+ struct sigcontext *to = to_ptr, *from = from_ptr;
+ int size = sizeof(*to); /* + sizeof(struct _fpstate); */
+
+ memcpy(to, from, size);
+ if(from->fpstate != NULL)
+ to->fpstate = (struct _fpstate *) (to + 1);
+
+ to->fpstate = NULL;
+}
+
+unsigned long *sc_sigmask(void *sc_ptr)
+{
+ struct sigcontext *sc = sc_ptr;
+
+ return(&sc->oldmask);
+}
+
+/* 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/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
new file mode 100644
index 00000000000000..a5682f1d020ddc
--- /dev/null
+++ b/arch/um/sys-x86_64/signal.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2003 PathScale, Inc.
+ * Licensed under the GPL
+ */
+
+#include "linux/stddef.h"
+#include "linux/errno.h"
+#include "linux/personality.h"
+#include "linux/ptrace.h"
+#include "asm/current.h"
+#include "asm/uaccess.h"
+#include "asm/sigcontext.h"
+#include "asm/ptrace.h"
+#include "asm/arch/ucontext.h"
+#include "choose-mode.h"
+#include "sysdep/ptrace.h"
+#include "frame_kern.h"
+
+#ifdef CONFIG_MODE_SKAS
+
+#include "skas.h"
+
+static int copy_sc_from_user_skas(struct pt_regs *regs,
+ struct sigcontext *from)
+{
+ int err = 0;
+
+#define GETREG(regs, regno, sc, regname) \
+ __get_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
+ &(sc)->regname)
+
+ err |= GETREG(regs, R8, from, r8);
+ err |= GETREG(regs, R9, from, r9);
+ err |= GETREG(regs, R10, from, r10);
+ err |= GETREG(regs, R11, from, r11);
+ err |= GETREG(regs, R12, from, r12);
+ err |= GETREG(regs, R13, from, r13);
+ err |= GETREG(regs, R14, from, r14);
+ err |= GETREG(regs, R15, from, r15);
+ err |= GETREG(regs, RDI, from, rdi);
+ err |= GETREG(regs, RSI, from, rsi);
+ err |= GETREG(regs, RBP, from, rbp);
+ err |= GETREG(regs, RBX, from, rbx);
+ err |= GETREG(regs, RDX, from, rdx);
+ err |= GETREG(regs, RAX, from, rax);
+ err |= GETREG(regs, RCX, from, rcx);
+ err |= GETREG(regs, RSP, from, rsp);
+ err |= GETREG(regs, RIP, from, rip);
+ err |= GETREG(regs, EFLAGS, from, eflags);
+ err |= GETREG(regs, CS, from, cs);
+
+#undef GETREG
+
+ return(err);
+}
+
+int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp,
+ struct pt_regs *regs, unsigned long mask)
+{
+ unsigned long eflags;
+ int err = 0;
+
+ err |= __put_user(0, &to->gs);
+ err |= __put_user(0, &to->fs);
+
+#define PUTREG(regs, regno, sc, regname) \
+ __put_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \
+ &(sc)->regname)
+
+ err |= PUTREG(regs, RDI, to, rdi);
+ err |= PUTREG(regs, RSI, to, rsi);
+ err |= PUTREG(regs, RBP, to, rbp);
+ err |= PUTREG(regs, RSP, to, rsp);
+ err |= PUTREG(regs, RBX, to, rbx);
+ err |= PUTREG(regs, RDX, to, rdx);
+ err |= PUTREG(regs, RCX, to, rcx);
+ err |= PUTREG(regs, RAX, to, rax);
+ err |= PUTREG(regs, R8, to, r8);
+ err |= PUTREG(regs, R9, to, r9);
+ err |= PUTREG(regs, R10, to, r10);
+ err |= PUTREG(regs, R11, to, r11);
+ err |= PUTREG(regs, R12, to, r12);
+ err |= PUTREG(regs, R13, to, r13);
+ err |= PUTREG(regs, R14, to, r14);
+ err |= PUTREG(regs, R15, to, r15);
+ err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
+ err |= __put_user(current->thread.err, &to->err);
+ err |= __put_user(current->thread.trap_no, &to->trapno);
+ err |= PUTREG(regs, RIP, to, rip);
+ err |= PUTREG(regs, EFLAGS, to, eflags);
+#undef PUTREG
+
+ err |= __put_user(mask, &to->oldmask);
+ err |= __put_user(current->thread.cr2, &to->cr2);
+
+ return(err);
+}
+
+#endif
+
+#ifdef CONFIG_MODE_TT
+int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext *from,
+ int fpsize)
+{
+ struct _fpstate *to_fp, *from_fp;
+ unsigned long sigs;
+ int err;
+
+ to_fp = to->fpstate;
+ from_fp = from->fpstate;
+ sigs = to->oldmask;
+ err = copy_from_user(to, from, sizeof(*to));
+ to->oldmask = sigs;
+ return(err);
+}
+
+int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate *fp,
+ struct sigcontext *from, int fpsize)
+{
+ struct _fpstate *to_fp, *from_fp;
+ int err;
+
+ to_fp = (fp ? fp : (struct _fpstate *) (to + 1));
+ from_fp = from->fpstate;
+ err = copy_to_user(to, from, sizeof(*to));
+ return(err);
+}
+
+#endif
+
+static int copy_sc_from_user(struct pt_regs *to, void __user *from)
+{
+ int ret;
+
+ ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
+ sizeof(struct _fpstate)),
+ copy_sc_from_user_skas(to, from));
+ return(ret);
+}
+
+static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp,
+ struct pt_regs *from, unsigned long mask)
+{
+ return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
+ sizeof(*fp)),
+ copy_sc_to_user_skas(to, fp, from, mask)));
+}
+
+struct rt_sigframe
+{
+ char *pretcode;
+ struct ucontext uc;
+ struct siginfo info;
+};
+
+#define round_down(m, n) (((m) / (n)) * (n))
+
+int setup_signal_stack_si(unsigned long stack_top, int sig,
+ struct k_sigaction *ka, struct pt_regs * regs,
+ siginfo_t *info, sigset_t *set)
+{
+ struct rt_sigframe __user *frame;
+ struct _fpstate __user *fp = NULL;
+ int err = 0;
+ struct task_struct *me = current;
+
+ frame = (struct rt_sigframe __user *)
+ round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8;
+ frame -= 128;
+
+ if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
+ goto out;
+
+#if 0 /* XXX */
+ if (save_i387(fp) < 0)
+ err |= -1;
+#endif
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto out;
+
+ if (ka->sa.sa_flags & SA_SIGINFO) {
+ err |= copy_siginfo_to_user(&frame->info, info);
+ if (err)
+ goto out;
+ }
+
+ /* Create the ucontext. */
+ err |= __put_user(0, &frame->uc.uc_flags);
+ err |= __put_user(0, &frame->uc.uc_link);
+ err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
+ err |= __put_user(sas_ss_flags(PT_REGS_SP(regs)),
+ &frame->uc.uc_stack.ss_flags);
+ err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
+ err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0]);
+ err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate);
+ if (sizeof(*set) == 16) {
+ __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
+ __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
+ }
+ else
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set,
+ sizeof(*set));
+
+ /* Set up to return from userspace. If provided, use a stub
+ already in userspace. */
+ /* x86-64 should always use SA_RESTORER. */
+ if (ka->sa.sa_flags & SA_RESTORER)
+ err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
+ else
+ /* could use a vstub here */
+ goto out;
+
+ if (err)
+ goto out;
+
+ /* Set up registers for signal handler */
+ {
+ struct exec_domain *ed = current_thread_info()->exec_domain;
+ if (unlikely(ed && ed->signal_invmap && sig < 32))
+ sig = ed->signal_invmap[sig];
+ }
+
+ PT_REGS_RDI(regs) = sig;
+ /* In case the signal handler was declared without prototypes */
+ PT_REGS_RAX(regs) = 0;
+
+ /* This also works for non SA_SIGINFO handlers because they expect the
+ next argument after the signal number on the stack. */
+ PT_REGS_RSI(regs) = (unsigned long) &frame->info;
+ PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
+ PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
+
+ PT_REGS_RSP(regs) = (unsigned long) frame;
+ out:
+ return(err);
+}
+
+long sys_rt_sigreturn(struct pt_regs *regs)
+{
+ unsigned long __user sp = PT_REGS_SP(&current->thread.regs);
+ struct rt_sigframe __user *frame =
+ (struct rt_sigframe __user *)(sp - 8);
+ struct ucontext __user *uc = &frame->uc;
+ sigset_t set;
+
+ if(copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
+ goto segfault;
+
+ sigdelsetmask(&set, ~_BLOCKABLE);
+
+ spin_lock_irq(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
+ goto segfault;
+
+ /* Avoid ERESTART handling */
+ PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
+ return(PT_REGS_SYSCALL_RET(&current->thread.regs));
+
+ segfault:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only. This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-file-style: "linux"
+ * End:
+ */
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
new file mode 100644
index 00000000000000..4c61dcc0901ff9
--- /dev/null
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/linkage.h"
+#include "linux/slab.h"
+#include "linux/shm.h"
+#include "asm/uaccess.h"
+#define __FRAME_OFFSETS
+#include "asm/ptrace.h"
+#include "asm/unistd.h"
+#include "asm/prctl.h" /* XXX This should get the constants from libc */
+#include "choose-mode.h"
+
+asmlinkage long wrap_sys_shmat(int shmid, char __user *shmaddr, int shmflg)
+{
+ unsigned long raddr;
+
+ return do_shmat(shmid, shmaddr, shmflg, &raddr) ?: (long) raddr;
+}
+
+#ifdef CONFIG_MODE_TT
+extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
+
+long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)
+{
+ /* XXX This should check VERIFY_WRITE depending on func, check this
+ * in i386 as well.
+ */
+ if(verify_area(VERIFY_READ, ptr, bytecount))
+ return(-EFAULT);
+ return(modify_ldt(func, ptr, bytecount));
+}
+#endif
+
+#ifdef CONFIG_MODE_SKAS
+extern int userspace_pid;
+
+#ifndef __NR_mm_indirect
+#define __NR_mm_indirect 241
+#endif
+
+long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)
+{
+ unsigned long args[6];
+ void *buf;
+ int res, n;
+
+ buf = kmalloc(bytecount, GFP_KERNEL);
+ if(buf == NULL)
+ return(-ENOMEM);
+
+ res = 0;
+
+ switch(func){
+ case 1:
+ case 0x11:
+ res = copy_from_user(buf, ptr, bytecount);
+ break;
+ }
+
+ if(res != 0){
+ res = -EFAULT;
+ goto out;
+ }
+
+ args[0] = func;
+ args[1] = (unsigned long) buf;
+ args[2] = bytecount;
+ res = syscall(__NR_mm_indirect, &current->mm->context.u,
+ __NR_modify_ldt, args);
+
+ if(res < 0)
+ goto out;
+
+ switch(func){
+ case 0:
+ case 2:
+ n = res;
+ res = copy_to_user(ptr, buf, n);
+ if(res != 0)
+ res = -EFAULT;
+ else
+ res = n;
+ break;
+ }
+
+ out:
+ kfree(buf);
+ return(res);
+}
+#endif
+
+long sys_modify_ldt(int func, void *ptr, unsigned long bytecount)
+{
+ return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func,
+ ptr, bytecount));
+}
+
+#ifdef CONFIG_MODE_TT
+extern long arch_prctl(int code, unsigned long addr);
+
+static long arch_prctl_tt(int code, unsigned long addr)
+{
+ unsigned long tmp;
+ long ret;
+
+ switch(code){
+ case ARCH_SET_GS:
+ case ARCH_SET_FS:
+ ret = arch_prctl(code, addr);
+ break;
+ case ARCH_GET_FS:
+ case ARCH_GET_GS:
+ ret = arch_prctl(code, (unsigned long) &tmp);
+ if(!ret)
+ ret = put_user(tmp, &addr);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return(ret);
+}
+#endif
+
+#ifdef CONFIG_MODE_SKAS
+
+static long arch_prctl_skas(int code, unsigned long addr)
+{
+ long ret = 0;
+
+ switch(code){
+ case ARCH_SET_GS:
+ current->thread.regs.regs.skas.regs[GS_BASE / sizeof(unsigned long)] = addr;
+ break;
+ case ARCH_SET_FS:
+ current->thread.regs.regs.skas.regs[FS_BASE / sizeof(unsigned long)] = addr;
+ break;
+ case ARCH_GET_FS:
+ ret = put_user(current->thread.regs.regs.skas.regs[GS / sizeof(unsigned long)], &addr);
+ break;
+ case ARCH_GET_GS:
+ ret = put_user(current->thread.regs.regs.skas.regs[FS / sizeof(unsigned \
+long)], &addr);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return(ret);
+}
+#endif
+
+long sys_arch_prctl(int code, unsigned long addr)
+{
+ return(CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, code, addr));
+}
+
+long sys_clone(unsigned long clone_flags, unsigned long newsp,
+ void __user *parent_tid, void __user *child_tid)
+{
+ long ret;
+
+ /* XXX: normal arch do here this pass, and also pass the regs to
+ * do_fork, instead of NULL. Currently the arch-independent code
+ * ignores these values, while the UML code (actually it's
+ * copy_thread) does the right thing. But this should change,
+ probably. */
+ /*if (!newsp)
+ newsp = UPT_SP(current->thread.regs);*/
+ current->thread.forking = 1;
+ ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
+ current->thread.forking = 0;
+ return(ret);
+}
+
+/*
+ * 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/sys-x86_64/sysrq.c b/arch/um/sys-x86_64/sysrq.c
new file mode 100644
index 00000000000000..c33f85f9e8bb2c
--- /dev/null
+++ b/arch/um/sys-x86_64/sysrq.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2003 PathScale, Inc.
+ *
+ * Licensed under the GPL
+ */
+
+#include "linux/kernel.h"
+#include "linux/version.h"
+#include "linux/module.h"
+#include "asm/current.h"
+#include "asm/ptrace.h"
+#include "sysrq.h"
+
+void __show_regs(struct pt_regs * regs)
+{
+ printk("\n");
+ print_modules();
+ printk("Pid: %d, comm: %.20s %s %s\n",
+ current->pid, current->comm, print_tainted(), UTS_RELEASE);
+ printk("RIP: %04lx:[<%016lx>] ", PT_REGS_CS(regs) & 0xffff,
+ PT_REGS_RIP(regs));
+ printk("\nRSP: %016lx EFLAGS: %08lx\n", PT_REGS_RSP(regs),
+ PT_REGS_EFLAGS(regs));
+ printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
+ PT_REGS_RAX(regs), PT_REGS_RBX(regs), PT_REGS_RCX(regs));
+ printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
+ PT_REGS_RDX(regs), PT_REGS_RSI(regs), PT_REGS_RDI(regs));
+ printk("RBP: %016lx R08: %016lx R09: %016lx\n",
+ PT_REGS_RBP(regs), PT_REGS_R8(regs), PT_REGS_R9(regs));
+ printk("R10: %016lx R11: %016lx R12: %016lx\n",
+ PT_REGS_R10(regs), PT_REGS_R11(regs), PT_REGS_R12(regs));
+ printk("R13: %016lx R14: %016lx R15: %016lx\n",
+ PT_REGS_R13(regs), PT_REGS_R14(regs), PT_REGS_R15(regs));
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ __show_regs(regs);
+ show_trace((unsigned long *) &regs);
+}
+
+/* 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/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile
new file mode 100644
index 00000000000000..002607980864c4
--- /dev/null
+++ b/arch/um/sys-x86_64/util/Makefile
@@ -0,0 +1,10 @@
+# Copyright 2003 - 2004 Pathscale, Inc
+# Released under the GPL
+
+hostprogs-y := mk_sc mk_thread
+always := $(hostprogs-y)
+
+mk_thread-objs := mk_thread_kern.o mk_thread_user.o
+
+HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS)
+HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS)
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c
new file mode 100644
index 00000000000000..c236e213918db4
--- /dev/null
+++ b/arch/um/sys-x86_64/util/mk_sc.c
@@ -0,0 +1,58 @@
+/* Copyright (C) 2003 - 2004 PathScale, Inc
+ * Released under the GPL
+ */
+
+#include <stdio.h>
+#include <signal.h>
+#include <linux/stddef.h>
+
+#define SC_OFFSET(name, field) \
+ printf("#define " name \
+ "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\
+ offsetof(struct sigcontext, field))
+
+#define SC_FP_OFFSET(name, field) \
+ printf("#define " name \
+ "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\
+ offsetof(struct _fpstate, field))
+
+#define SC_FP_OFFSET_PTR(name, field, type) \
+ printf("#define " name \
+ "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\
+ offsetof(struct _fpstate, field))
+
+int main(int argc, char **argv)
+{
+ SC_OFFSET("SC_RBX", rbx);
+ SC_OFFSET("SC_RCX", rcx);
+ SC_OFFSET("SC_RDX", rdx);
+ SC_OFFSET("SC_RSI", rsi);
+ SC_OFFSET("SC_RDI", rdi);
+ SC_OFFSET("SC_RBP", rbp);
+ SC_OFFSET("SC_RAX", rax);
+ SC_OFFSET("SC_R8", r8);
+ SC_OFFSET("SC_R9", r9);
+ SC_OFFSET("SC_R10", r10);
+ SC_OFFSET("SC_R11", r11);
+ SC_OFFSET("SC_R12", r12);
+ SC_OFFSET("SC_R13", r13);
+ SC_OFFSET("SC_R14", r14);
+ SC_OFFSET("SC_R15", r15);
+ SC_OFFSET("SC_IP", rip);
+ SC_OFFSET("SC_SP", rsp);
+ SC_OFFSET("SC_CR2", cr2);
+ SC_OFFSET("SC_ERR", err);
+ SC_OFFSET("SC_TRAPNO", trapno);
+ SC_OFFSET("SC_CS", cs);
+ SC_OFFSET("SC_FS", fs);
+ SC_OFFSET("SC_GS", gs);
+ SC_OFFSET("SC_EFLAGS", eflags);
+ SC_OFFSET("SC_SIGMASK", oldmask);
+#if 0
+ SC_OFFSET("SC_ORIG_RAX", orig_rax);
+ SC_OFFSET("SC_DS", ds);
+ SC_OFFSET("SC_ES", es);
+ SC_OFFSET("SC_SS", ss);
+#endif
+ return(0);
+}
diff --git a/arch/um/sys-x86_64/util/mk_thread_kern.c b/arch/um/sys-x86_64/util/mk_thread_kern.c
new file mode 100644
index 00000000000000..a281673f02b240
--- /dev/null
+++ b/arch/um/sys-x86_64/util/mk_thread_kern.c
@@ -0,0 +1,21 @@
+#include "linux/config.h"
+#include "linux/stddef.h"
+#include "linux/sched.h"
+
+extern void print_head(void);
+extern void print_constant_ptr(char *name, int value);
+extern void print_constant(char *name, char *type, int value);
+extern void print_tail(void);
+
+#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field)
+
+int main(int argc, char **argv)
+{
+ print_head();
+#ifdef CONFIG_MODE_TT
+ print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid));
+#endif
+ print_tail();
+ return(0);
+}
+
diff --git a/arch/um/sys-x86_64/util/mk_thread_user.c b/arch/um/sys-x86_64/util/mk_thread_user.c
new file mode 100644
index 00000000000000..7989725568b8df
--- /dev/null
+++ b/arch/um/sys-x86_64/util/mk_thread_user.c
@@ -0,0 +1,30 @@
+#include <stdio.h>
+
+void print_head(void)
+{
+ printf("/*\n");
+ printf(" * Generated by mk_thread\n");
+ printf(" */\n");
+ printf("\n");
+ printf("#ifndef __UM_THREAD_H\n");
+ printf("#define __UM_THREAD_H\n");
+ printf("\n");
+}
+
+void print_constant_ptr(char *name, int value)
+{
+ printf("#define %s(task) ((unsigned long *) "
+ "&(((char *) (task))[%d]))\n", name, value);
+}
+
+void print_constant(char *name, char *type, int value)
+{
+ printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type,
+ value);
+}
+
+void print_tail(void)
+{
+ printf("\n");
+ printf("#endif\n");
+}
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 47339a83c9957f..5186d2a4c4e950 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -251,7 +251,7 @@ config PREEMPT
config PREEMPT_BKL
bool "Preempt The Big Kernel Lock"
- depends on PREEMPT || SMP
+ depends on PREEMPT
default y
help
This option reduces the latency of the kernel by making the
diff --git a/arch/x86_64/Makefile b/arch/x86_64/Makefile
index a69f7bcdfc2cdf..6f90c246c41899 100644
--- a/arch/x86_64/Makefile
+++ b/arch/x86_64/Makefile
@@ -59,6 +59,8 @@ endif
# -funit-at-a-time shrinks the kernel .text considerably
# unfortunately it makes reading oopses harder.
CFLAGS += $(call cc-option,-funit-at-a-time)
+# prevent gcc from generating any FP code by mistake
+CFLAGS += $(call cc-option,-mno-sse -mno-mmx -mno-sse2 -mno-3dnow,)
head-y := arch/x86_64/kernel/head.o arch/x86_64/kernel/head64.o arch/x86_64/kernel/init_task.o
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig
index 06d778083feeaa..941e9b93008117 100644
--- a/arch/x86_64/defconfig
+++ b/arch/x86_64/defconfig
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.10-rc1-bk6
-# Thu Oct 28 00:07:32 2004
+# Linux kernel version: 2.6.10-bk7
+# Fri Jan 7 06:27:52 2005
#
CONFIG_X86_64=y
CONFIG_64BIT=y
@@ -45,6 +45,10 @@ CONFIG_FUTEX=y
CONFIG_EPOLL=y
# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_SHMEM=y
+CONFIG_CC_ALIGN_FUNCTIONS=0
+CONFIG_CC_ALIGN_LABELS=0
+CONFIG_CC_ALIGN_LOOPS=0
+CONFIG_CC_ALIGN_JUMPS=0
# CONFIG_TINY_SHMEM is not set
#
@@ -88,6 +92,7 @@ CONFIG_NR_CPUS=8
CONFIG_GART_IOMMU=y
CONFIG_SWIOTLB=y
CONFIG_X86_MCE=y
+CONFIG_X86_MCE_INTEL=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
@@ -110,10 +115,13 @@ CONFIG_ACPI_SLEEP_PROC_FS=y
CONFIG_ACPI_AC=y
CONFIG_ACPI_BATTERY=y
CONFIG_ACPI_BUTTON=y
+# CONFIG_ACPI_VIDEO is not set
CONFIG_ACPI_FAN=y
CONFIG_ACPI_PROCESSOR=y
CONFIG_ACPI_THERMAL=y
+CONFIG_ACPI_NUMA=y
# CONFIG_ACPI_ASUS is not set
+# CONFIG_ACPI_IBM is not set
CONFIG_ACPI_TOSHIBA=y
CONFIG_ACPI_BLACKLIST_YEAR=2001
CONFIG_ACPI_DEBUG=y
@@ -122,11 +130,35 @@ CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_PCI=y
CONFIG_ACPI_SYSTEM=y
+# CONFIG_ACPI_CONTAINER is not set
#
# CPU Frequency scaling
#
-# CONFIG_CPU_FREQ is not set
+CONFIG_CPU_FREQ=y
+# CONFIG_CPU_FREQ_DEBUG is not set
+CONFIG_CPU_FREQ_PROC_INTF=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_24_API=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_TABLE=y
+
+#
+# CPUFreq processor drivers
+#
+CONFIG_X86_POWERNOW_K8=y
+CONFIG_X86_POWERNOW_K8_ACPI=y
+# CONFIG_X86_SPEEDSTEP_CENTRINO is not set
+CONFIG_X86_ACPI_CPUFREQ=y
+
+#
+# shared options
+#
+CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y
#
# Bus options (PCI etc.)
@@ -174,6 +206,7 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
+# CONFIG_PNP is not set
#
# Block devices
@@ -189,6 +222,7 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_SX8 is not set
# CONFIG_BLK_DEV_UB is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
CONFIG_INITRAMFS_SOURCE=""
@@ -292,6 +326,7 @@ CONFIG_BLK_DEV_SD=y
#
# CONFIG_SCSI_SPI_ATTRS is not set
# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
#
# SCSI low-level drivers
@@ -337,14 +372,12 @@ CONFIG_SCSI_SATA_VIA=y
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_QLOGIC_1280_1040 is not set
CONFIG_SCSI_QLA2XXX=y
# CONFIG_SCSI_QLA21XX is not set
# CONFIG_SCSI_QLA22XX is not set
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
-# CONFIG_SCSI_QLA6322 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_DEBUG is not set
@@ -397,6 +430,8 @@ CONFIG_IP_MULTICAST=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
+CONFIG_IP_TCPDIAG=y
+CONFIG_IP_TCPDIAG_IPV6=y
CONFIG_IPV6=y
# CONFIG_IPV6_PRIVACY is not set
# CONFIG_INET6_AH is not set
@@ -508,7 +543,9 @@ CONFIG_TIGON3=y
# Ethernet (10000 Mbit)
#
# CONFIG_IXGB is not set
-# CONFIG_S2IO is not set
+CONFIG_S2IO=m
+# CONFIG_S2IO_NAPI is not set
+# CONFIG_2BUFF_MODE is not set
#
# Token Ring devices
@@ -743,6 +780,7 @@ CONFIG_USB_EHCI_HCD=y
# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
CONFIG_USB_OHCI_HCD=y
CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_SL811_HCD is not set
#
# USB Device Class drivers
@@ -752,6 +790,10 @@ CONFIG_USB_UHCI_HCD=y
# CONFIG_USB_MIDI is not set
# CONFIG_USB_ACM is not set
CONFIG_USB_PRINTER=y
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information
+#
CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_DEBUG is not set
# CONFIG_USB_STORAGE_RW_DETECT is not set
@@ -797,7 +839,7 @@ CONFIG_USB_HIDINPUT=y
#
#
-# USB Network adaptors
+# USB Network Adapters
#
# CONFIG_USB_CATC is not set
# CONFIG_USB_KAWETH is not set
@@ -840,6 +882,16 @@ CONFIG_USB_HIDINPUT=y
# CONFIG_USB_GADGET is not set
#
+# MMC/SD Card support
+#
+# CONFIG_MMC is not set
+
+#
+# InfiniBand support
+#
+# CONFIG_INFINIBAND is not set
+
+#
# Firmware Drivers
#
# CONFIG_EDD is not set
@@ -870,6 +922,7 @@ CONFIG_FS_POSIX_ACL=y
# CONFIG_MINIX_FS is not set
# CONFIG_ROMFS_FS is not set
# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
CONFIG_AUTOFS_FS=y
# CONFIG_AUTOFS4_FS is not set
@@ -884,8 +937,11 @@ CONFIG_ISO9660_FS=y
#
# DOS/FAT/NT Filesystems
#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
@@ -951,7 +1007,46 @@ CONFIG_MSDOS_PARTITION=y
#
# Native Language Support
#
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=y
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
#
# Profiling support
@@ -972,6 +1067,7 @@ CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_INFO is not set
CONFIG_INIT_DEBUG=y
# CONFIG_IOMMU_DEBUG is not set
+CONFIG_KPROBES=y
#
# Security options
@@ -985,6 +1081,10 @@ CONFIG_INIT_DEBUG=y
# CONFIG_CRYPTO is not set
#
+# Hardware crypto devices
+#
+
+#
# Library routines
#
# CONFIG_CRC_CCITT is not set
diff --git a/arch/x86_64/ia32/ia32_aout.c b/arch/x86_64/ia32/ia32_aout.c
index 6ac57fcf1340b4..2014f2113cd8ac 100644
--- a/arch/x86_64/ia32/ia32_aout.c
+++ b/arch/x86_64/ia32/ia32_aout.c
@@ -115,7 +115,9 @@ static void set_brk(unsigned long start, unsigned long end)
end = PAGE_ALIGN(end);
if (end <= start)
return;
+ down_write(&current->mm->mmap_sem);
do_brk(start, end - start);
+ up_write(&current->mm->mmap_sem);
}
#if CORE_DUMP
@@ -325,7 +327,10 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
pos = 32;
map_size = ex.a_text+ex.a_data;
+ down_write(&current->mm->mmap_sem);
error = do_brk(text_addr & PAGE_MASK, map_size);
+ up_write(&current->mm->mmap_sem);
+
if (error != (text_addr & PAGE_MASK)) {
send_sig(SIGKILL, current, 0);
return error;
@@ -361,7 +366,9 @@ static int load_aout_binary(struct linux_binprm * bprm, struct pt_regs * regs)
if (!bprm->file->f_op->mmap||((fd_offset & ~PAGE_MASK) != 0)) {
loff_t pos = fd_offset;
+ down_write(&current->mm->mmap_sem);
do_brk(N_TXTADDR(ex), ex.a_text+ex.a_data);
+ up_write(&current->mm->mmap_sem);
bprm->file->f_op->read(bprm->file,(char *)N_TXTADDR(ex),
ex.a_text+ex.a_data, &pos);
flush_icache_range((unsigned long) N_TXTADDR(ex),
@@ -469,8 +476,9 @@ static int load_aout_library(struct file *file)
error_time = jiffies;
}
#endif
-
+ down_write(&current->mm->mmap_sem);
do_brk(start_addr, ex.a_text + ex.a_data + ex.a_bss);
+ up_write(&current->mm->mmap_sem);
file->f_op->read(file, (char *)start_addr,
ex.a_text + ex.a_data, &pos);
@@ -494,7 +502,9 @@ static int load_aout_library(struct file *file)
len = PAGE_ALIGN(ex.a_text + ex.a_data);
bss = ex.a_text + ex.a_data + ex.a_bss;
if (bss > len) {
+ down_write(&current->mm->mmap_sem);
error = do_brk(start_addr + len, bss - len);
+ up_write(&current->mm->mmap_sem);
retval = error;
if (error != start_addr + len)
goto out;
diff --git a/arch/x86_64/ia32/ia32_signal.c b/arch/x86_64/ia32/ia32_signal.c
index 16854c4faa64c7..7b78206dd90bc8 100644
--- a/arch/x86_64/ia32/ia32_signal.c
+++ b/arch/x86_64/ia32/ia32_signal.c
@@ -261,6 +261,12 @@ ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc,
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387_ia32(current, buf, 0);
+ } else {
+ struct task_struct *me = current;
+ if (me->used_math) {
+ clear_fpu(me);
+ me->used_math = 0;
+ }
}
}
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S
index 4210fa0e6918d7..270f8ca873ae06 100644
--- a/arch/x86_64/ia32/ia32entry.S
+++ b/arch/x86_64/ia32/ia32entry.S
@@ -587,6 +587,10 @@ ia32_sys_call_table:
.quad compat_sys_mq_getsetattr
.quad quiet_ni_syscall /* reserved for kexec */
.quad sys32_waitid
+ .quad quiet_ni_syscall /* sys_altroot */
+ .quad sys_add_key
+ .quad sys_request_key
+ .quad sys_keyctl
/* don't forget to change IA32_NR_syscalls */
ia32_syscall_end:
.rept IA32_NR_syscalls-(ia32_syscall_end-ia32_sys_call_table)/8
diff --git a/arch/x86_64/kernel/aperture.c b/arch/x86_64/kernel/aperture.c
index 1d8b3912c1d908..4baa99fe1e5c95 100644
--- a/arch/x86_64/kernel/aperture.c
+++ b/arch/x86_64/kernel/aperture.c
@@ -200,8 +200,8 @@ static __u32 __init search_agp_bridge(u32 *order, int *valid_agp)
void __init iommu_hole_init(void)
{
int fix, num;
- u32 aper_size, aper_alloc = 0, aper_order;
- u64 aper_base;
+ u32 aper_size, aper_alloc = 0, aper_order, last_aper_order = 0;
+ u64 aper_base, last_aper_base = 0;
int valid_agp = 0;
if (iommu_aperture_disabled || !fix_aperture)
@@ -230,7 +230,15 @@ void __init iommu_hole_init(void)
if (!aperture_valid(name, aper_base, aper_size)) {
fix = 1;
break;
- }
+ }
+
+ if ((last_aper_order && aper_order != last_aper_order) ||
+ (last_aper_base && aper_base != last_aper_base)) {
+ fix = 1;
+ break;
+ }
+ last_aper_order = aper_order;
+ last_aper_base = aper_base;
}
if (!fix && !fallback_aper_force)
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
index cd37a0aa66f3e5..dbccec4894c0b1 100644
--- a/arch/x86_64/kernel/apic.c
+++ b/arch/x86_64/kernel/apic.c
@@ -225,6 +225,11 @@ int __init verify_local_APIC(void)
void __init sync_Arb_IDs(void)
{
+ /* Unsupported on P4 - see Intel Dev. Manual Vol. 3, Ch. 8.6.1 */
+ unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
+ if (ver >= 0x14) /* P4 or higher */
+ return;
+
/*
* Wait for idle.
*/
diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c
index 9aa5cb6af6602a..d2c42fb99cb345 100644
--- a/arch/x86_64/kernel/genapic.c
+++ b/arch/x86_64/kernel/genapic.c
@@ -41,6 +41,12 @@ void __init clustered_apic_check(void)
u8 id;
u8 cluster_cnt[NUM_APIC_CLUSTERS];
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) {
+ /* AMD always uses flat mode right now */
+ genapic = &apic_flat;
+ goto print;
+ }
+
memset(cluster_cnt, 0, sizeof(cluster_cnt));
for (i = 0; i < NR_CPUS; i++) {
@@ -71,6 +77,7 @@ void __init clustered_apic_check(void)
else
genapic = &apic_cluster;
+print:
printk(KERN_INFO "Setting APIC routing to %s\n", genapic->name);
}
diff --git a/arch/x86_64/kernel/head.S b/arch/x86_64/kernel/head.S
index 766a7d6ef9b0bf..30e92ff8b3c073 100644
--- a/arch/x86_64/kernel/head.S
+++ b/arch/x86_64/kernel/head.S
@@ -355,7 +355,7 @@ ENTRY(cpu_gdt_table)
.quad 0x008f9a000000ffff /* __KERNEL_COMPAT32_CS */
.quad 0x00af9a000000ffff /* __KERNEL_CS */
.quad 0x00cf92000000ffff /* __KERNEL_DS */
- .quad 0x00cffe000000ffff /* __USER32_CS */
+ .quad 0x00cffa000000ffff /* __USER32_CS */
.quad 0x00cff2000000ffff /* __USER_DS, __USER32_DS */
.quad 0x00affa000000ffff /* __USER_CS */
.quad 0x00cf9a000000ffff /* __KERNEL32_CS */
diff --git a/arch/x86_64/kernel/head64.c b/arch/x86_64/kernel/head64.c
index 5254e90a8113cd..6cad46c98a2340 100644
--- a/arch/x86_64/kernel/head64.c
+++ b/arch/x86_64/kernel/head64.c
@@ -61,16 +61,17 @@ static void __init copy_bootdata(char *real_mode_data)
static void __init setup_boot_cpu_data(void)
{
- int dummy, eax;
+ unsigned int dummy, eax;
/* get vendor info */
- cpuid(0, &boot_cpu_data.cpuid_level,
- (int *)&boot_cpu_data.x86_vendor_id[0],
- (int *)&boot_cpu_data.x86_vendor_id[8],
- (int *)&boot_cpu_data.x86_vendor_id[4]);
+ cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
+ (unsigned int *)&boot_cpu_data.x86_vendor_id[0],
+ (unsigned int *)&boot_cpu_data.x86_vendor_id[8],
+ (unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
/* get cpu type */
- cpuid(1, &eax, &dummy, &dummy, (int *) &boot_cpu_data.x86_capability);
+ cpuid(1, &eax, &dummy, &dummy,
+ (unsigned int *) &boot_cpu_data.x86_capability);
boot_cpu_data.x86 = (eax >> 8) & 0xf;
boot_cpu_data.x86_model = (eax >> 4) & 0xf;
boot_cpu_data.x86_mask = eax & 0xf;
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index c22a8f045ecf9e..7b568f14b5ecb9 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -1160,13 +1160,6 @@ static void __init setup_ioapic_ids_from_mpc (void)
old_id = mp_ioapics[apic].mpc_apicid;
- if (mp_ioapics[apic].mpc_apicid >= 0xf) {
- apic_printk(APIC_QUIET,KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
- apic, mp_ioapics[apic].mpc_apicid);
- apic_printk(APIC_QUIET,KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
- reg_00.bits.ID);
- mp_ioapics[apic].mpc_apicid = reg_00.bits.ID;
- }
printk(KERN_INFO "Using IO-APIC %d\n", mp_ioapics[apic].mpc_apicid);
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
index 6e717e4704602b..b05d3b19278d5e 100644
--- a/arch/x86_64/kernel/mce.c
+++ b/arch/x86_64/kernel/mce.c
@@ -31,6 +31,8 @@ static int mce_dont_init;
static int tolerant = 1;
static int banks;
static unsigned long bank[NR_BANKS] = { [0 ... NR_BANKS-1] = ~0UL };
+static unsigned long console_logged;
+static int notify_user;
/*
* Lockless MCE logging infrastructure.
@@ -68,6 +70,9 @@ void mce_log(struct mce *mce)
smp_wmb();
mcelog.entry[entry].finished = 1;
smp_wmb();
+
+ if (!test_and_set_bit(0, &console_logged))
+ notify_user = 1;
}
static void print_mce(struct mce *m)
@@ -252,6 +257,19 @@ static void mcheck_timer(void *data)
{
on_each_cpu(mcheck_check_cpu, NULL, 1, 1);
schedule_delayed_work(&mcheck_work, check_interval * HZ);
+
+ /*
+ * It's ok to read stale data here for notify_user and
+ * console_logged as we'll simply get the updated versions
+ * on the next mcheck_timer execution and atomic operations
+ * on console_logged act as synchronization for notify_user
+ * writes.
+ */
+ if (notify_user && console_logged) {
+ notify_user = 0;
+ clear_bit(0, &console_logged);
+ printk(KERN_INFO "Machine check events logged\n");
+ }
}
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 1f415db882d188..7f5f57e5474012 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -576,7 +576,6 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
extern void __bad_mpf_size(void);
unsigned int *bp = phys_to_virt(base);
struct intel_mp_floating *mpf;
- static int printed __initdata;
Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
if (sizeof(*mpf) != 16)
@@ -600,10 +599,6 @@ static int __init smp_scan_config (unsigned long base, unsigned long length)
bp += 4;
length -= 16;
}
- if (!printed) {
- printk(KERN_INFO "No mptable found.\n");
- printed = 1;
- }
return 0;
}
@@ -640,7 +635,11 @@ void __init find_intel_smp (void)
address = *(unsigned short *)phys_to_virt(0x40E);
address <<= 4;
- smp_scan_config(address, 0x1000);
+ if (smp_scan_config(address, 0x1000))
+ return;
+
+ /* If we have come this far, we did not find an MP table */
+ printk(KERN_INFO "No mptable found.\n");
}
/*
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c
index 1bf8d4e95e928d..407d42b2dc5582 100644
--- a/arch/x86_64/kernel/setup.c
+++ b/arch/x86_64/kernel/setup.c
@@ -493,7 +493,7 @@ void __init setup_arch(char **cmdline_p)
check_efer();
- init_memory_mapping();
+ init_memory_mapping(0, (end_pfn_map << PAGE_SHIFT));
#ifdef CONFIG_ACPI_BOOT
/*
@@ -657,18 +657,18 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
cpuid(0x80000005, &dummy, &ebx, &ecx, &edx);
printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",
edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);
- c->x86_cache_size=(ecx>>24)+(edx>>24);
- /* DTLB and ITLB together, but only 4K */
- c->x86_tlbsize = ((ebx>>16)&0xff) + (ebx&0xff);
+ c->x86_cache_size=(ecx>>24)+(edx>>24);
+ /* On K8 L1 TLB is inclusive, so don't count it */
+ c->x86_tlbsize = 0;
}
if (n >= 0x80000006) {
cpuid(0x80000006, &dummy, &ebx, &ecx, &edx);
- ecx = cpuid_ecx(0x80000006);
- c->x86_cache_size = ecx >> 16;
+ ecx = cpuid_ecx(0x80000006);
+ c->x86_cache_size = ecx >> 16;
c->x86_tlbsize += ((ebx >> 16) & 0xfff) + (ebx & 0xfff);
- printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
+ printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",
c->x86_cache_size, ecx & 0xFF);
}
@@ -849,10 +849,10 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c)
memset(&c->x86_capability, 0, sizeof c->x86_capability);
/* Get vendor name */
- cpuid(0x00000000, &c->cpuid_level,
- (int *)&c->x86_vendor_id[0],
- (int *)&c->x86_vendor_id[8],
- (int *)&c->x86_vendor_id[4]);
+ cpuid(0x00000000, (unsigned int *)&c->cpuid_level,
+ (unsigned int *)&c->x86_vendor_id[0],
+ (unsigned int *)&c->x86_vendor_id[8],
+ (unsigned int *)&c->x86_vendor_id[4]);
get_cpu_vendor(c);
@@ -892,19 +892,19 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
/* AMD-defined flags: level 0x80000001 */
xlvl = cpuid_eax(0x80000000);
- if ( (xlvl & 0xffff0000) == 0x80000000 ) {
- if ( xlvl >= 0x80000001 ) {
+ if ((xlvl & 0xffff0000) == 0x80000000) {
+ if (xlvl >= 0x80000001) {
c->x86_capability[1] = cpuid_edx(0x80000001);
c->x86_capability[5] = cpuid_ecx(0x80000001);
}
- if ( xlvl >= 0x80000004 )
+ if (xlvl >= 0x80000004)
get_model_name(c); /* Default name */
}
/* Transmeta-defined flags: level 0x80860001 */
xlvl = cpuid_eax(0x80860000);
- if ( (xlvl & 0xffff0000) == 0x80860000 ) {
- if ( xlvl >= 0x80860001 )
+ if ((xlvl & 0xffff0000) == 0x80860000) {
+ if (xlvl >= 0x80860001)
c->x86_capability[2] = cpuid_edx(0x80860001);
}
@@ -918,20 +918,19 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
* At the end of this section, c->x86_capability better
* indicate the features this CPU genuinely supports!
*/
- switch ( c->x86_vendor ) {
-
- case X86_VENDOR_AMD:
- init_amd(c);
- break;
+ switch (c->x86_vendor) {
+ case X86_VENDOR_AMD:
+ init_amd(c);
+ break;
- case X86_VENDOR_INTEL:
- init_intel(c);
- break;
+ case X86_VENDOR_INTEL:
+ init_intel(c);
+ break;
- case X86_VENDOR_UNKNOWN:
- default:
- display_cacheinfo(c);
- break;
+ case X86_VENDOR_UNKNOWN:
+ default:
+ display_cacheinfo(c);
+ break;
}
select_idle_routine(c);
@@ -944,9 +943,9 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
* common between the CPUs. The first time this routine gets
* executed, c == &boot_cpu_data.
*/
- if ( c != &boot_cpu_data ) {
+ if (c != &boot_cpu_data) {
/* AND the already accumulated flags with these */
- for ( i = 0 ; i < NCAPINTS ; i++ )
+ for (i = 0 ; i < NCAPINTS ; i++)
boot_cpu_data.x86_capability[i] &= c->x86_capability[i];
}
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c
index e9aa2ca0b55dfe..ad3b240cdd9c77 100644
--- a/arch/x86_64/kernel/signal.c
+++ b/arch/x86_64/kernel/signal.c
@@ -125,6 +125,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
+ } else {
+ struct task_struct *me = current;
+ if (me->used_math) {
+ clear_fpu(me);
+ me->used_math = 0;
+ }
}
}
@@ -139,7 +145,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
sigset_t set;
- long eax;
+ unsigned long eax;
frame = (struct rt_sigframe __user *)(regs->rsp - 8);
if (verify_area(VERIFY_READ, frame, sizeof(*frame))) {
diff --git a/arch/x86_64/lib/io.c b/arch/x86_64/lib/io.c
index df68a2623736f6..87b4a4e1803912 100644
--- a/arch/x86_64/lib/io.c
+++ b/arch/x86_64/lib/io.c
@@ -13,3 +13,11 @@ void __memcpy_fromio(void *dst,unsigned long src,unsigned len)
__inline_memcpy(dst,(const void *) src,len);
}
EXPORT_SYMBOL(__memcpy_fromio);
+
+void memset_io(volatile void __iomem *a, int b, size_t c)
+{
+ /* XXX: memset can mangle the IO patterns quite a bit.
+ perhaps it would be better to use a dumb one */
+ memset((void *)a,b,c);
+}
+EXPORT_SYMBOL(memset_io);
diff --git a/arch/x86_64/lib/old-checksum.c b/arch/x86_64/lib/old-checksum.c
deleted file mode 100644
index 20d5b8f633d36b..00000000000000
--- a/arch/x86_64/lib/old-checksum.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Temporal C versions of the checksum functions until optimized assembler versions
- * can go in.
- */
-
-#include <net/checksum.h>
-
-/*
- * Copy from userspace and compute checksum. If we catch an exception
- * then zero the rest of the buffer.
- */
-unsigned int csum_partial_copy_from_user (const char *src, char *dst,
- int len, unsigned int sum,
- int *err_ptr)
-{
- int missing;
-
- missing = copy_from_user(dst, src, len);
- if (missing) {
- memset(dst + len - missing, 0, missing);
- *err_ptr = -EFAULT;
- }
-
- return csum_partial(dst, len, sum);
-}
-
-unsigned int csum_partial_copy_nocheck(const char *src, char *dst, int len, unsigned int sum)
-{
- memcpy(dst,src,len);
- return csum_partial(dst,len,sum);
-}
-
-/* Fallback for csum_and_copy_to_user is currently in include/net/checksum.h */
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index f47f0715e37f4e..e4c8d2dc190c7f 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -68,8 +68,8 @@ void show_mem(void)
for_each_pgdat(pgdat) {
for (i = 0; i < pgdat->node_spanned_pages; ++i) {
- page = pgdat->node_mem_map + i;
- total++;
+ page = pfn_to_page(pgdat->node_start_pfn + i);
+ total++;
if (PageReserved(page))
reserved++;
else if (PageSwapCache(page))
@@ -252,51 +252,55 @@ static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned lon
__flush_tlb();
}
+static void __init find_early_table_space(unsigned long end)
+{
+ unsigned long puds, pmds, tables;
+
+ puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
+ pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
+ tables = round_up(puds * sizeof(pud_t), PAGE_SIZE) +
+ round_up(pmds * sizeof(pmd_t), PAGE_SIZE);
+
+ table_start = find_e820_area(0x8000, __pa_symbol(&_text), tables);
+ if (table_start == -1UL)
+ panic("Cannot find space for the kernel page tables");
+
+ table_start >>= PAGE_SHIFT;
+ table_end = table_start;
+}
+
/* Setup the direct mapping of the physical memory at PAGE_OFFSET.
This runs before bootmem is initialized and gets pages directly from the
physical memory. To access them they are temporarily mapped. */
-void __init init_memory_mapping(void)
+void __init init_memory_mapping(unsigned long start, unsigned long end)
{
- unsigned long adr;
- unsigned long end;
unsigned long next;
- unsigned long puds, pmds, tables;
Dprintk("init_memory_mapping\n");
- end = end_pfn_map << PAGE_SHIFT;
-
/*
* Find space for the kernel direct mapping tables.
* Later we should allocate these tables in the local node of the memory
* mapped. Unfortunately this is done currently before the nodes are
* discovered.
*/
+ find_early_table_space(end);
- puds = (end + PUD_SIZE - 1) >> PUD_SHIFT;
- pmds = (end + PMD_SIZE - 1) >> PMD_SHIFT;
- tables = round_up(puds*8, PAGE_SIZE) + round_up(pmds * 8, PAGE_SIZE);
-
- table_start = find_e820_area(0x8000, __pa_symbol(&_text), tables);
- if (table_start == -1UL)
- panic("Cannot find space for the kernel page tables");
+ start = (unsigned long)__va(start);
+ end = (unsigned long)__va(end);
- table_start >>= PAGE_SHIFT;
- table_end = table_start;
-
- end += __PAGE_OFFSET; /* turn virtual */
-
- for (adr = PAGE_OFFSET; adr < end; adr = next) {
+ for (; start < end; start = next) {
int map;
unsigned long pud_phys;
pud_t *pud = alloc_low_page(&map, &pud_phys);
- next = adr + PGDIR_SIZE;
+ next = start + PGDIR_SIZE;
if (next > end)
next = end;
- phys_pud_init(pud, adr-PAGE_OFFSET, next-PAGE_OFFSET);
- set_pgd(init_level4_pgt + pgd_index(adr), mk_kernel_pgd(pud_phys));
+ phys_pud_init(pud, __pa(start), __pa(next));
+ set_pgd(pgd_offset_k(start), mk_kernel_pgd(pud_phys));
unmap_low_page(map);
}
+
asm volatile("movq %%cr4,%0" : "=r" (mmu_cr4_features));
__flush_tlb_all();
early_printk("kernel direct mapping tables upto %lx @ %lx-%lx\n", end,
@@ -437,7 +441,7 @@ void __init mem_init(void)
/*
* Only count reserved RAM pages
*/
- if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+ if (page_is_ram(tmp) && PageReserved(pfn_to_page(tmp)))
reservedpages++;
#endif
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c
index 1a166779eeba56..12363e69b0c31e 100644
--- a/arch/x86_64/mm/ioremap.c
+++ b/arch/x86_64/mm/ioremap.c
@@ -175,11 +175,11 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
if (phys_addr >= 0xA0000 && last_addr < 0x100000)
return (__force void __iomem *)phys_to_virt(phys_addr);
+#ifndef CONFIG_DISCONTIGMEM
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
- if (phys_addr < virt_to_phys(high_memory)) {
-#ifndef CONFIG_DISCONTIGMEM
+ if (last_addr < virt_to_phys(high_memory)) {
char *t_addr, *t_end;
struct page *page;
@@ -189,8 +189,8 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
if(!PageReserved(page))
return NULL;
-#endif
}
+#endif
/*
* Mappings have to be page-aligned
@@ -202,7 +202,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l
/*
* Ok, go for it..
*/
- area = get_vm_area(size, VM_IOREMAP | (flags << 24));
+ area = get_vm_area(size, VM_IOREMAP | (flags << 20));
if (!area)
return NULL;
area->phys_addr = phys_addr;
@@ -263,7 +263,7 @@ void iounmap(volatile void __iomem *addr)
}
*pprev = p->next;
unmap_vm_area(p);
- if ((p->flags >> 24) &&
+ if ((p->flags >> 20) &&
p->phys_addr + p->size - 1 < virt_to_phys(high_memory)) {
change_page_attr(virt_to_page(__va(p->phys_addr)),
p->size >> PAGE_SHIFT,
diff --git a/arch/x86_64/mm/k8topology.c b/arch/x86_64/mm/k8topology.c
index b3acd04b3b30ed..55a2e67e32a68d 100644
--- a/arch/x86_64/mm/k8topology.c
+++ b/arch/x86_64/mm/k8topology.c
@@ -47,6 +47,10 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
int nodeid, i, nb;
int found = 0;
u32 reg;
+ unsigned numnodes;
+ nodemask_t nodes_parsed;
+
+ nodes_clear(nodes_parsed);
nb = find_northbridge();
if (nb < 0)
@@ -55,10 +59,9 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
printk(KERN_INFO "Scanning NUMA topology in Northbridge %d\n", nb);
reg = read_pci_config(0, nb, 0, 0x60);
- for (i = 0; i <= ((reg >> 4) & 7); i++)
- node_set_online(i);
+ numnodes = ((reg >> 4) & 7) + 1;
- printk(KERN_INFO "Number of nodes %d (%x)\n", num_online_nodes(), reg);
+ printk(KERN_INFO "Number of nodes %d\n", numnodes);
memset(&nodes,0,sizeof(nodes));
prevbase = 0;
@@ -70,11 +73,11 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
nodeid = limit & 7;
if ((base & 3) == 0) {
- if (i < num_online_nodes())
+ if (i < numnodes)
printk("Skipping disabled node %d\n", i);
continue;
}
- if (nodeid >= num_online_nodes()) {
+ if (nodeid >= numnodes) {
printk("Ignoring excess node %d (%lx:%lx)\n", nodeid,
base, limit);
continue;
@@ -90,7 +93,7 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
nodeid, (base>>8)&3, (limit>>8) & 3);
return -1;
}
- if (node_online(nodeid)) {
+ if (node_isset(nodeid, nodes_parsed)) {
printk(KERN_INFO "Node %d already present. Skipping\n",
nodeid);
continue;
@@ -138,12 +141,14 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
nodes[nodeid].end = limit;
prevbase = base;
+
+ node_set(nodeid, nodes_parsed);
}
if (!found)
return -1;
- memnode_shift = compute_hash_shift(nodes);
+ memnode_shift = compute_hash_shift(nodes, numnodes);
if (memnode_shift < 0) {
printk(KERN_ERR "No NUMA node hash function found. Contact maintainer\n");
return -1;
@@ -154,8 +159,8 @@ int __init k8_scan_nodes(unsigned long start, unsigned long end)
if (nodes[i].start != nodes[i].end) {
/* assume 1:1 NODE:CPU */
cpu_to_node[i] = i;
- setup_node_bootmem(i, nodes[i].start, nodes[i].end);
- }
+ setup_node_bootmem(i, nodes[i].start, nodes[i].end);
+ }
}
numa_init_array();
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c
index b1a7db4f4d6dcc..ecc0c60989c034 100644
--- a/arch/x86_64/mm/numa.c
+++ b/arch/x86_64/mm/numa.c
@@ -34,9 +34,7 @@ cpumask_t node_to_cpumask[MAX_NUMNODES];
int numa_off __initdata;
-unsigned long nodes_present;
-
-int __init compute_hash_shift(struct node *nodes)
+int __init compute_hash_shift(struct node *nodes, int numnodes)
{
int i;
int shift = 24;
@@ -45,7 +43,7 @@ int __init compute_hash_shift(struct node *nodes)
/* When in doubt use brute force. */
while (shift < 48) {
memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE);
- for_each_online_node(i) {
+ for (i = 0; i < numnodes; i++) {
if (nodes[i].start == nodes[i].end)
continue;
for (addr = nodes[i].start;
@@ -197,7 +195,7 @@ static int numa_emulation(unsigned long start_pfn, unsigned long end_pfn)
(nodes[i].end - nodes[i].start) >> 20);
node_set_online(i);
}
- memnode_shift = compute_hash_shift(nodes);
+ memnode_shift = compute_hash_shift(nodes, numa_fake);
if (memnode_shift < 0) {
memnode_shift = 0;
printk(KERN_ERR "No NUMA hash function found. Emulation disabled.\n");
@@ -274,7 +272,7 @@ void __init paging_init(void)
/* [numa=off] */
__init int numa_setup(char *opt)
{
- if (!strcmp(opt,"off"))
+ if (!strncmp(opt,"off",3))
numa_off = 1;
#ifdef CONFIG_NUMA_EMU
if(!strncmp(opt, "fake=", 5)) {
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 05074f17773041..5b3cd2000a54e4 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -131,28 +131,36 @@ __change_page_attr(unsigned long address, unsigned long pfn, pgprot_t prot,
kpte_flags = pte_val(*kpte);
if (pgprot_val(prot) != pgprot_val(ref_prot)) {
if ((kpte_flags & _PAGE_PSE) == 0) {
- pte_t old = *kpte;
- pte_t standard = pfn_pte(pfn, ref_prot);
-
set_pte(kpte, pfn_pte(pfn, prot));
- if (pte_same(old,standard))
- get_page(kpte_page);
} else {
+ /*
+ * split_large_page will take the reference for this change_page_attr
+ * on the split page.
+ */
struct page *split = split_large_page(address, prot, ref_prot);
if (!split)
return -ENOMEM;
- get_page(split);
set_pte(kpte,mk_pte(split, ref_prot));
+ kpte_page = split;
}
+ get_page(kpte_page);
} else if ((kpte_flags & _PAGE_PSE) == 0) {
set_pte(kpte, pfn_pte(pfn, ref_prot));
__put_page(kpte_page);
- }
+ } else
+ BUG();
- if (page_count(kpte_page) == 1) {
+ /* on x86-64 the direct mapping set at boot is not using 4k pages */
+ BUG_ON(PageReserved(kpte_page));
+
+ switch (page_count(kpte_page)) {
+ case 1:
save_page(address, kpte_page);
revert_page(address, ref_prot);
- }
+ break;
+ case 0:
+ BUG(); /* memleak and failed 2M page regeneration */
+ }
return 0;
}
diff --git a/arch/x86_64/mm/srat.c b/arch/x86_64/mm/srat.c
index 1db7483a0564dc..3bd04832f041c9 100644
--- a/arch/x86_64/mm/srat.c
+++ b/arch/x86_64/mm/srat.c
@@ -20,17 +20,20 @@
static struct acpi_table_slit *acpi_slit;
-static DECLARE_BITMAP(nodes_parsed, MAX_NUMNODES) __initdata;
+static nodemask_t nodes_parsed __initdata;
+static nodemask_t nodes_found __initdata;
static struct node nodes[MAX_NUMNODES] __initdata;
static __u8 pxm2node[256] __initdata = { [0 ... 255] = 0xff };
static __init int setup_node(int pxm)
{
- if (pxm2node[pxm] == 0xff) {
- if (num_online_nodes() >= MAX_NUMNODES)
+ unsigned node = pxm2node[pxm];
+ if (node == 0xff) {
+ if (nodes_weight(nodes_found) >= MAX_NUMNODES)
return -1;
- pxm2node[pxm] = num_online_nodes();
- node_set_online(num_online_nodes());
+ node = first_unset_node(nodes_found);
+ node_set(node, nodes_found);
+ pxm2node[pxm] = node;
}
return pxm2node[pxm];
}
@@ -140,7 +143,7 @@ acpi_numa_memory_affinity_init(struct acpi_table_memory_affinity *ma)
return;
}
nd = &nodes[node];
- if (!test_and_set_bit(node, &nodes_parsed)) {
+ if (!node_test_and_set(node, nodes_parsed)) {
nd->start = start;
nd->end = end;
} else {
@@ -163,7 +166,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
int i;
if (acpi_numa <= 0)
return -1;
- memnode_shift = compute_hash_shift(nodes);
+ memnode_shift = compute_hash_shift(nodes, nodes_weight(nodes_parsed));
if (memnode_shift < 0) {
printk(KERN_ERR
"SRAT: No NUMA node hash function found. Contact maintainer\n");
@@ -171,7 +174,7 @@ int __init acpi_scan_nodes(unsigned long start, unsigned long end)
return -1;
}
for (i = 0; i < MAX_NUMNODES; i++) {
- if (!test_bit(i, &nodes_parsed))
+ if (!node_isset(i, nodes_parsed))
continue;
cutoff_node(i, start, end);
if (nodes[i].start == nodes[i].end)