[PATCH] uml: Fix sysrq-r support for skas mode
authorAllan Graves <allan.graves@oracle.com>
Tue, 4 Oct 2005 18:53:52 +0000 (14:53 -0400)
committerLinus Torvalds <torvalds@g5.osdl.org>
Tue, 4 Oct 2005 20:22:01 +0000 (13:22 -0700)
The old code had the IP and SP coming from the registers in the thread
struct, which are completely wrong since those are the userspace
registers.  This fixes that by pulling the correct values from the
jmp_buf in which the kernel state of each thread is stored.

Signed-off-by: Allan Graves <allan.graves@oracle.com>
Signed-off-by: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
arch/um/include/registers.h
arch/um/include/sysdep-x86_64/ptrace.h
arch/um/kernel/sysrq.c
arch/um/os-Linux/sys-i386/registers.c
arch/um/os-Linux/sys-x86_64/registers.c
arch/um/sys-i386/sysrq.c
include/asm-um/processor-generic.h
include/asm-um/processor-i386.h
include/asm-um/processor-x86_64.h

index 0a35e6d0baa047b455a050899f408cddf8632d5c..4892e5fcef07dce7170c70ce85a9f4e3ad867d92 100644 (file)
@@ -15,16 +15,6 @@ 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);
 extern void get_safe_registers(unsigned long * regs);
+extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
 
 #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:
- */
index 331aa2d1f3f5469f04c0fa9bbefe0a15934edde0..8f0656766c2171b58a858d889108753f69f2f33d 100644 (file)
@@ -218,10 +218,6 @@ struct syscall_args {
                 case RBP: UPT_RBP(regs) = __upt_val; break; \
                 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
                 case CS: UPT_CS(regs) = __upt_val; break; \
-                case DS: UPT_DS(regs) = __upt_val; break; \
-                case ES: UPT_ES(regs) = __upt_val; break; \
-                case FS: UPT_FS(regs) = __upt_val; break; \
-                case GS: UPT_GS(regs) = __upt_val; break; \
                 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
                 default :  \
                         panic("Bad register in UPT_SET : %d\n", reg);  \
index f80850091e798c1eab0ad3f820cdf21350cf22b3..b331e970002ffe29c4d8db3d97c0d42a0084e525 100644 (file)
@@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
 
        if (esp == NULL) {
                if (task != current && task != NULL) {
-                       /* XXX: Isn't this bogus? I.e. isn't this the
-                        * *userspace* stack of this task? If not so, use this
-                        * even when task == current (as in i386).
-                        */
                        esp = (unsigned long *) KSTK_ESP(task);
-                       /* Which one? No actual difference - just coding style.*/
-                       //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
                } else {
                        esp = (unsigned long *) &esp;
                }
@@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp)
        }
 
        printk("Call Trace: \n");
-       show_trace(current, esp);
+       show_trace(task, esp);
 }
index 3125d320722c9c529c1c566f2854d20439192e1b..aee4812333c6ebebb6b821ebb92ac28820fcaf34 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <setjmp.h>
 #include "sysdep/ptrace_user.h"
 #include "sysdep/ptrace.h"
 #include "uml-config.h"
@@ -126,13 +127,11 @@ void get_safe_registers(unsigned long *regs)
        memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
 }
 
-/*
- * 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:
- */
+void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
+{
+       struct __jmp_buf_tag *jmpbuf = buffer;
+
+       UPT_SET(uml_regs, EIP, jmpbuf->__jmpbuf[JB_PC]);
+       UPT_SET(uml_regs, UESP, jmpbuf->__jmpbuf[JB_SP]);
+       UPT_SET(uml_regs, EBP, jmpbuf->__jmpbuf[JB_BP]);
+}
index 44438d15c3d699c5492d903a2e87df3765efe550..4b638dfb52b07b73cbf7cb450513417510c5bb8e 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <errno.h>
 #include <string.h>
