aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAllan Graves <allan.graves@oracle.com>2005-10-04 14:53:52 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-04 16:22:01 -0400
commitfad1c45c939bb246a488be1fa06f539e85b80545 (patch)
tree2a368da0e73817083caed84f4fe8085fcb654554
parent71dc036247573e377703233af289019f4aa3176e (diff)
[PATCH] uml: Fix sysrq-r support for skas mode
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>
-rw-r--r--arch/um/include/registers.h12
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h4
-rw-r--r--arch/um/kernel/sysrq.c8
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c19
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c19
-rw-r--r--arch/um/sys-i386/sysrq.c13
-rw-r--r--include/asm-um/processor-generic.h23
-rw-r--r--include/asm-um/processor-i386.h15
-rw-r--r--include/asm-um/processor-x86_64.h14
9 files changed, 38 insertions, 89 deletions
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index 0a35e6d0baa0..4892e5fcef07 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -15,16 +15,6 @@ extern void save_registers(int pid, union uml_pt_regs *regs);
15extern void restore_registers(int pid, union uml_pt_regs *regs); 15extern void restore_registers(int pid, union uml_pt_regs *regs);
16extern void init_registers(int pid); 16extern void init_registers(int pid);
17extern void get_safe_registers(unsigned long * regs); 17extern void get_safe_registers(unsigned long * regs);
18extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
18 19
19#endif 20#endif
20
21/*
22 * Overrides for Emacs so that we follow Linus's tabbing style.
23 * Emacs will notice this stuff at the end of the file and automatically
24 * adjust the settings for this buffer only. This must remain at the end
25 * of the file.
26 * ---------------------------------------------------------------------------
27 * Local variables:
28 * c-file-style: "linux"
29 * End:
30 */
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 331aa2d1f3f5..8f0656766c21 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -218,10 +218,6 @@ struct syscall_args {
218 case RBP: UPT_RBP(regs) = __upt_val; break; \ 218 case RBP: UPT_RBP(regs) = __upt_val; break; \
219 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ 219 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
220 case CS: UPT_CS(regs) = __upt_val; break; \ 220 case CS: UPT_CS(regs) = __upt_val; break; \
221 case DS: UPT_DS(regs) = __upt_val; break; \
222 case ES: UPT_ES(regs) = __upt_val; break; \
223 case FS: UPT_FS(regs) = __upt_val; break; \
224 case GS: UPT_GS(regs) = __upt_val; break; \
225 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ 221 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
226 default : \ 222 default : \
227 panic("Bad register in UPT_SET : %d\n", reg); \ 223 panic("Bad register in UPT_SET : %d\n", reg); \
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
index f80850091e79..b331e970002f 100644
--- a/arch/um/kernel/sysrq.c
+++ b/arch/um/kernel/sysrq.c
@@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
62 62
63 if (esp == NULL) { 63 if (esp == NULL) {
64 if (task != current && task != NULL) { 64 if (task != current && task != NULL) {
65 /* XXX: Isn't this bogus? I.e. isn't this the
66 * *userspace* stack of this task? If not so, use this
67 * even when task == current (as in i386).
68 */
69 esp = (unsigned long *) KSTK_ESP(task); 65 esp = (unsigned long *) KSTK_ESP(task);
70 /* Which one? No actual difference - just coding style.*/
71 //esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
72 } else { 66 } else {
73 esp = (unsigned long *) &esp; 67 esp = (unsigned long *) &esp;
74 } 68 }
@@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp)
84 } 78 }
85 79
86 printk("Call Trace: \n"); 80 printk("Call Trace: \n");
87 show_trace(current, esp); 81 show_trace(task, esp);
88} 82}
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 3125d320722c..aee4812333c6 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -5,6 +5,7 @@
5 5
6#include <errno.h> 6#include <errno.h>
7#include <string.h> 7#include <string.h>
8#include <setjmp.h>
8#include "sysdep/ptrace_user.h" 9#include "sysdep/ptrace_user.h"
9#include "sysdep/ptrace.h" 10#include "sysdep/ptrace.h"
10#include "uml-config.h" 11#include "uml-config.h"
@@ -126,13 +127,11 @@ void get_safe_registers(unsigned long *regs)
126 memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); 127 memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
127} 128}
128 129
129/* 130void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
130 * Overrides for Emacs so that we follow Linus's tabbing style. 131{
131 * Emacs will notice this stuff at the end of the file and automatically 132 struct __jmp_buf_tag *jmpbuf = buffer;
132 * adjust the settings for this buffer only. This must remain at the end 133
133 * of the file. 134 UPT_SET(uml_regs, EIP, jmpbuf->__jmpbuf[JB_PC]);
134 * --------------------------------------------------------------------------- 135 UPT_SET(uml_regs, UESP, jmpbuf->__jmpbuf[JB_SP]);
135 * Local variables: 136 UPT_SET(uml_regs, EBP, jmpbuf->__jmpbuf[JB_BP]);
136 * c-file-style: "linux" 137}
137 * End:
138 */
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 44438d15c3d6..4b638dfb52b0 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -5,6 +5,7 @@
5 5
6#include <errno.h> 6#include <errno.h>
7#include <string.h> 7#include <string.h>
8#include <setjmp.h>
8#include "ptrace_user.h" 9#include "ptrace_user.h"
9#include "uml-config.h" 10#include "uml-config.h"
10#include "skas_ptregs.h" 11#include "skas_ptregs.h"
@@ -74,13 +75,11 @@ void get_safe_registers(unsigned long *regs)
74 memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); 75 memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
75} 76}
76 77
77/* 78void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
78 * Overrides for Emacs so that we follow Linus's tabbing style. 79{
79 * Emacs will notice this stuff at the end of the file and automatically 80 struct __jmp_buf_tag *jmpbuf = buffer;
80 * adjust the settings for this buffer only. This must remain at the end 81
81 * of the file. 82 UPT_SET(uml_regs, RIP, jmpbuf->__jmpbuf[JB_PC]);
82 * --------------------------------------------------------------------------- 83 UPT_SET(uml_regs, RSP, jmpbuf->__jmpbuf[JB_RSP]);
83 * Local variables: 84 UPT_SET(uml_regs, RBP, jmpbuf->__jmpbuf[JB_RBP]);
84 * c-file-style: "linux" 85}
85 * End:
86 */
diff --git a/arch/um/sys-i386/sysrq.c b/arch/um/sys-i386/sysrq.c
index e3706d15c4f5..d5244f070539 100644
--- a/arch/um/sys-i386/sysrq.c
+++ b/arch/um/sys-i386/sysrq.c
@@ -88,9 +88,7 @@ void show_trace(struct task_struct* task, unsigned long * stack)
88 task = current; 88 task = current;
89 89
90 if (task != current) { 90 if (task != current) {
91 //ebp = (unsigned long) KSTK_EBP(task); 91 ebp = (unsigned long) KSTK_EBP(task);
92 /* Which one? No actual difference - just coding style.*/
93 ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
94 } else { 92 } else {
95 asm ("movl %%ebp, %0" : "=r" (ebp) : ); 93 asm ("movl %%ebp, %0" : "=r" (ebp) : );
96 } 94 }
@@ -99,15 +97,6 @@ void show_trace(struct task_struct* task, unsigned long * stack)
99 ((unsigned long)stack & (~(THREAD_SIZE - 1))); 97 ((unsigned long)stack & (~(THREAD_SIZE - 1)));
100 print_context_stack(context, stack, ebp); 98 print_context_stack(context, stack, ebp);
101 99
102 /*while (((long) stack & (THREAD_SIZE-1)) != 0) {
103 addr = *stack;
104 if (__kernel_text_address(addr)) {
105 printk("%08lx: [<%08lx>]", (unsigned long) stack, addr);
106 print_symbol(" %s", addr);
107 printk("\n");
108 }
109 stack++;
110 }*/
111 printk("\n"); 100 printk("\n");
112} 101}
113 102
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index 2d242360c3d6..075771c371f6 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -13,6 +13,7 @@ struct task_struct;
13#include "linux/config.h" 13#include "linux/config.h"
14#include "asm/ptrace.h" 14#include "asm/ptrace.h"
15#include "choose-mode.h" 15#include "choose-mode.h"
16#include "registers.h"
16 17
17struct mm_struct; 18struct mm_struct;
18 19
@@ -136,19 +137,15 @@ extern struct cpuinfo_um cpu_data[];
136#define current_cpu_data boot_cpu_data 137#define current_cpu_data boot_cpu_data
137#endif 138#endif
138 139
139#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs))
140#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs))
141#define get_wchan(p) (0)
142 140
141#ifdef CONFIG_MODE_SKAS
142#define KSTK_REG(tsk, reg) \
143 ({ union uml_pt_regs regs; \
144 get_thread_regs(&regs, tsk->thread.mode.skas.switch_buf); \
145 UPT_REG(&regs, reg); })
146#else
147#define KSTK_REG(tsk, reg) (0xbadbabe)
143#endif 148#endif
149#define get_wchan(p) (0)
144 150
145/* 151#endif
146 * Overrides for Emacs so that we follow Linus's tabbing style.
147 * Emacs will notice this stuff at the end of the file and automatically
148 * adjust the settings for this buffer only. This must remain at the end
149 * of the file.
150 * ---------------------------------------------------------------------------
151 * Local variables:
152 * c-file-style: "linux"
153 * End:
154 */
diff --git a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
index 431bad3ae9d7..4108a579eb92 100644
--- a/include/asm-um/processor-i386.h
+++ b/include/asm-um/processor-i386.h
@@ -43,17 +43,10 @@ static inline void rep_nop(void)
43#define ARCH_IS_STACKGROW(address) \ 43#define ARCH_IS_STACKGROW(address) \
44 (address + 32 >= UPT_SP(&current->thread.regs.regs)) 44 (address + 32 >= UPT_SP(&current->thread.regs.regs))
45 45
46#define KSTK_EIP(tsk) KSTK_REG(tsk, EIP)
47#define KSTK_ESP(tsk) KSTK_REG(tsk, UESP)
48#define KSTK_EBP(tsk) KSTK_REG(tsk, EBP)
49
46#include "asm/processor-generic.h" 50#include "asm/processor-generic.h"
47 51
48#endif 52#endif
49
50/*
51 * Overrides for Emacs so that we follow Linus's tabbing style.
52 * Emacs will notice this stuff at the end of the file and automatically
53 * adjust the settings for this buffer only. This must remain at the end
54 * of the file.
55 * ---------------------------------------------------------------------------
56 * Local variables:
57 * c-file-style: "linux"
58 * End:
59 */
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
index 0beb9a42ae05..e1e1255a1d36 100644
--- a/include/asm-um/processor-x86_64.h
+++ b/include/asm-um/processor-x86_64.h
@@ -36,17 +36,9 @@ extern inline void rep_nop(void)
36#define ARCH_IS_STACKGROW(address) \ 36#define ARCH_IS_STACKGROW(address) \
37 (address + 128 >= UPT_SP(&current->thread.regs.regs)) 37 (address + 128 >= UPT_SP(&current->thread.regs.regs))
38 38
39#define KSTK_EIP(tsk) KSTK_REG(tsk, RIP)
40#define KSTK_ESP(tsk) KSTK_REG(tsk, RSP)
41
39#include "asm/processor-generic.h" 42#include "asm/processor-generic.h"
40 43
41#endif 44#endif
42
43/*
44 * Overrides for Emacs so that we follow Linus's tabbing style.
45 * Emacs will notice this stuff at the end of the file and automatically
46 * adjust the settings for this buffer only. This must remain at the end
47 * of the file.
48 * ---------------------------------------------------------------------------
49 * Local variables:
50 * c-file-style: "linux"
51 * End:
52 */