From 6c80a21cb1825e576ffff9df2302bf0fa1065ceb Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 6 May 2005 16:28:56 +1000 Subject: [PATCH] ppc64: global interrupt queue cleanup Move the code to set global interrupt queue membership to xics.c, and remove no longer needed extern declarations. Also call it on all cpus (even the boot cpu) to prepare for kexec. Signed-off-by: Milton Miller Signed-off-by: R Sharada Signed-off-by: Paul Mackerras Signed-off-by: Linus Torvalds --- arch/ppc64/kernel/pSeries_smp.c | 7 ------- arch/ppc64/kernel/xics.c | 16 ++++++++++++---- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'arch') diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index c60d8cb2b84d..fbad349ec58c 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c @@ -326,13 +326,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) cpu_clear(cpu, of_spin_map); - /* - * 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); } static DEFINE_SPINLOCK(timebase_lock); diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index eedd1d3c2a10..879f39b90a33 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c @@ -432,6 +432,7 @@ void xics_cause_IPI(int cpu) { ops->qirr_info(cpu, IPI_PRIORITY); } +#endif /* CONFIG_SMP */ void xics_setup_cpu(void) { @@ -439,9 +440,17 @@ void xics_setup_cpu(void) ops->cppr_info(cpu, 0xff); iosync(); -} -#endif /* CONFIG_SMP */ + /* + * 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. + * + * XXX: undo of teardown on kexec needs this too, as may hotplug + */ + rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, + (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); +} void xics_init_IRQ(void) { @@ -563,8 +572,7 @@ nextnode: for (; i < NR_IRQS; ++i) get_irq_desc(i)->handler = &xics_pic; - ops->cppr_info(boot_cpuid, 0xff); - iosync(); + xics_setup_cpu(); ppc64_boot_msg(0x21, "XICS Done"); } -- cgit v1.2.2 From 22490eb80ceb4ac07ef36fff253904fb4adf57f2 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 6 May 2005 15:39:23 -0700 Subject: Fix acpi_find_rsdp() - acpi_scan_rsdp takes length, not end Noticed by Jakub Jermar --- arch/i386/kernel/acpi/boot.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 53eb5cfd5b63..848bb97af7ca 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -650,7 +650,7 @@ acpi_find_rsdp (void) */ rsdp_phys = acpi_scan_rsdp (0, 0x400); if (!rsdp_phys) - rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); + rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000); return rsdp_phys; } -- cgit v1.2.2 From b7c2b704bd78aa3665fc24100bd2d4f5f8305d7a Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Fri, 6 May 2005 17:41:03 -0700 Subject: [PATCH] ppc64: enable CONFIG_RTAS_PROC by default This patch enables CONFIG_RTAS_PROC by default on pSeries. This will preserve /proc/ppc64/rtas/rmo_buffer, which is needed by librtas. Signed-off-by: John Rose Signed-off-by: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc64/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch') diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index 257ff66d83cf..5cb343883e4d 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig @@ -262,6 +262,7 @@ config PPC_RTAS config RTAS_PROC bool "Proc interface to RTAS" depends on PPC_RTAS + default y config RTAS_FLASH tristate "Firmware flash interface" -- cgit v1.2.2 From b272125273103458b9727df1868b81bae64f44cb Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 6 May 2005 21:30:41 -0700 Subject: [PATCH] ppc32: Fix POWER3/POWER4 compiler error In separating out support for hardware floating point we missed the fact that both POWER3 and POWER4 have HW FP. Enable CONFIG_PPC_FPU for POWER3 and POWER4 fixes the issue. Signed-off-by: Kumar Gala Acked-by: Paul Mackerras Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/ppc/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index d0d94e56b90b..600f23d7fd33 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig @@ -77,9 +77,11 @@ config 44x bool "44x" config POWER3 + select PPC_FPU bool "POWER3" config POWER4 + select PPC_FPU bool "POWER4 and 970 (G5)" config 8xx -- cgit v1.2.2 From f2a0f8b9301ca34034c4a2ec09a09ff4677e83dd Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 6 May 2005 21:30:43 -0700 Subject: [PATCH] uml: __deprecated makes build unnecessarily noisy Remove the __deprecated from verify_area_skas and verify_area_tt. Since verify_area is itself marked __deprecated, and it is the only caller of these, then they don't need to be marked. Marking them only makes the build noisier. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/include/uaccess-skas.h | 4 ++-- arch/um/kernel/tt/include/uaccess-tt.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h index c35620385da0..cd6c280482cb 100644 --- a/arch/um/kernel/skas/include/uaccess-skas.h +++ b/arch/um/kernel/skas/include/uaccess-skas.h @@ -18,8 +18,8 @@ ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) -static inline int __deprecated verify_area_skas(int type, const void * addr, - unsigned long size) +static inline int verify_area_skas(int type, const void * addr, + unsigned long size) { return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); } diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h index bb69d6b7d022..3fbb5fe26f49 100644 --- a/arch/um/kernel/tt/include/uaccess-tt.h +++ b/arch/um/kernel/tt/include/uaccess-tt.h @@ -33,8 +33,8 @@ extern unsigned long uml_physmem; (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ (under_task_size(addr, size) || is_stack(addr, size)))) -static inline int __deprecated verify_area_tt(int type, const void * addr, - unsigned long size) +static inline int verify_area_tt(int type, const void * addr, + unsigned long size) { return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); } -- cgit v1.2.2 From 16c11163019879c0e1e69d3ec7d4574a80e9c77e Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 6 May 2005 21:30:45 -0700 Subject: [PATCH] uml: command line handling cleanup Command line handling cleanups - a couple of things made static and an unused declaration removed from header. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/include/user_util.h | 1 - arch/um/kernel/um_arch.c | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'arch') diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 103cd320386c..b8c5b8a95250 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h @@ -67,7 +67,6 @@ extern void *um_kmalloc(int size); extern int switcheroo(int fd, int prot, void *from, void *to, int size); extern void setup_machinename(char *machine_out); extern void setup_hostinfo(void); -extern void add_arg(char *arg); extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); extern void init_new_thread_signals(int altstack); extern void do_exec(int old_pid, int new_pid); diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 5c49d88eed3d..4d10ec372a67 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c @@ -23,6 +23,7 @@ #include "asm/ptrace.h" #include "asm/elf.h" #include "asm/user.h" +#include "asm/setup.h" #include "ubd_user.h" #include "asm/current.h" #include "asm/setup.h" @@ -42,9 +43,9 @@ #define DEFAULT_COMMAND_LINE "root=98:0" /* Changed in linux_main and setup_arch, which run before SMP is started */ -char command_line[COMMAND_LINE_SIZE] = { 0 }; +static char command_line[COMMAND_LINE_SIZE] = { 0 }; -void add_arg(char *arg) +static void add_arg(char *arg) { if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { printf("add_arg: Too many command line arguments!\n"); @@ -449,7 +450,7 @@ void __init setup_arch(char **cmdline_p) { notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); paging_init(); - strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); + strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); *cmdline_p = command_line; setup_hostinfo(); } -- cgit v1.2.2 From 82c1c11bdd92d94f8fd620a3ea6c894eba37d4ed Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Fri, 6 May 2005 21:30:46 -0700 Subject: [PATCH] uml: S390 preparation, peekusr/pokeusr defined by subarch s390 needs to change some parts of arch/um/kernel/ptrace.c. Thus, the code regarding PEEKUSER and POKEUSER are shifted to arch/um/sys-/ptrace.c. Also s390 debug registers need to be updated, when singlestepping is switched on / off. Thus, setting/resetting of singlestepping is centralized in the new function set_singlestep(), which also inserts the macro SUBARCH_SET_SINGLESTEP(mode), if defined. Finally, s390 has the "ieee_instruction_pointer" in its registers, which also is allowed to be read via ptrace( PTRACE_PEEKUSER, getpid(), PT_IEEE_IP, 0); To implement this feature, sys_ptrace inserts the macro SUBARCH_PTRACE_SPECIAL, if defined. Signed-off-by: Bodo Stroesser Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/ptrace.c | 79 +++++++++++++++++---------------------------- arch/um/sys-i386/ptrace.c | 40 +++++++++++++++++++++++ arch/um/sys-ppc/ptrace.c | 40 +++++++++++++++++++++++ arch/um/sys-x86_64/ptrace.c | 44 +++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 50 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 3efa59a941a4..2b75d8d9ba73 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c @@ -19,15 +19,30 @@ #include "skas_ptrace.h" #include "sysdep/ptrace.h" +static inline void set_singlestepping(struct task_struct *child, int on) +{ + if (on) + child->ptrace |= PT_DTRACE; + else + child->ptrace &= ~PT_DTRACE; + child->thread.singlestep_syscall = 0; + +#ifdef SUBARCH_SET_SINGLESTEPPING + SUBARCH_SET_SINGLESTEPPING(child, on) +#endif + } + /* * Called by kernel/ptrace.c when detaching.. */ void ptrace_disable(struct task_struct *child) { - child->ptrace &= ~PT_DTRACE; - child->thread.singlestep_syscall = 0; + set_singlestepping(child,0); } +extern int peek_user(struct task_struct * child, long addr, long data); +extern int poke_user(struct task_struct * child, long addr, long data); + long sys_ptrace(long request, long pid, long addr, long data) { struct task_struct *child; @@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data) goto out_tsk; } +#ifdef SUBACH_PTRACE_SPECIAL + SUBARCH_PTRACE_SPECIAL(child,request,addr,data) +#endif + ret = ptrace_check_attach(child, request == PTRACE_KILL); if (ret < 0) goto out_tsk; @@ -87,28 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data) } /* read the word at location addr in the USER area. */ - case PTRACE_PEEKUSR: { - unsigned long tmp; - - ret = -EIO; - if ((addr & 3) || addr < 0) - break; - - tmp = 0; /* Default return condition */ - if(addr < MAX_REG_OFFSET){ - tmp = getreg(child, addr); - } -#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT) - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - tmp = child->thread.arch.debugregs[addr]; - } -#endif - ret = put_user(tmp, (unsigned long __user *) data); - break; - } + case PTRACE_PEEKUSR: + ret = peek_user(child, addr, data); + break; /* when I and D space are separate, this will have to be fixed. */ case PTRACE_POKETEXT: /* write the word at location addr. */ @@ -121,26 +121,8 @@ long sys_ptrace(long request, long pid, long addr, long data) break; case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ - ret = -EIO; - if ((addr & 3) || addr < 0) - break; - - if (addr < MAX_REG_OFFSET) { - ret = putreg(child, addr, data); - break; - } -#if defined(CONFIG_UML_X86) && !defined(CONFIG_64BIT) - else if((addr >= offsetof(struct user, u_debugreg[0])) && - (addr <= offsetof(struct user, u_debugreg[7]))){ - addr -= offsetof(struct user, u_debugreg[0]); - addr = addr >> 2; - if((addr == 4) || (addr == 5)) break; - child->thread.arch.debugregs[addr] = data; - ret = 0; - } -#endif - - break; + ret = poke_user(child, addr, data); + break; case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ case PTRACE_CONT: { /* restart after signal. */ @@ -148,8 +130,7 @@ long sys_ptrace(long request, long pid, long addr, long data) if (!valid_signal(data)) break; - child->ptrace &= ~PT_DTRACE; - child->thread.singlestep_syscall = 0; + set_singlestepping(child, 0); if (request == PTRACE_SYSCALL) { set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); } @@ -172,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data) if (child->exit_state == EXIT_ZOMBIE) /* already dead */ break; - child->ptrace &= ~PT_DTRACE; - child->thread.singlestep_syscall = 0; + set_singlestepping(child, 0); child->exit_code = SIGKILL; wake_up_process(child); break; @@ -184,8 +164,7 @@ long sys_ptrace(long request, long pid, long addr, long data) if (!valid_signal(data)) break; clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); - child->ptrace |= PT_DTRACE; - child->thread.singlestep_syscall = 0; + set_singlestepping(child, 1); child->exit_code = data; /* give it a chance to run. */ wake_up_process(child); diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index e470d28cdf84..e839ce65ad28 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c @@ -73,6 +73,25 @@ int putreg(struct task_struct *child, int regno, unsigned long value) return 0; } +int poke_user(struct task_struct *child, long addr, long data) +{ + if ((addr & 3) || addr < 0) + return -EIO; + + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + + else if((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if((addr == 4) || (addr == 5)) return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } + return -EIO; +} + unsigned long getreg(struct task_struct *child, int regno) { unsigned long retval = ~0UL; @@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno) return retval; } +int peek_user(struct task_struct *child, long addr, long data) +{ +/* read the word at location addr in the USER area. */ + unsigned long tmp; + + if ((addr & 3) || addr < 0) + return -EIO; + + tmp = 0; /* Default return condition */ + if(addr < MAX_REG_OFFSET){ + tmp = getreg(child, addr); + } + else if((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } + return put_user(tmp, (unsigned long *) data); +} + struct i387_fxsave_struct { unsigned short cwd; unsigned short swd; diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c index a971366d3277..8e71b47f2b8e 100644 --- a/arch/um/sys-ppc/ptrace.c +++ b/arch/um/sys-ppc/ptrace.c @@ -8,6 +8,25 @@ int putreg(struct task_struct *child, unsigned long regno, return 0; } +int poke_user(struct task_struct *child, long addr, long data) +{ + if ((addr & 3) || addr < 0) + return -EIO; + + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + + else if((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if((addr == 4) || (addr == 5)) return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } + return -EIO; +} + unsigned long getreg(struct task_struct *child, unsigned long regno) { unsigned long retval = ~0UL; @@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno) return retval; } +int peek_user(struct task_struct *child, long addr, long data) +{ + /* read the word at location addr in the USER area. */ + unsigned long tmp; + + if ((addr & 3) || addr < 0) + return -EIO; + + tmp = 0; /* Default return condition */ + if(addr < MAX_REG_OFFSET){ + tmp = getreg(child, addr); + } + else if((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } + return put_user(tmp, (unsigned long *) data); +} + /* * 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/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 8c146b2a1e00..b593bb256f2c 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c @@ -62,6 +62,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value) return 0; } +int poke_user(struct task_struct *child, long addr, long data) +{ + if ((addr & 3) || addr < 0) + return -EIO; + + if (addr < MAX_REG_OFFSET) + return putreg(child, addr, data); + +#if 0 /* Need x86_64 debugregs handling */ + else if((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + if((addr == 4) || (addr == 5)) return -EIO; + child->thread.arch.debugregs[addr] = data; + return 0; + } +#endif + return -EIO; +} + unsigned long getreg(struct task_struct *child, int regno) { unsigned long retval = ~0UL; @@ -84,6 +105,29 @@ unsigned long getreg(struct task_struct *child, int regno) return retval; } +int peek_user(struct task_struct *child, long addr, long data) +{ + /* read the word at location addr in the USER area. */ + unsigned long tmp; + + if ((addr & 3) || addr < 0) + return -EIO; + + tmp = 0; /* Default return condition */ + if(addr < MAX_REG_OFFSET){ + tmp = getreg(child, addr); + } +#if 0 /* Need x86_64 debugregs handling */ + else if((addr >= offsetof(struct user, u_debugreg[0])) && + (addr <= offsetof(struct user, u_debugreg[7]))){ + addr -= offsetof(struct user, u_debugreg[0]); + addr = addr >> 2; + tmp = child->thread.arch.debugregs[addr]; + } +#endif + return put_user(tmp, (unsigned long *) data); +} + void arch_switch(void) { /* XXX -- cgit v1.2.2 From 804c2415c9182b95719cdf85913f6313f7ac042a Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Fri, 6 May 2005 21:30:49 -0700 Subject: [PATCH] uml: S390 preparation, save an extra register s390 tt-mode needs to save not only syscall number, but an further register also. Signed-off-by: Bodo Stroesser Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tt/syscall_user.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch') diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c index e4e7e9c2224c..b218316cfdb2 100644 --- a/arch/um/kernel/tt/syscall_user.c +++ b/arch/um/kernel/tt/syscall_user.c @@ -63,6 +63,10 @@ void do_syscall(void *task, int pid, int local_using_sysemu) UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); +#ifdef UPT_ORIGGPR2 + UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs); +#endif + if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && ((unsigned long *) PT_IP(proc_regs) <= &_etext)) tracer_panic("I'm tracing myself and I can't get out"); -- cgit v1.2.2 From ccfcd37cb694fc71ddf16fa7faa9e06811a26e5b Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 6 May 2005 21:30:50 -0700 Subject: [PATCH] uml: Eliminate unusable function Eliminate the non-inline version of switch_mm, which can't be used, considering the inline version in asm/mmu_context.h Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process_kern.c | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 7a943696f950..dea80d4357f0 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -115,16 +115,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) return(pid); } -void switch_mm(struct mm_struct *prev, struct mm_struct *next, - struct task_struct *tsk) -{ - int cpu = smp_processor_id(); - - if (prev != next) - cpu_clear(cpu, prev->cpu_vm_mask); - cpu_set(cpu, next->cpu_vm_mask); -} - void set_current(void *t) { struct task_struct *task = t; -- cgit v1.2.2 From 37f02b63bdc55147a32cedf7831452efd5a72748 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 6 May 2005 21:30:51 -0700 Subject: [PATCH] uml: Makefile cleanup This eliminates some stuff from arch/um/kernel/Makefile which refers to a file which has long since been deleted. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/Makefile | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index dca654263857..9736ca27c5f0 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile @@ -23,14 +23,10 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o obj-$(CONFIG_MODE_TT) += tt/ obj-$(CONFIG_MODE_SKAS) += skas/ -# This needs be compiled with frame pointers regardless of how the rest of the -# kernel is built. -CFLAGS_frame.o := -fno-omit-frame-pointer - user-objs-$(CONFIG_TTY_LOG) += tty_log.o USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ - time.o tty_log.o umid.o user_util.o frame.o + time.o tty_log.o umid.o user_util.o include arch/um/scripts/Makefile.rules -- cgit v1.2.2 From 675dffc914412a25d33bbc8baea30681c565c9c1 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 6 May 2005 21:30:51 -0700 Subject: [PATCH] uml: Turn literal numbers into symbolic constants So, there I was, looking at my own code, wondering what the magic setjmp return values did. This patch turns the constants that are used to make requests of the initial thread into meaningful symbols. Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/process.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 4dc13bc8cfd8..773cd2b525fc 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c @@ -201,6 +201,11 @@ void userspace(union uml_pt_regs *regs) } } } +#define INIT_JMP_NEW_THREAD 0 +#define INIT_JMP_REMOVE_SIGSTACK 1 +#define INIT_JMP_CALLBACK 2 +#define INIT_JMP_HALT 3 +#define INIT_JMP_REBOOT 4 void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, void (*handler)(int)) @@ -236,7 +241,7 @@ void thread_wait(void *sw, void *fb) *switch_buf = &buf; fork_buf = fb; if(sigsetjmp(buf, 1) == 0) - siglongjmp(*fork_buf, 1); + siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); } void switch_threads(void *me, void *next) @@ -266,21 +271,25 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) *fork_buf_ptr = &initial_jmpbuf; n = sigsetjmp(initial_jmpbuf, 1); - if(n == 0) - new_thread_proc((void *) stack, new_thread_handler); - else if(n == 1) - remove_sigstack(); - else if(n == 2){ + switch(n){ + case INIT_JMP_NEW_THREAD: + new_thread_proc((void *) stack, new_thread_handler); + break; + case INIT_JMP_REMOVE_SIGSTACK: + remove_sigstack(); + break; + case INIT_JMP_CALLBACK: (*cb_proc)(cb_arg); siglongjmp(*cb_back, 1); - } - else if(n == 3){ + break; + case INIT_JMP_HALT: kmalloc_ok = 0; return(0); - } - else if(n == 4){ + case INIT_JMP_REBOOT: kmalloc_ok = 0; return(1); + default: + panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); } siglongjmp(**switch_buf, 1); } @@ -305,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) block_signals(); if(sigsetjmp(here, 1) == 0) - siglongjmp(initial_jmpbuf, 2); + siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK); unblock_signals(); cb_proc = NULL; @@ -316,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) void halt_skas(void) { block_signals(); - siglongjmp(initial_jmpbuf, 3); + siglongjmp(initial_jmpbuf, INIT_JMP_HALT); } void reboot_skas(void) { block_signals(); - siglongjmp(initial_jmpbuf, 4); + siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); } void switch_mm_skas(int mm_fd) -- cgit v1.2.2 From 1f3be588b51e809476cdecd4eaf6fd04670d9c36 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Fri, 6 May 2005 21:30:52 -0700 Subject: [PATCH] uml: Use CONFIG variable for address space size tt/mem.c still uses hardcoded TOP for i386 instead of CONFIG_TOP_ADDR provided by subarch's Kconfig_XXXX, which would be right. Signed-off-by: Bodo Stroesser Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/tt/mem.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c index 74346a04a2b2..bcb8796c3cb1 100644 --- a/arch/um/kernel/tt/mem.c +++ b/arch/um/kernel/tt/mem.c @@ -21,14 +21,8 @@ void before_mem_tt(unsigned long brk_start) remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); } -#ifdef CONFIG_HOST_2G_2G -#define TOP 0x80000000 -#else -#define TOP 0xc0000000 -#endif - #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) -#define START (TOP - SIZE) +#define START (CONFIG_TOP_ADDR - SIZE) unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, unsigned long *task_size_out) -- cgit v1.2.2 From b8bd0220c1ac6273eda66e25d992654219f846b6 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Fri, 6 May 2005 21:30:53 -0700 Subject: [PATCH] uml: S390 preparation, arch_align_stack Only x86 and x86_64 use arch_align_stack(), all other subarches have: #define arch_align_stack(x) (x) So, if this definition is found, UML's own arch_align_stack() should be skipped. Signed-off-by: Bodo Stroesser Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process_kern.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index dea80d4357f0..3dcb080c44a0 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -466,12 +466,21 @@ int singlestepping(void * t) return 2; } +/* + * Only x86 and x86_64 have an arch_align_stack(). + * All other arches have "#define arch_align_stack(x) (x)" + * in their asm/system.h + * As this is included in UML from asm-um/system-generic.h, + * we can use it to behave as the subarch does. + */ +#ifndef arch_align_stack unsigned long arch_align_stack(unsigned long sp) { if (randomize_va_space) sp -= get_random_int() % 8192; return sp & ~0xf; } +#endif /* -- cgit v1.2.2 From 0f7e663dea7f0e22f3b2d07156c5e9d2e8656610 Mon Sep 17 00:00:00 2001 From: Bodo Stroesser Date: Fri, 6 May 2005 21:30:54 -0700 Subject: [PATCH] uml: Fix process exit race tt-mode closes switch_pipes in exit_thread_tt and kills processes in switch_to_tt, if the exit_state is EXIT_DEAD or EXIT_ZOMBIE. In very rare cases the exiting process can be scheduled out after having set exit_state and closed switch_pipes (from release_task it calls proc_pid_flush, which might sleep). If this process is to be restarted, UML failes in switch_to_tt with: write of switch_pipe failed, err = 9 We fix this by closing switch_pipes not in exit_thread_tt, but later in release_thread_tt. Additionally, we set switch_pipe[0] = 0 after closing. switch_to_tt must not kill "from" process depending on its exit_state, but must kill it after release_thread was processed only, so it examines switch_pipe[0] for its decision. Signed-off-by: Bodo Stroesser Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/process_kern.c | 1 - arch/um/kernel/skas/include/mode_kern-skas.h | 1 - arch/um/kernel/skas/process_kern.c | 4 ---- arch/um/kernel/tt/include/mode_kern-tt.h | 1 - arch/um/kernel/tt/process_kern.c | 20 +++++++++++--------- 5 files changed, 11 insertions(+), 16 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 3dcb080c44a0..c1adf7ba3fd1 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c @@ -142,7 +142,6 @@ void release_thread(struct task_struct *task) void exit_thread(void) { - CHOOSE_MODE(exit_thread_tt(), exit_thread_skas()); unprotect_stack((unsigned long) current_thread); } diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h index 94c564962378..e48490028111 100644 --- a/arch/um/kernel/skas/include/mode_kern-skas.h +++ b/arch/um/kernel/skas/include/mode_kern-skas.h @@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct *p, struct pt_regs *regs); extern void release_thread_skas(struct task_struct *task); -extern void exit_thread_skas(void); extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); extern void init_idle_skas(void); extern void flush_tlb_kernel_range_skas(unsigned long start, diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 5d096ea63b97..ab5d3271da0b 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c @@ -83,10 +83,6 @@ void release_thread_skas(struct task_struct *task) { } -void exit_thread_skas(void) -{ -} - void fork_handler(int sig) { change_sig(SIGUSR1, 1); diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h index 28aaab3448fa..e0ca0e0b2516 100644 --- a/arch/um/kernel/tt/include/mode_kern-tt.h +++ b/arch/um/kernel/tt/include/mode_kern-tt.h @@ -19,7 +19,6 @@ extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, unsigned long stack_top, struct task_struct *p, struct pt_regs *regs); extern void release_thread_tt(struct task_struct *task); -extern void exit_thread_tt(void); extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); extern void init_idle_tt(void); extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index f19f7c18febe..df810ca8fc12 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c @@ -65,8 +65,7 @@ void *switch_to_tt(void *prev, void *next, void *last) panic("write of switch_pipe failed, err = %d", -err); reading = 1; - if((from->exit_state == EXIT_ZOMBIE) || - (from->exit_state == EXIT_DEAD)) + if(from->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(os_getpid(), 0); err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); @@ -81,8 +80,7 @@ void *switch_to_tt(void *prev, void *next, void *last) * in case it has not already killed itself. */ prev_sched = current->thread.prev_sched; - if((prev_sched->exit_state == EXIT_ZOMBIE) || - (prev_sched->exit_state == EXIT_DEAD)) + if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); change_sig(SIGVTALRM, vtalrm); @@ -101,14 +99,18 @@ void release_thread_tt(struct task_struct *task) { int pid = task->thread.mode.tt.extern_pid; + /* + * We first have to kill the other process, before + * closing its switch_pipe. Else it might wake up + * and receive "EOF" before we could kill it. + */ if(os_getpid() != pid) os_kill_process(pid, 0); -} -void exit_thread_tt(void) -{ - os_close_file(current->thread.mode.tt.switch_pipe[0]); - os_close_file(current->thread.mode.tt.switch_pipe[1]); + os_close_file(task->thread.mode.tt.switch_pipe[0]); + os_close_file(task->thread.mode.tt.switch_pipe[1]); + /* use switch_pipe as flag: thread is released */ + task->thread.mode.tt.switch_pipe[0] = -1; } void suspend_new_thread(int fd) -- cgit v1.2.2 From 2d58cc9a437f3833d242e9d1617ec9b4044e26f3 Mon Sep 17 00:00:00 2001 From: Jeff Dike Date: Fri, 6 May 2005 21:30:55 -0700 Subject: [PATCH] uml: x86_64 fixes This fixes some x86_64 bugs - - maybe_map returns -1 on error instead of 0, which is interpreted as physical address 0 - removed an include of ipc.h, which isn't needed - fixed the calculation of signal frame location - the signal delivery code is now immune to the stack expansion check - added a missing include Signed-off-by: Jeff Dike Cc: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/um/kernel/skas/uaccess.c | 7 +++++-- arch/um/kernel/syscall_kern.c | 1 - arch/um/kernel/trap_kern.c | 2 +- arch/um/sys-x86_64/signal.c | 2 +- arch/um/sys-x86_64/syscalls.c | 2 ++ 5 files changed, 9 insertions(+), 5 deletions(-) (limited to 'arch') diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index f7da9d027672..75195281081e 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -29,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write) if(IS_ERR(phys) || (is_write && !pte_write(pte))){ err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); if(err) - return(0); + return(-1UL); phys = um_virt_to_phys(current, virt, NULL); } + if(IS_ERR(phys)) + phys = (void *) -1; + return((unsigned long) phys); } @@ -42,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write, int n; addr = maybe_map(addr, is_write); - if(addr == -1) + if(addr == -1UL) return(-1); page = phys_to_page(addr); diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c index 42731e04f50f..b7a55251e897 100644 --- a/arch/um/kernel/syscall_kern.c +++ b/arch/um/kernel/syscall_kern.c @@ -17,7 +17,6 @@ #include "linux/utime.h" #include "asm/mman.h" #include "asm/uaccess.h" -#include "asm/ipc.h" #include "kern_util.h" #include "user_util.h" #include "sysdep/syscalls.h" diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 54e2ec33a43c..5fca2c61eb98 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c @@ -48,7 +48,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, goto good_area; else if(!(vma->vm_flags & VM_GROWSDOWN)) goto out; - else if(!ARCH_IS_STACKGROW(address)) + else if(is_user && !ARCH_IS_STACKGROW(address)) goto out; else if(expand_stack(vma, address)) goto out; diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index b740177066a0..73a7926f7370 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c @@ -168,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, frame = (struct rt_sigframe __user *) round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; - frame -= 128; + ((unsigned char *) frame) -= 128; if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) goto out; diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index 2a575ef52bba..dd9914642b8e 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c @@ -44,6 +44,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount) #ifdef CONFIG_MODE_SKAS extern int userspace_pid[]; +#include "skas_ptrace.h" + long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) { struct ptrace_ldt ldt; -- cgit v1.2.2