+#include <setjmp.h>
 #include "ptrace_user.h"
 #include "uml-config.h"
 #include "skas_ptregs.h"
@@ -74,13 +75,11 @@ void get_safe_registers(unsigned long *regs)
        memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
 }
 
-/*
- * 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:
- */
+void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
+{
+       struct __jmp_buf_tag *jmpbuf = buffer;
+
+       UPT_SET(uml_regs, RIP, jmpbuf->__jmpbuf[JB_PC]);
+       UPT_SET(uml_regs, RSP, jmpbuf->__jmpbuf[JB_RSP]);
+       UPT_SET(uml_regs, RBP, jmpbuf->__jmpbuf[JB_RBP]);
+}
index e3706d15c4f51bfefe364ee37c45c5fe99375c12..d5244f07053990392d695705013bc86993cad76c 100644 (file)
@@ -88,9 +88,7 @@ void show_trace(struct task_struct* task, unsigned long * stack)
                task = current;
 
        if (task != current) {
-               //ebp = (unsigned long) KSTK_EBP(task);
-               /* Which one? No actual difference - just coding style.*/
-               ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
+               ebp = (unsigned long) KSTK_EBP(task);
        } else {
                asm ("movl %%ebp, %0" : "=r" (ebp) : );
        }
@@ -99,15 +97,6 @@ void show_trace(struct task_struct* task, unsigned long * stack)
                ((unsigned long)stack & (~(THREAD_SIZE - 1)));
        print_context_stack(context, stack, ebp);
 
-       /*while (((long) stack & (THREAD_SIZE-1)) != 0) {
-               addr = *stack;
-               if (__kernel_text_address(addr)) {
-                       printk("%08lx:  [<%08lx>]", (unsigned long) stack, addr);
-                       print_symbol(" %s", addr);
-                       printk("\n");
-               }
-               stack++;
-       }*/
        printk("\n");
 }
 
index 2d242360c3d655b12e0494528901af2dfa945fc0..075771c371f6a40be8b1e1dc5e6a0731711d11ec 100644 (file)
@@ -13,6 +13,7 @@ struct task_struct;
 #include "linux/config.h"
 #include "asm/ptrace.h"
 #include "choose-mode.h"
+#include "registers.h"
 
 struct mm_struct;
 
@@ -136,19 +137,15 @@ extern struct cpuinfo_um cpu_data[];
 #define current_cpu_data boot_cpu_data
 #endif
 
-#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
-#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
-#define get_wchan(p) (0)
 
+#ifdef CONFIG_MODE_SKAS
+#define KSTK_REG(tsk, reg) \
+       ({ union uml_pt_regs regs; \
+          get_thread_regs(&regs, tsk->thread.mode.skas.switch_buf); \
+          UPT_REG(&regs, reg); })
+#else
+#define KSTK_REG(tsk, reg) (0xbadbabe)
 #endif
+#define get_wchan(p) (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:
- */
+#endif
index 431bad3ae9d7cf33f72ec43cdd779e58cec12bb2..4108a579eb92a531f1010a1f0dd3f7e321dbd15c 100644 (file)
@@ -43,17 +43,10 @@ static inline void rep_nop(void)
 #define ARCH_IS_STACKGROW(address) \
        (address + 32 >= UPT_SP(&current->thread.regs.regs))
 
+#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP)
+#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP)
+#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP)
+
 #include "asm/processor-generic.h"
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index 0beb9a42ae05b5cf1afe8fd45d3e914837b6ad0f..e1e1255a1d3655c18bc2aa2206eead6187170a2b 100644 (file)
@@ -36,17 +36,9 @@ extern inline void rep_nop(void)
 #define ARCH_IS_STACKGROW(address) \
         (address + 128 >= UPT_SP(&current->thread.regs.regs))
 
+#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP)
+#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP)
+
 #include "asm/processor-generic.h"
 
 #endif
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */