Commit fad1c45c authored by Allan Graves's avatar Allan Graves Committed by Linus Torvalds

[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: default avatarAllan Graves <allan.graves@oracle.com>
Signed-off-by: default avatarJeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 71dc0362
...@@ -15,16 +15,6 @@ extern void save_registers(int pid, union uml_pt_regs *regs); ...@@ -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 restore_registers(int pid, union uml_pt_regs *regs);
extern void init_registers(int pid); extern void init_registers(int pid);
extern void get_safe_registers(unsigned long * regs); extern void get_safe_registers(unsigned long * regs);
extern void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer);
#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:
*/
...@@ -218,10 +218,6 @@ struct syscall_args { ...@@ -218,10 +218,6 @@ struct syscall_args {
case RBP: UPT_RBP(regs) = __upt_val; break; \ case RBP: UPT_RBP(regs) = __upt_val; break; \
case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
case CS: UPT_CS(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; \ case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
default : \ default : \
panic("Bad register in UPT_SET : %d\n", reg); \ panic("Bad register in UPT_SET : %d\n", reg); \
......
...@@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp) ...@@ -62,13 +62,7 @@ void show_stack(struct task_struct *task, unsigned long *esp)
if (esp == NULL) { if (esp == NULL) {
if (task != current && task != 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); esp = (unsigned long *) KSTK_ESP(task);
/* Which one? No actual difference - just coding style.*/
//esp = (unsigned long *) PT_REGS_IP(&task->thread.regs);
} else { } else {
esp = (unsigned long *) &esp; esp = (unsigned long *) &esp;
} }
...@@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp) ...@@ -84,5 +78,5 @@ void show_stack(struct task_struct *task, unsigned long *esp)
} }
printk("Call Trace: \n"); printk("Call Trace: \n");
show_trace(current, esp); show_trace(task, esp);
} }
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <setjmp.h>
#include "sysdep/ptrace_user.h" #include "sysdep/ptrace_user.h"
#include "sysdep/ptrace.h" #include "sysdep/ptrace.h"
#include "uml-config.h" #include "uml-config.h"
...@@ -126,13 +127,11 @@ void get_safe_registers(unsigned long *regs) ...@@ -126,13 +127,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
} }
/* void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
* Overrides for Emacs so that we follow Linus's tabbing style. {
* Emacs will notice this stuff at the end of the file and automatically struct __jmp_buf_tag *jmpbuf = buffer;
* adjust the settings for this buffer only. This must remain at the end
* of the file. UPT_SET(uml_regs, EIP, jmpbuf->__jmpbuf[JB_PC]);
* --------------------------------------------------------------------------- UPT_SET(uml_regs, UESP, jmpbuf->__jmpbuf[JB_SP]);
* Local variables: UPT_SET(uml_regs, EBP, jmpbuf->__jmpbuf[JB_BP]);
* c-file-style: "linux" }
* End:
*/
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#include <setjmp.h>
#include "ptrace_user.h" #include "ptrace_user.h"
#include "uml-config.h" #include "uml-config.h"
#include "skas_ptregs.h" #include "skas_ptregs.h"
...@@ -74,13 +75,11 @@ void get_safe_registers(unsigned long *regs) ...@@ -74,13 +75,11 @@ void get_safe_registers(unsigned long *regs)
memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long)); memcpy(regs, exec_regs, HOST_FRAME_SIZE * sizeof(unsigned long));
} }
/* void get_thread_regs(union uml_pt_regs *uml_regs, void *buffer)
* Overrides for Emacs so that we follow Linus's tabbing style. {
* Emacs will notice this stuff at the end of the file and automatically struct __jmp_buf_tag *jmpbuf = buffer;
* adjust the settings for this buffer only. This must remain at the end
* of the file. UPT_SET(uml_regs, RIP, jmpbuf->__jmpbuf[JB_PC]);
* --------------------------------------------------------------------------- UPT_SET(uml_regs, RSP, jmpbuf->__jmpbuf[JB_RSP]);
* Local variables: UPT_SET(uml_regs, RBP, jmpbuf->__jmpbuf[JB_RBP]);
* c-file-style: "linux" }
* End:
*/
...@@ -88,9 +88,7 @@ void show_trace(struct task_struct* task, unsigned long * stack) ...@@ -88,9 +88,7 @@ void show_trace(struct task_struct* task, unsigned long * stack)
task = current; task = current;
if (task != current) { if (task != current) {
//ebp = (unsigned long) KSTK_EBP(task); ebp = (unsigned long) KSTK_EBP(task);
/* Which one? No actual difference - just coding style.*/
ebp = (unsigned long) PT_REGS_EBP(&task->thread.regs);
} else { } else {
asm ("movl %%ebp, %0" : "=r" (ebp) : ); asm ("movl %%ebp, %0" : "=r" (ebp) : );
} }
...@@ -99,15 +97,6 @@ void show_trace(struct task_struct* task, unsigned long * stack) ...@@ -99,15 +97,6 @@ void show_trace(struct task_struct* task, unsigned long * stack)
((unsigned long)stack & (~(THREAD_SIZE - 1))); ((unsigned long)stack & (~(THREAD_SIZE - 1)));
print_context_stack(context, stack, ebp); 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"); printk("\n");
} }
...@@ -13,6 +13,7 @@ struct task_struct; ...@@ -13,6 +13,7 @@ struct task_struct;
#include "linux/config.h" #include "linux/config.h"
#include "asm/ptrace.h" #include "asm/ptrace.h"
#include "choose-mode.h" #include "choose-mode.h"
#include "registers.h"
struct mm_struct; struct mm_struct;
...@@ -136,19 +137,15 @@ extern struct cpuinfo_um cpu_data[]; ...@@ -136,19 +137,15 @@ extern struct cpuinfo_um cpu_data[];
#define current_cpu_data boot_cpu_data #define current_cpu_data boot_cpu_data
#endif #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 #endif
#define get_wchan(p) (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:
*/
...@@ -43,17 +43,10 @@ static inline void rep_nop(void) ...@@ -43,17 +43,10 @@ static inline void rep_nop(void)
#define ARCH_IS_STACKGROW(address) \ #define ARCH_IS_STACKGROW(address) \
(address + 32 >= UPT_SP(&current->thread.regs.regs)) (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" #include "asm/processor-generic.h"
#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:
*/
...@@ -36,17 +36,9 @@ extern inline void rep_nop(void) ...@@ -36,17 +36,9 @@ extern inline void rep_nop(void)
#define ARCH_IS_STACKGROW(address) \ #define ARCH_IS_STACKGROW(address) \
(address + 128 >= UPT_SP(&current->thread.regs.regs)) (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" #include "asm/processor-generic.h"
#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:
*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment