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

Commit d1254b12 authored by Jeff Dike's avatar Jeff Dike Committed by Linus Torvalds
Browse files

uml: fix x86_64 core dump crash



Stop UML crashing when trying to dump a process core on x86_64.  This is the
minimal fix to stop the crash - more things are broken here, and patches are
forthcoming.

The immediate thing to do is define ELF_CORE_COPY_REGS and
ELF_CORE_COPY_FPREGS.  Defining ELF_CORE_COPY_FPREGS allows dump_fpu to go
away.  It is defined in terms of save_fp_registers, so that needs to be added.

Signed-off-by: default avatarJeff Dike <jdike@linux.intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c7ec16da
Loading
Loading
Loading
Loading
+15 −0
Original line number Original line Diff line number Diff line
@@ -4,6 +4,7 @@
 */
 */


#include <errno.h>
#include <errno.h>
#include <sys/ptrace.h>
#include <string.h>
#include <string.h>
#include "ptrace_user.h"
#include "ptrace_user.h"
#include "uml-config.h"
#include "uml-config.h"
@@ -17,6 +18,20 @@
static unsigned long exec_regs[MAX_REG_NR];
static unsigned long exec_regs[MAX_REG_NR];
static unsigned long exec_fp_regs[HOST_FP_SIZE];
static unsigned long exec_fp_regs[HOST_FP_SIZE];


int save_fp_registers(int pid, unsigned long *fp_regs)
{
	if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
		return -errno;
	return 0;
}

int restore_fp_registers(int pid, unsigned long *fp_regs)
{
	if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
		return -errno;
	return 0;
}

void init_thread_registers(union uml_pt_regs *to)
void init_thread_registers(union uml_pt_regs *to)
{
{
	memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
	memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
+0 −6
Original line number Original line Diff line number Diff line
@@ -156,12 +156,6 @@ int is_syscall(unsigned long addr)
	return(instr == 0x050f);
	return(instr == 0x050f);
}
}


int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
{
	panic("dump_fpu");
	return(1);
}

int get_fpregs(unsigned long buf, struct task_struct *child)
int get_fpregs(unsigned long buf, struct task_struct *child)
{
{
	panic("get_fpregs");
	panic("get_fpregs");
+40 −0
Original line number Original line Diff line number Diff line
@@ -6,7 +6,9 @@
#ifndef __UM_ELF_X86_64_H
#ifndef __UM_ELF_X86_64_H
#define __UM_ELF_X86_64_H
#define __UM_ELF_X86_64_H


#include <linux/sched.h>
#include <asm/user.h>
#include <asm/user.h>
#include "skas.h"


/* x86-64 relocation types, taken from asm-x86_64/elf.h */
/* x86-64 relocation types, taken from asm-x86_64/elf.h */
#define R_X86_64_NONE		0	/* No reloc */
#define R_X86_64_NONE		0	/* No reloc */
@@ -64,6 +66,44 @@ typedef struct { } elf_fpregset_t;
	PT_REGS_R15(regs) = 0; \
	PT_REGS_R15(regs) = 0; \
} while (0)
} while (0)


#define ELF_CORE_COPY_REGS(pr_reg, regs)		\
	(pr_reg)[0] = (regs)->regs.gp[0];			\
	(pr_reg)[1] = (regs)->regs.gp[1];			\
	(pr_reg)[2] = (regs)->regs.gp[2];			\
	(pr_reg)[3] = (regs)->regs.gp[3];			\
	(pr_reg)[4] = (regs)->regs.gp[4];			\
	(pr_reg)[5] = (regs)->regs.gp[5];			\
	(pr_reg)[6] = (regs)->regs.gp[6];			\
	(pr_reg)[7] = (regs)->regs.gp[7];			\
	(pr_reg)[8] = (regs)->regs.gp[8];			\
	(pr_reg)[9] = (regs)->regs.gp[9];			\
	(pr_reg)[10] = (regs)->regs.gp[10];			\
	(pr_reg)[11] = (regs)->regs.gp[11];			\
	(pr_reg)[12] = (regs)->regs.gp[12];			\
	(pr_reg)[13] = (regs)->regs.gp[13];			\
	(pr_reg)[14] = (regs)->regs.gp[14];			\
	(pr_reg)[15] = (regs)->regs.gp[15];			\
	(pr_reg)[16] = (regs)->regs.gp[16];			\
	(pr_reg)[17] = (regs)->regs.gp[17];			\
	(pr_reg)[18] = (regs)->regs.gp[18];			\
	(pr_reg)[19] = (regs)->regs.gp[19];			\
	(pr_reg)[20] = (regs)->regs.gp[20];			\
	(pr_reg)[21] = current->thread.arch.fs;			\
	(pr_reg)[22] = 0;					\
	(pr_reg)[23] = 0;					\
	(pr_reg)[24] = 0;					\
	(pr_reg)[25] = 0;					\
	(pr_reg)[26] = 0;

static inline int elf_core_copy_fpregs(struct task_struct *t,
				       elf_fpregset_t *fpu)
{
	int cpu = current_thread->cpu;
	return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu);
}

#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu)

#ifdef TIF_IA32 /* XXX */
#ifdef TIF_IA32 /* XXX */
#error XXX, indeed
#error XXX, indeed
        clear_thread_flag(TIF_IA32);
        clear_thread_flag(TIF_IA32);