Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

[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
Loading
Loading
Loading
Loading
+1 −11
Original line number Original line Diff line number Diff line
@@ -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:
 */
+0 −4
Original line number Original line Diff line number Diff line
@@ -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);  \
+1 −7
Original line number Original line Diff line number Diff line
@@ -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)
	}
	}


	printk("Call Trace: \n");
	printk("Call Trace: \n");
	show_trace(current, esp);
	show_trace(task, esp);
}
}
+9 −10
Original line number Original line Diff line number Diff line
@@ -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)
	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:
 */
+9 −10
Original line number Original line Diff line number Diff line
@@ -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)
	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:
 */
Loading