x86: rename the struct pt_regs members for 32/64-bit consistency
We have a lot of code which differs only by the naming of specific members of structures that contain registers. In order to enable additional unifications, this patch drops the e- or r- size prefix from the register names in struct pt_regs, and drops the x- prefixes for segment registers on the 32-bit side. This patch also performs the equivalent renames in some additional places that might be candidates for unification in the future. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
53756d3722
commit
65ea5b0349
|
@ -53,7 +53,7 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump)
|
|||
/* changed the size calculations - should hopefully work better. lbt */
|
||||
dump->magic = CMAGIC;
|
||||
dump->start_code = 0;
|
||||
dump->start_stack = regs->rsp & ~(PAGE_SIZE - 1);
|
||||
dump->start_stack = regs->sp & ~(PAGE_SIZE - 1);
|
||||
dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
|
||||
dump->u_dsize = ((unsigned long)
|
||||
(current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
|
||||
|
@ -75,22 +75,22 @@ static void dump_thread32(struct pt_regs *regs, struct user32 *dump)
|
|||
dump->u_ssize = tmp >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
dump->regs.ebx = regs->rbx;
|
||||
dump->regs.ecx = regs->rcx;
|
||||
dump->regs.edx = regs->rdx;
|
||||
dump->regs.esi = regs->rsi;
|
||||
dump->regs.edi = regs->rdi;
|
||||
dump->regs.ebp = regs->rbp;
|
||||
dump->regs.eax = regs->rax;
|
||||
dump->regs.bx = regs->bx;
|
||||
dump->regs.cx = regs->cx;
|
||||
dump->regs.dx = regs->dx;
|
||||
dump->regs.si = regs->si;
|
||||
dump->regs.di = regs->di;
|
||||
dump->regs.bp = regs->bp;
|
||||
dump->regs.ax = regs->ax;
|
||||
dump->regs.ds = current->thread.ds;
|
||||
dump->regs.es = current->thread.es;
|
||||
asm("movl %%fs,%0" : "=r" (fs)); dump->regs.fs = fs;
|
||||
asm("movl %%gs,%0" : "=r" (gs)); dump->regs.gs = gs;
|
||||
dump->regs.orig_eax = regs->orig_rax;
|
||||
dump->regs.eip = regs->rip;
|
||||
dump->regs.orig_ax = regs->orig_ax;
|
||||
dump->regs.ip = regs->ip;
|
||||
dump->regs.cs = regs->cs;
|
||||
dump->regs.eflags = regs->eflags;
|
||||
dump->regs.esp = regs->rsp;
|
||||
dump->regs.flags = regs->flags;
|
||||
dump->regs.sp = regs->sp;
|
||||
dump->regs.ss = regs->ss;
|
||||
|
||||
#if 1 /* FIXME */
|
||||
|
@ -432,9 +432,9 @@ beyond_if:
|
|||
asm volatile("movl %0,%%fs" :: "r" (0)); \
|
||||
asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS));
|
||||
load_gs_index(0);
|
||||
(regs)->rip = ex.a_entry;
|
||||
(regs)->rsp = current->mm->start_stack;
|
||||
(regs)->eflags = 0x200;
|
||||
(regs)->ip = ex.a_entry;
|
||||
(regs)->sp = current->mm->start_stack;
|
||||
(regs)->flags = 0x200;
|
||||
(regs)->cs = __USER32_CS;
|
||||
(regs)->ss = __USER32_DS;
|
||||
regs->r8 = regs->r9 = regs->r10 = regs->r11 =
|
||||
|
|
|
@ -73,22 +73,22 @@ struct file;
|
|||
/* Assumes current==process to be dumped */
|
||||
#undef ELF_CORE_COPY_REGS
|
||||
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
|
||||
pr_reg[0] = regs->rbx; \
|
||||
pr_reg[1] = regs->rcx; \
|
||||
pr_reg[2] = regs->rdx; \
|
||||
pr_reg[3] = regs->rsi; \
|
||||
pr_reg[4] = regs->rdi; \
|
||||
pr_reg[5] = regs->rbp; \
|
||||
pr_reg[6] = regs->rax; \
|
||||
pr_reg[0] = regs->bx; \
|
||||
pr_reg[1] = regs->cx; \
|
||||
pr_reg[2] = regs->dx; \
|
||||
pr_reg[3] = regs->si; \
|
||||
pr_reg[4] = regs->di; \
|
||||
pr_reg[5] = regs->bp; \
|
||||
pr_reg[6] = regs->ax; \
|
||||
pr_reg[7] = _GET_SEG(ds); \
|
||||
pr_reg[8] = _GET_SEG(es); \
|
||||
pr_reg[9] = _GET_SEG(fs); \
|
||||
pr_reg[10] = _GET_SEG(gs); \
|
||||
pr_reg[11] = regs->orig_rax; \
|
||||
pr_reg[12] = regs->rip; \
|
||||
pr_reg[11] = regs->orig_ax; \
|
||||
pr_reg[12] = regs->ip; \
|
||||
pr_reg[13] = regs->cs; \
|
||||
pr_reg[14] = regs->eflags; \
|
||||
pr_reg[15] = regs->rsp; \
|
||||
pr_reg[14] = regs->flags; \
|
||||
pr_reg[15] = regs->sp; \
|
||||
pr_reg[16] = regs->ss;
|
||||
|
||||
|
||||
|
@ -205,9 +205,9 @@ do { \
|
|||
asm volatile("movl %0,%%fs" :: "r" (0)); \
|
||||
asm volatile("movl %0,%%es; movl %0,%%ds": :"r" (__USER32_DS)); \
|
||||
load_gs_index(0); \
|
||||
(regs)->rip = (new_rip); \
|
||||
(regs)->rsp = (new_rsp); \
|
||||
(regs)->eflags = 0x200; \
|
||||
(regs)->ip = (new_rip); \
|
||||
(regs)->sp = (new_rsp); \
|
||||
(regs)->flags = X86_EFLAGS_IF; \
|
||||
(regs)->cs = __USER32_CS; \
|
||||
(regs)->ss = __USER32_DS; \
|
||||
set_fs(USER_DS); \
|
||||
|
@ -233,13 +233,13 @@ extern int syscall32_setup_pages(struct linux_binprm *, int exstack);
|
|||
static void elf32_init(struct pt_regs *regs)
|
||||
{
|
||||
struct task_struct *me = current;
|
||||
regs->rdi = 0;
|
||||
regs->rsi = 0;
|
||||
regs->rdx = 0;
|
||||
regs->rcx = 0;
|
||||
regs->rax = 0;
|
||||
regs->rbx = 0;
|
||||
regs->rbp = 0;
|
||||
regs->di = 0;
|
||||
regs->si = 0;
|
||||
regs->dx = 0;
|
||||
regs->cx = 0;
|
||||
regs->ax = 0;
|
||||
regs->bx = 0;
|
||||
regs->bp = 0;
|
||||
regs->r8 = regs->r9 = regs->r10 = regs->r11 = regs->r12 =
|
||||
regs->r13 = regs->r14 = regs->r15 = 0;
|
||||
me->thread.fs = 0;
|
||||
|
|
|
@ -154,7 +154,7 @@ asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
|
|||
}
|
||||
seg = get_fs();
|
||||
set_fs(KERNEL_DS);
|
||||
ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->rsp);
|
||||
ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
|
||||
set_fs(seg);
|
||||
if (ret >= 0 && uoss_ptr) {
|
||||
if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)) ||
|
||||
|
@ -195,7 +195,7 @@ struct rt_sigframe
|
|||
#define COPY(x) { \
|
||||
unsigned int reg; \
|
||||
err |= __get_user(reg, &sc->e ##x); \
|
||||
regs->r ## x = reg; \
|
||||
regs->x = reg; \
|
||||
}
|
||||
|
||||
#define RELOAD_SEG(seg,mask) \
|
||||
|
@ -220,7 +220,7 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
|
|||
#if DEBUG_SIG
|
||||
printk(KERN_DEBUG "SIG restore_sigcontext: "
|
||||
"sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
|
||||
sc, sc->err, sc->eip, sc->cs, sc->eflags);
|
||||
sc, sc->err, sc->ip, sc->cs, sc->flags);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -249,9 +249,9 @@ static int ia32_restore_sigcontext(struct pt_regs *regs,
|
|||
regs->ss |= 3;
|
||||
|
||||
err |= __get_user(tmpflags, &sc->eflags);
|
||||
regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
|
||||
regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5);
|
||||
/* disable syscall checks */
|
||||
regs->orig_rax = -1;
|
||||
regs->orig_ax = -1;
|
||||
|
||||
err |= __get_user(tmp, &sc->fpstate);
|
||||
buf = compat_ptr(tmp);
|
||||
|
@ -279,9 +279,9 @@ badframe:
|
|||
|
||||
asmlinkage long sys32_sigreturn(struct pt_regs *regs)
|
||||
{
|
||||
struct sigframe __user *frame = (struct sigframe __user *)(regs->rsp-8);
|
||||
struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
|
||||
sigset_t set;
|
||||
unsigned int eax;
|
||||
unsigned int ax;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
@ -298,9 +298,9 @@ asmlinkage long sys32_sigreturn(struct pt_regs *regs)
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (ia32_restore_sigcontext(regs, &frame->sc, &eax))
|
||||
if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
|
||||
goto badframe;
|
||||
return eax;
|
||||
return ax;
|
||||
|
||||
badframe:
|
||||
signal_fault(regs, frame, "32bit sigreturn");
|
||||
|
@ -311,10 +311,10 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
|
|||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
sigset_t set;
|
||||
unsigned int eax;
|
||||
unsigned int ax;
|
||||
struct pt_regs tregs;
|
||||
|
||||
frame = (struct rt_sigframe __user *)(regs->rsp - 4);
|
||||
frame = (struct rt_sigframe __user *)(regs->sp - 4);
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
@ -327,14 +327,14 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
|
||||
if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
|
||||
goto badframe;
|
||||
|
||||
tregs = *regs;
|
||||
if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return eax;
|
||||
return ax;
|
||||
|
||||
badframe:
|
||||
signal_fault(regs, frame, "32bit rt sigreturn");
|
||||
|
@ -361,21 +361,21 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
|
|||
__asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
|
||||
err |= __put_user(tmp, (unsigned int __user *)&sc->es);
|
||||
|
||||
err |= __put_user((u32)regs->rdi, &sc->edi);
|
||||
err |= __put_user((u32)regs->rsi, &sc->esi);
|
||||
err |= __put_user((u32)regs->rbp, &sc->ebp);
|
||||
err |= __put_user((u32)regs->rsp, &sc->esp);
|
||||
err |= __put_user((u32)regs->rbx, &sc->ebx);
|
||||
err |= __put_user((u32)regs->rdx, &sc->edx);
|
||||
err |= __put_user((u32)regs->rcx, &sc->ecx);
|
||||
err |= __put_user((u32)regs->rax, &sc->eax);
|
||||
err |= __put_user((u32)regs->di, &sc->edi);
|
||||
err |= __put_user((u32)regs->si, &sc->esi);
|
||||
err |= __put_user((u32)regs->bp, &sc->ebp);
|
||||
err |= __put_user((u32)regs->sp, &sc->esp);
|
||||
err |= __put_user((u32)regs->bx, &sc->ebx);
|
||||
err |= __put_user((u32)regs->dx, &sc->edx);
|
||||
err |= __put_user((u32)regs->cx, &sc->ecx);
|
||||
err |= __put_user((u32)regs->ax, &sc->eax);
|
||||
err |= __put_user((u32)regs->cs, &sc->cs);
|
||||
err |= __put_user((u32)regs->ss, &sc->ss);
|
||||
err |= __put_user(current->thread.trap_no, &sc->trapno);
|
||||
err |= __put_user(current->thread.error_code, &sc->err);
|
||||
err |= __put_user((u32)regs->rip, &sc->eip);
|
||||
err |= __put_user((u32)regs->eflags, &sc->eflags);
|
||||
err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
|
||||
err |= __put_user((u32)regs->ip, &sc->eip);
|
||||
err |= __put_user((u32)regs->flags, &sc->eflags);
|
||||
err |= __put_user((u32)regs->sp, &sc->esp_at_signal);
|
||||
|
||||
tmp = save_i387_ia32(current, fpstate, regs, 0);
|
||||
if (tmp < 0)
|
||||
|
@ -400,28 +400,28 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
|
|||
static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
|
||||
size_t frame_size)
|
||||
{
|
||||
unsigned long rsp;
|
||||
unsigned long sp;
|
||||
|
||||
/* Default to using normal stack */
|
||||
rsp = regs->rsp;
|
||||
sp = regs->sp;
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if (ka->sa.sa_flags & SA_ONSTACK) {
|
||||
if (sas_ss_flags(rsp) == 0)
|
||||
rsp = current->sas_ss_sp + current->sas_ss_size;
|
||||
if (sas_ss_flags(sp) == 0)
|
||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
||||
}
|
||||
|
||||
/* This is the legacy signal stack switching. */
|
||||
else if ((regs->ss & 0xffff) != __USER_DS &&
|
||||
!(ka->sa.sa_flags & SA_RESTORER) &&
|
||||
ka->sa.sa_restorer)
|
||||
rsp = (unsigned long) ka->sa.sa_restorer;
|
||||
sp = (unsigned long) ka->sa.sa_restorer;
|
||||
|
||||
rsp -= frame_size;
|
||||
sp -= frame_size;
|
||||
/* Align the stack pointer according to the i386 ABI,
|
||||
* i.e. so that on function entry ((sp + 4) & 15) == 0. */
|
||||
rsp = ((rsp + 4) & -16ul) - 4;
|
||||
return (void __user *) rsp;
|
||||
sp = ((sp + 4) & -16ul) - 4;
|
||||
return (void __user *) sp;
|
||||
}
|
||||
|
||||
int ia32_setup_frame(int sig, struct k_sigaction *ka,
|
||||
|
@ -486,13 +486,13 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
|
|||
goto give_sigsegv;
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->rsp = (unsigned long) frame;
|
||||
regs->rip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->sp = (unsigned long) frame;
|
||||
regs->ip = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
/* Make -mregparm=3 work */
|
||||
regs->rax = sig;
|
||||
regs->rdx = 0;
|
||||
regs->rcx = 0;
|
||||
regs->ax = sig;
|
||||
regs->dx = 0;
|
||||
regs->cx = 0;
|
||||
|
||||
asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
|
||||
asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
|
||||
|
@ -501,13 +501,13 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
|
|||
regs->ss = __USER32_DS;
|
||||
|
||||
set_fs(USER_DS);
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
if (test_thread_flag(TIF_SINGLESTEP))
|
||||
ptrace_notify(SIGTRAP);
|
||||
|
||||
#if DEBUG_SIG
|
||||
printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
|
||||
current->comm, current->pid, frame, regs->rip, frame->pretcode);
|
||||
current->comm, current->pid, frame, regs->ip, frame->pretcode);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -556,7 +556,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
err |= __put_user(0, &frame->uc.uc_link);
|
||||
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
|
||||
err |= __put_user(sas_ss_flags(regs->rsp),
|
||||
err |= __put_user(sas_ss_flags(regs->sp),
|
||||
&frame->uc.uc_stack.ss_flags);
|
||||
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
|
||||
err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
|
||||
|
@ -581,18 +581,18 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
goto give_sigsegv;
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->rsp = (unsigned long) frame;
|
||||
regs->rip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->sp = (unsigned long) frame;
|
||||
regs->ip = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
/* Make -mregparm=3 work */
|
||||
regs->rax = sig;
|
||||
regs->rdx = (unsigned long) &frame->info;
|
||||
regs->rcx = (unsigned long) &frame->uc;
|
||||
regs->ax = sig;
|
||||
regs->dx = (unsigned long) &frame->info;
|
||||
regs->cx = (unsigned long) &frame->uc;
|
||||
|
||||
/* Make -mregparm=3 work */
|
||||
regs->rax = sig;
|
||||
regs->rdx = (unsigned long) &frame->info;
|
||||
regs->rcx = (unsigned long) &frame->uc;
|
||||
regs->ax = sig;
|
||||
regs->dx = (unsigned long) &frame->info;
|
||||
regs->cx = (unsigned long) &frame->uc;
|
||||
|
||||
asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
|
||||
asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
|
||||
|
@ -601,13 +601,13 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
regs->ss = __USER32_DS;
|
||||
|
||||
set_fs(USER_DS);
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
if (test_thread_flag(TIF_SINGLESTEP))
|
||||
ptrace_notify(SIGTRAP);
|
||||
|
||||
#if DEBUG_SIG
|
||||
printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
|
||||
current->comm, current->pid, frame, regs->rip, frame->pretcode);
|
||||
current->comm, current->pid, frame, regs->ip, frame->pretcode);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -73,19 +73,19 @@ static int putreg32(struct task_struct *child, unsigned regno, u32 val)
|
|||
stack[offsetof(struct pt_regs, cs)/8] = val & 0xffff;
|
||||
break;
|
||||
|
||||
R32(ebx, rbx);
|
||||
R32(ecx, rcx);
|
||||
R32(edx, rdx);
|
||||
R32(edi, rdi);
|
||||
R32(esi, rsi);
|
||||
R32(ebp, rbp);
|
||||
R32(eax, rax);
|
||||
R32(orig_eax, orig_rax);
|
||||
R32(eip, rip);
|
||||
R32(esp, rsp);
|
||||
R32(ebx, bx);
|
||||
R32(ecx, cx);
|
||||
R32(edx, dx);
|
||||
R32(edi, di);
|
||||
R32(esi, si);
|
||||
R32(ebp, bp);
|
||||
R32(eax, ax);
|
||||
R32(orig_eax, orig_ax);
|
||||
R32(eip, ip);
|
||||
R32(esp, sp);
|
||||
|
||||
case offsetof(struct user32, regs.eflags): {
|
||||
__u64 *flags = &stack[offsetof(struct pt_regs, eflags)/8];
|
||||
__u64 *flags = &stack[offsetof(struct pt_regs, flags)/8];
|
||||
|
||||
val &= FLAG_MASK;
|
||||
/*
|
||||
|
@ -145,22 +145,22 @@ static int getreg32(struct task_struct *child, unsigned regno, u32 *val)
|
|||
|
||||
R32(cs, cs);
|
||||
R32(ss, ss);
|
||||
R32(ebx, rbx);
|
||||
R32(ecx, rcx);
|
||||
R32(edx, rdx);
|
||||
R32(edi, rdi);
|
||||
R32(esi, rsi);
|
||||
R32(ebp, rbp);
|
||||
R32(eax, rax);
|
||||
R32(orig_eax, orig_rax);
|
||||
R32(eip, rip);
|
||||
R32(esp, rsp);
|
||||
R32(ebx, bx);
|
||||
R32(ecx, cx);
|
||||
R32(edx, dx);
|
||||
R32(edi, di);
|
||||
R32(esi, si);
|
||||
R32(ebp, bp);
|
||||
R32(eax, ax);
|
||||
R32(orig_eax, orig_ax);
|
||||
R32(eip, ip);
|
||||
R32(esp, sp);
|
||||
|
||||
case offsetof(struct user32, regs.eflags):
|
||||
/*
|
||||
* If the debugger set TF, hide it from the readout.
|
||||
*/
|
||||
*val = stack[offsetof(struct pt_regs, eflags)/8];
|
||||
*val = stack[offsetof(struct pt_regs, flags)/8];
|
||||
if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||
*val &= ~X86_EFLAGS_TF;
|
||||
break;
|
||||
|
|
|
@ -816,11 +816,11 @@ asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv,
|
|||
asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
void __user *parent_tid = (void __user *)regs->rdx;
|
||||
void __user *child_tid = (void __user *)regs->rdi;
|
||||
void __user *parent_tid = (void __user *)regs->dx;
|
||||
void __user *child_tid = (void __user *)regs->di;
|
||||
|
||||
if (!newsp)
|
||||
newsp = regs->rsp;
|
||||
newsp = regs->sp;
|
||||
return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
|
||||
}
|
||||
|
||||
|
|
|
@ -344,13 +344,13 @@ do_suspend_lowlevel:
|
|||
call save_processor_state
|
||||
|
||||
movq $saved_context, %rax
|
||||
movq %rsp, pt_regs_rsp(%rax)
|
||||
movq %rbp, pt_regs_rbp(%rax)
|
||||
movq %rsi, pt_regs_rsi(%rax)
|
||||
movq %rdi, pt_regs_rdi(%rax)
|
||||
movq %rbx, pt_regs_rbx(%rax)
|
||||
movq %rcx, pt_regs_rcx(%rax)
|
||||
movq %rdx, pt_regs_rdx(%rax)
|
||||
movq %rsp, pt_regs_sp(%rax)
|
||||
movq %rbp, pt_regs_bp(%rax)
|
||||
movq %rsi, pt_regs_si(%rax)
|
||||
movq %rdi, pt_regs_di(%rax)
|
||||
movq %rbx, pt_regs_bx(%rax)
|
||||
movq %rcx, pt_regs_cx(%rax)
|
||||
movq %rdx, pt_regs_dx(%rax)
|
||||
movq %r8, pt_regs_r8(%rax)
|
||||
movq %r9, pt_regs_r9(%rax)
|
||||
movq %r10, pt_regs_r10(%rax)
|
||||
|
@ -360,7 +360,7 @@ do_suspend_lowlevel:
|
|||
movq %r14, pt_regs_r14(%rax)
|
||||
movq %r15, pt_regs_r15(%rax)
|
||||
pushfq
|
||||
popq pt_regs_eflags(%rax)
|
||||
popq pt_regs_flags(%rax)
|
||||
|
||||
movq $.L97, saved_rip(%rip)
|
||||
|
||||
|
@ -391,15 +391,15 @@ do_suspend_lowlevel:
|
|||
movq %rbx, %cr2
|
||||
movq saved_context_cr0(%rax), %rbx
|
||||
movq %rbx, %cr0
|
||||
pushq pt_regs_eflags(%rax)
|
||||
pushq pt_regs_flags(%rax)
|
||||
popfq
|
||||
movq pt_regs_rsp(%rax), %rsp
|
||||
movq pt_regs_rbp(%rax), %rbp
|
||||
movq pt_regs_rsi(%rax), %rsi
|
||||
movq pt_regs_rdi(%rax), %rdi
|
||||
movq pt_regs_rbx(%rax), %rbx
|
||||
movq pt_regs_rcx(%rax), %rcx
|
||||
movq pt_regs_rdx(%rax), %rdx
|
||||
movq pt_regs_sp(%rax), %rsp
|
||||
movq pt_regs_bp(%rax), %rbp
|
||||
movq pt_regs_si(%rax), %rsi
|
||||
movq pt_regs_di(%rax), %rdi
|
||||
movq pt_regs_bx(%rax), %rbx
|
||||
movq pt_regs_cx(%rax), %rcx
|
||||
movq pt_regs_dx(%rax), %rdx
|
||||
movq pt_regs_r8(%rax), %r8
|
||||
movq pt_regs_r9(%rax), %r9
|
||||
movq pt_regs_r10(%rax), %r10
|
||||
|
|
|
@ -75,22 +75,22 @@ void foo(void)
|
|||
OFFSET(GDS_pad, Xgt_desc_struct, pad);
|
||||
BLANK();
|
||||
|
||||
OFFSET(PT_EBX, pt_regs, ebx);
|
||||
OFFSET(PT_ECX, pt_regs, ecx);
|
||||
OFFSET(PT_EDX, pt_regs, edx);
|
||||
OFFSET(PT_ESI, pt_regs, esi);
|
||||
OFFSET(PT_EDI, pt_regs, edi);
|
||||
OFFSET(PT_EBP, pt_regs, ebp);
|
||||
OFFSET(PT_EAX, pt_regs, eax);
|
||||
OFFSET(PT_DS, pt_regs, xds);
|
||||
OFFSET(PT_ES, pt_regs, xes);
|
||||
OFFSET(PT_FS, pt_regs, xfs);
|
||||
OFFSET(PT_ORIG_EAX, pt_regs, orig_eax);
|
||||
OFFSET(PT_EIP, pt_regs, eip);
|
||||
OFFSET(PT_CS, pt_regs, xcs);
|
||||
OFFSET(PT_EFLAGS, pt_regs, eflags);
|
||||
OFFSET(PT_OLDESP, pt_regs, esp);
|
||||
OFFSET(PT_OLDSS, pt_regs, xss);
|
||||
OFFSET(PT_EBX, pt_regs, bx);
|
||||
OFFSET(PT_ECX, pt_regs, cx);
|
||||
OFFSET(PT_EDX, pt_regs, dx);
|
||||
OFFSET(PT_ESI, pt_regs, si);
|
||||
OFFSET(PT_EDI, pt_regs, di);
|
||||
OFFSET(PT_EBP, pt_regs, bp);
|
||||
OFFSET(PT_EAX, pt_regs, ax);
|
||||
OFFSET(PT_DS, pt_regs, ds);
|
||||
OFFSET(PT_ES, pt_regs, es);
|
||||
OFFSET(PT_FS, pt_regs, fs);
|
||||
OFFSET(PT_ORIG_EAX, pt_regs, orig_ax);
|
||||
OFFSET(PT_EIP, pt_regs, ip);
|
||||
OFFSET(PT_CS, pt_regs, cs);
|
||||
OFFSET(PT_EFLAGS, pt_regs, flags);
|
||||
OFFSET(PT_OLDESP, pt_regs, sp);
|
||||
OFFSET(PT_OLDSS, pt_regs, ss);
|
||||
BLANK();
|
||||
|
||||
OFFSET(EXEC_DOMAIN_handler, exec_domain, handler);
|
||||
|
|
|
@ -83,14 +83,14 @@ int main(void)
|
|||
DEFINE(pbe_next, offsetof(struct pbe, next));
|
||||
BLANK();
|
||||
#define ENTRY(entry) DEFINE(pt_regs_ ## entry, offsetof(struct pt_regs, entry))
|
||||
ENTRY(rbx);
|
||||
ENTRY(rbx);
|
||||
ENTRY(rcx);
|
||||
ENTRY(rdx);
|
||||
ENTRY(rsp);
|
||||
ENTRY(rbp);
|
||||
ENTRY(rsi);
|
||||
ENTRY(rdi);
|
||||
ENTRY(bx);
|
||||
ENTRY(bx);
|
||||
ENTRY(cx);
|
||||
ENTRY(dx);
|
||||
ENTRY(sp);
|
||||
ENTRY(bp);
|
||||
ENTRY(si);
|
||||
ENTRY(di);
|
||||
ENTRY(r8);
|
||||
ENTRY(r9);
|
||||
ENTRY(r10);
|
||||
|
@ -99,7 +99,7 @@ int main(void)
|
|||
ENTRY(r13);
|
||||
ENTRY(r14);
|
||||
ENTRY(r15);
|
||||
ENTRY(eflags);
|
||||
ENTRY(flags);
|
||||
BLANK();
|
||||
#undef ENTRY
|
||||
#define ENTRY(entry) DEFINE(saved_context_ ## entry, offsetof(struct saved_context, entry))
|
||||
|
|
|
@ -634,7 +634,7 @@ void __init early_cpu_init(void)
|
|||
struct pt_regs * __devinit idle_regs(struct pt_regs *regs)
|
||||
{
|
||||
memset(regs, 0, sizeof(struct pt_regs));
|
||||
regs->xfs = __KERNEL_PERCPU;
|
||||
regs->fs = __KERNEL_PERCPU;
|
||||
return regs;
|
||||
}
|
||||
|
||||
|
|
|
@ -110,12 +110,12 @@ static void print_mce(struct mce *m)
|
|||
KERN_EMERG
|
||||
"CPU %d: Machine Check Exception: %16Lx Bank %d: %016Lx\n",
|
||||
m->cpu, m->mcgstatus, m->bank, m->status);
|
||||
if (m->rip) {
|
||||
if (m->ip) {
|
||||
printk(KERN_EMERG "RIP%s %02x:<%016Lx> ",
|
||||
!(m->mcgstatus & MCG_STATUS_EIPV) ? " !INEXACT!" : "",
|
||||
m->cs, m->rip);
|
||||
m->cs, m->ip);
|
||||
if (m->cs == __KERNEL_CS)
|
||||
print_symbol("{%s}", m->rip);
|
||||
print_symbol("{%s}", m->ip);
|
||||
printk("\n");
|
||||
}
|
||||
printk(KERN_EMERG "TSC %Lx ", m->tsc);
|
||||
|
@ -156,16 +156,16 @@ static int mce_available(struct cpuinfo_x86 *c)
|
|||
static inline void mce_get_rip(struct mce *m, struct pt_regs *regs)
|
||||
{
|
||||
if (regs && (m->mcgstatus & MCG_STATUS_RIPV)) {
|
||||
m->rip = regs->rip;
|
||||
m->ip = regs->ip;
|
||||
m->cs = regs->cs;
|
||||
} else {
|
||||
m->rip = 0;
|
||||
m->ip = 0;
|
||||
m->cs = 0;
|
||||
}
|
||||
if (rip_msr) {
|
||||
/* Assume the RIP in the MSR is exact. Is this true? */
|
||||
m->mcgstatus |= MCG_STATUS_EIPV;
|
||||
rdmsrl(rip_msr, m->rip);
|
||||
rdmsrl(rip_msr, m->ip);
|
||||
m->cs = 0;
|
||||
}
|
||||
}
|
||||
|
@ -288,7 +288,7 @@ void do_machine_check(struct pt_regs * regs, long error_code)
|
|||
* instruction which caused the MCE.
|
||||
*/
|
||||
if (m.mcgstatus & MCG_STATUS_EIPV)
|
||||
user_space = panicm.rip && (panicm.cs & 3);
|
||||
user_space = panicm.ip && (panicm.cs & 3);
|
||||
|
||||
/*
|
||||
* If we know that the error was in user space, send a
|
||||
|
|
|
@ -339,7 +339,7 @@ static irqreturn_t math_error_irq(int cpl, void *dev_id)
|
|||
outb(0,0xF0);
|
||||
if (ignore_fpu_irq || !boot_cpu_data.hard_math)
|
||||
return IRQ_NONE;
|
||||
math_error((void __user *)get_irq_regs()->eip);
|
||||
math_error((void __user *)get_irq_regs()->ip);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
|
|
|
@ -1412,7 +1412,7 @@ static void irq_complete_move(unsigned int irq)
|
|||
if (likely(!cfg->move_in_progress))
|
||||
return;
|
||||
|
||||
vector = ~get_irq_regs()->orig_rax;
|
||||
vector = ~get_irq_regs()->orig_ax;
|
||||
me = smp_processor_id();
|
||||
if ((vector == cfg->vector) && cpu_isset(me, cfg->domain)) {
|
||||
cpumask_t cleanup_mask;
|
||||
|
|
|
@ -100,7 +100,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
|||
* beyond the 0x3ff range: to get the full 65536 ports bitmapped
|
||||
* you'd need 8kB of bitmaps/process, which is a bit excessive.
|
||||
*
|
||||
* Here we just change the eflags value on the stack: we allow
|
||||
* Here we just change the flags value on the stack: we allow
|
||||
* only the super-user to do it. This depends on the stack-layout
|
||||
* on system-call entry - see also fork() and the signal handling
|
||||
* code.
|
||||
|
@ -109,8 +109,8 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
|||
asmlinkage long sys_iopl(unsigned long regsp)
|
||||
{
|
||||
volatile struct pt_regs *regs = (struct pt_regs *)®sp;
|
||||
unsigned int level = regs->ebx;
|
||||
unsigned int old = (regs->eflags >> 12) & 3;
|
||||
unsigned int level = regs->bx;
|
||||
unsigned int old = (regs->flags >> 12) & 3;
|
||||
struct thread_struct *t = ¤t->thread;
|
||||
|
||||
if (level > 3)
|
||||
|
@ -122,7 +122,7 @@ asmlinkage long sys_iopl(unsigned long regsp)
|
|||
}
|
||||
|
||||
t->iopl = level << 12;
|
||||
regs->eflags = (regs->eflags & ~X86_EFLAGS_IOPL) | t->iopl;
|
||||
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | t->iopl;
|
||||
set_iopl_mask(t->iopl);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -95,7 +95,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
|||
* beyond the 0x3ff range: to get the full 65536 ports bitmapped
|
||||
* you'd need 8kB of bitmaps/process, which is a bit excessive.
|
||||
*
|
||||
* Here we just change the eflags value on the stack: we allow
|
||||
* Here we just change the flags value on the stack: we allow
|
||||
* only the super-user to do it. This depends on the stack-layout
|
||||
* on system-call entry - see also fork() and the signal handling
|
||||
* code.
|
||||
|
@ -103,7 +103,7 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
|||
|
||||
asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
|
||||
{
|
||||
unsigned int old = (regs->eflags >> 12) & 3;
|
||||
unsigned int old = (regs->flags >> 12) & 3;
|
||||
|
||||
if (level > 3)
|
||||
return -EINVAL;
|
||||
|
@ -112,6 +112,6 @@ asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
|
|||
if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
}
|
||||
regs->eflags = (regs->eflags &~ X86_EFLAGS_IOPL) | (level << 12);
|
||||
regs->flags = (regs->flags &~ X86_EFLAGS_IOPL) | (level << 12);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -70,7 +70,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
|
|||
{
|
||||
struct pt_regs *old_regs;
|
||||
/* high bit used in ret_from_ code */
|
||||
int irq = ~regs->orig_eax;
|
||||
int irq = ~regs->orig_ax;
|
||||
struct irq_desc *desc = irq_desc + irq;
|
||||
#ifdef CONFIG_4KSTACKS
|
||||
union irq_ctx *curctx, *irqctx;
|
||||
|
@ -88,13 +88,13 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
|
|||
#ifdef CONFIG_DEBUG_STACKOVERFLOW
|
||||
/* Debugging check for stack overflow: is there less than 1KB free? */
|
||||
{
|
||||
long esp;
|
||||
long sp;
|
||||
|
||||
__asm__ __volatile__("andl %%esp,%0" :
|
||||
"=r" (esp) : "0" (THREAD_SIZE - 1));
|
||||
if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) {
|
||||
"=r" (sp) : "0" (THREAD_SIZE - 1));
|
||||
if (unlikely(sp < (sizeof(struct thread_info) + STACK_WARN))) {
|
||||
printk("do_IRQ: stack overflow: %ld\n",
|
||||
esp - sizeof(struct thread_info));
|
||||
sp - sizeof(struct thread_info));
|
||||
dump_stack();
|
||||
}
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
|
|||
* current stack (which is the irq stack already after all)
|
||||
*/
|
||||
if (curctx != irqctx) {
|
||||
int arg1, arg2, ebx;
|
||||
int arg1, arg2, bx;
|
||||
|
||||
/* build the stack frame on the IRQ stack */
|
||||
isp = (u32*) ((char*)irqctx + sizeof(*irqctx));
|
||||
|
@ -128,10 +128,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs)
|
|||
(curctx->tinfo.preempt_count & SOFTIRQ_MASK);
|
||||
|
||||
asm volatile(
|
||||
" xchgl %%ebx,%%esp \n"
|
||||
" call *%%edi \n"
|
||||
" movl %%ebx,%%esp \n"
|
||||
: "=a" (arg1), "=d" (arg2), "=b" (ebx)
|
||||
" xchgl %%ebx,%%esp \n"
|
||||
" call *%%edi \n"
|
||||
" movl %%ebx,%%esp \n"
|
||||
: "=a" (arg1), "=d" (arg2), "=b" (bx)
|
||||
: "0" (irq), "1" (desc), "2" (isp),
|
||||
"D" (desc->handle_irq)
|
||||
: "memory", "cc"
|
||||
|
|
|
@ -53,11 +53,11 @@ static inline void stack_overflow_check(struct pt_regs *regs)
|
|||
u64 curbase = (u64)task_stack_page(current);
|
||||
static unsigned long warned = -60*HZ;
|
||||
|
||||
if (regs->rsp >= curbase && regs->rsp <= curbase + THREAD_SIZE &&
|
||||
regs->rsp < curbase + sizeof(struct thread_info) + 128 &&
|
||||
if (regs->sp >= curbase && regs->sp <= curbase + THREAD_SIZE &&
|
||||
regs->sp < curbase + sizeof(struct thread_info) + 128 &&
|
||||
time_after(jiffies, warned + 60*HZ)) {
|
||||
printk("do_IRQ: %s near stack overflow (cur:%Lx,rsp:%lx)\n",
|
||||
current->comm, curbase, regs->rsp);
|
||||
printk("do_IRQ: %s near stack overflow (cur:%Lx,sp:%lx)\n",
|
||||
current->comm, curbase, regs->sp);
|
||||
show_stack(NULL,NULL);
|
||||
warned = jiffies;
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
|
|||
struct pt_regs *old_regs = set_irq_regs(regs);
|
||||
|
||||
/* high bit used in ret_from_ code */
|
||||
unsigned vector = ~regs->orig_rax;
|
||||
unsigned vector = ~regs->orig_ax;
|
||||
unsigned irq;
|
||||
|
||||
exit_idle();
|
||||
|
|
|
@ -212,7 +212,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
|
|||
{
|
||||
__get_cpu_var(current_kprobe) = p;
|
||||
kcb->kprobe_saved_eflags = kcb->kprobe_old_eflags
|
||||
= (regs->eflags & (TF_MASK | IF_MASK));
|
||||
= (regs->flags & (TF_MASK | IF_MASK));
|
||||
if (is_IF_modifier(p->opcode))
|
||||
kcb->kprobe_saved_eflags &= ~IF_MASK;
|
||||
}
|
||||
|
@ -232,20 +232,20 @@ static __always_inline void restore_btf(void)
|
|||
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
clear_btf();
|
||||
regs->eflags |= TF_MASK;
|
||||
regs->eflags &= ~IF_MASK;
|
||||
regs->flags |= TF_MASK;
|
||||
regs->flags &= ~IF_MASK;
|
||||
/*single step inline if the instruction is an int3*/
|
||||
if (p->opcode == BREAKPOINT_INSTRUCTION)
|
||||
regs->eip = (unsigned long)p->addr;
|
||||
regs->ip = (unsigned long)p->addr;
|
||||
else
|
||||
regs->eip = (unsigned long)p->ainsn.insn;
|
||||
regs->ip = (unsigned long)p->ainsn.insn;
|
||||
}
|
||||
|
||||
/* Called with kretprobe_lock held */
|
||||
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long *sara = (unsigned long *)®s->esp;
|
||||
unsigned long *sara = (unsigned long *)®s->sp;
|
||||
|
||||
ri->ret_addr = (kprobe_opcode_t *) *sara;
|
||||
|
||||
|
@ -264,7 +264,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
kprobe_opcode_t *addr;
|
||||
struct kprobe_ctlblk *kcb;
|
||||
|
||||
addr = (kprobe_opcode_t *)(regs->eip - sizeof(kprobe_opcode_t));
|
||||
addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
|
||||
|
||||
/*
|
||||
* We don't want to be preempted for the entire
|
||||
|
@ -279,8 +279,8 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
if (p) {
|
||||
if (kcb->kprobe_status == KPROBE_HIT_SS &&
|
||||
*p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->eflags |= kcb->kprobe_saved_eflags;
|
||||
regs->flags &= ~TF_MASK;
|
||||
regs->flags |= kcb->kprobe_saved_eflags;
|
||||
goto no_kprobe;
|
||||
}
|
||||
/* We have reentered the kprobe_handler(), since
|
||||
|
@ -301,7 +301,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
* another cpu right after we hit, no further
|
||||
* handling of this interrupt is appropriate
|
||||
*/
|
||||
regs->eip -= sizeof(kprobe_opcode_t);
|
||||
regs->ip -= sizeof(kprobe_opcode_t);
|
||||
ret = 1;
|
||||
goto no_kprobe;
|
||||
}
|
||||
|
@ -325,7 +325,7 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
* Back up over the (now missing) int3 and run
|
||||
* the original instruction.
|
||||
*/
|
||||
regs->eip -= sizeof(kprobe_opcode_t);
|
||||
regs->ip -= sizeof(kprobe_opcode_t);
|
||||
ret = 1;
|
||||
}
|
||||
/* Not one of ours: let kernel handle it */
|
||||
|
@ -344,7 +344,7 @@ ss_probe:
|
|||
if (p->ainsn.boostable == 1 && !p->post_handler){
|
||||
/* Boost up -- we can execute copied instructions directly */
|
||||
reset_current_kprobe();
|
||||
regs->eip = (unsigned long)p->ainsn.insn;
|
||||
regs->ip = (unsigned long)p->ainsn.insn;
|
||||
preempt_enable_no_resched();
|
||||
return 1;
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ no_kprobe:
|
|||
asm volatile ( ".global kretprobe_trampoline\n"
|
||||
"kretprobe_trampoline: \n"
|
||||
" pushf\n"
|
||||
/* skip cs, eip, orig_eax */
|
||||
/* skip cs, ip, orig_ax */
|
||||
" subl $12, %esp\n"
|
||||
" pushl %fs\n"
|
||||
" pushl %ds\n"
|
||||
|
@ -382,10 +382,10 @@ no_kprobe:
|
|||
" pushl %ebx\n"
|
||||
" movl %esp, %eax\n"
|
||||
" call trampoline_handler\n"
|
||||
/* move eflags to cs */
|
||||
/* move flags to cs */
|
||||
" movl 52(%esp), %edx\n"
|
||||
" movl %edx, 48(%esp)\n"
|
||||
/* save true return address on eflags */
|
||||
/* save true return address on flags */
|
||||
" movl %eax, 52(%esp)\n"
|
||||
" popl %ebx\n"
|
||||
" popl %ecx\n"
|
||||
|
@ -394,7 +394,7 @@ no_kprobe:
|
|||
" popl %edi\n"
|
||||
" popl %ebp\n"
|
||||
" popl %eax\n"
|
||||
/* skip eip, orig_eax, es, ds, fs */
|
||||
/* skip ip, orig_ax, es, ds, fs */
|
||||
" addl $20, %esp\n"
|
||||
" popf\n"
|
||||
" ret\n");
|
||||
|
@ -415,9 +415,9 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
|
|||
spin_lock_irqsave(&kretprobe_lock, flags);
|
||||
head = kretprobe_inst_table_head(current);
|
||||
/* fixup registers */
|
||||
regs->xcs = __KERNEL_CS | get_kernel_rpl();
|
||||
regs->eip = trampoline_address;
|
||||
regs->orig_eax = 0xffffffff;
|
||||
regs->cs = __KERNEL_CS | get_kernel_rpl();
|
||||
regs->ip = trampoline_address;
|
||||
regs->orig_ax = 0xffffffff;
|
||||
|
||||
/*
|
||||
* It is possible to have multiple instances associated with a given
|
||||
|
@ -478,11 +478,11 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
|
|||
* interrupt. We have to fix up the stack as follows:
|
||||
*
|
||||
* 0) Except in the case of absolute or indirect jump or call instructions,
|
||||
* the new eip is relative to the copied instruction. We need to make
|
||||
* the new ip is relative to the copied instruction. We need to make
|
||||
* it relative to the original instruction.
|
||||
*
|
||||
* 1) If the single-stepped instruction was pushfl, then the TF and IF
|
||||
* flags are set in the just-pushed eflags, and may need to be cleared.
|
||||
* flags are set in the just-pushed flags, and may need to be cleared.
|
||||
*
|
||||
* 2) If the single-stepped instruction was a call, the return address
|
||||
* that is atop the stack is the address following the copied instruction.
|
||||
|
@ -493,11 +493,11 @@ fastcall void *__kprobes trampoline_handler(struct pt_regs *regs)
|
|||
static void __kprobes resume_execution(struct kprobe *p,
|
||||
struct pt_regs *regs, struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
unsigned long *tos = (unsigned long *)®s->esp;
|
||||
unsigned long *tos = (unsigned long *)®s->sp;
|
||||
unsigned long copy_eip = (unsigned long)p->ainsn.insn;
|
||||
unsigned long orig_eip = (unsigned long)p->addr;
|
||||
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
switch (p->ainsn.insn[0]) {
|
||||
case 0x9c: /* pushfl */
|
||||
*tos &= ~(TF_MASK | IF_MASK);
|
||||
|
@ -508,8 +508,8 @@ static void __kprobes resume_execution(struct kprobe *p,
|
|||
case 0xca:
|
||||
case 0xcb:
|
||||
case 0xcf:
|
||||
case 0xea: /* jmp absolute -- eip is correct */
|
||||
/* eip is already adjusted, no more changes required */
|
||||
case 0xea: /* jmp absolute -- ip is correct */
|
||||
/* ip is already adjusted, no more changes required */
|
||||
p->ainsn.boostable = 1;
|
||||
goto no_change;
|
||||
case 0xe8: /* call relative - Fix return addr */
|
||||
|
@ -522,14 +522,14 @@ static void __kprobes resume_execution(struct kprobe *p,
|
|||
if ((p->ainsn.insn[1] & 0x30) == 0x10) {
|
||||
/*
|
||||
* call absolute, indirect
|
||||
* Fix return addr; eip is correct.
|
||||
* Fix return addr; ip is correct.
|
||||
* But this is not boostable
|
||||
*/
|
||||
*tos = orig_eip + (*tos - copy_eip);
|
||||
goto no_change;
|
||||
} else if (((p->ainsn.insn[1] & 0x31) == 0x20) || /* jmp near, absolute indirect */
|
||||
((p->ainsn.insn[1] & 0x31) == 0x21)) { /* jmp far, absolute indirect */
|
||||
/* eip is correct. And this is boostable */
|
||||
/* ip is correct. And this is boostable */
|
||||
p->ainsn.boostable = 1;
|
||||
goto no_change;
|
||||
}
|
||||
|
@ -538,21 +538,21 @@ static void __kprobes resume_execution(struct kprobe *p,
|
|||
}
|
||||
|
||||
if (p->ainsn.boostable == 0) {
|
||||
if ((regs->eip > copy_eip) &&
|
||||
(regs->eip - copy_eip) + 5 < MAX_INSN_SIZE) {
|
||||
if ((regs->ip > copy_eip) &&
|
||||
(regs->ip - copy_eip) + 5 < MAX_INSN_SIZE) {
|
||||
/*
|
||||
* These instructions can be executed directly if it
|
||||
* jumps back to correct address.
|
||||
*/
|
||||
set_jmp_op((void *)regs->eip,
|
||||
(void *)orig_eip + (regs->eip - copy_eip));
|
||||
set_jmp_op((void *)regs->ip,
|
||||
(void *)orig_eip + (regs->ip - copy_eip));
|
||||
p->ainsn.boostable = 1;
|
||||
} else {
|
||||
p->ainsn.boostable = -1;
|
||||
}
|
||||
}
|
||||
|
||||
regs->eip = orig_eip + (regs->eip - copy_eip);
|
||||
regs->ip = orig_eip + (regs->ip - copy_eip);
|
||||
|
||||
no_change:
|
||||
restore_btf();
|
||||
|
@ -578,8 +578,8 @@ static int __kprobes post_kprobe_handler(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
resume_execution(cur, regs, kcb);
|
||||
regs->eflags |= kcb->kprobe_saved_eflags;
|
||||
trace_hardirqs_fixup_flags(regs->eflags);
|
||||
regs->flags |= kcb->kprobe_saved_eflags;
|
||||
trace_hardirqs_fixup_flags(regs->flags);
|
||||
|
||||
/*Restore back the original saved kprobes variables and continue. */
|
||||
if (kcb->kprobe_status == KPROBE_REENTER) {
|
||||
|
@ -591,11 +591,11 @@ out:
|
|||
preempt_enable_no_resched();
|
||||
|
||||
/*
|
||||
* if somebody else is singlestepping across a probe point, eflags
|
||||
* if somebody else is singlestepping across a probe point, flags
|
||||
* will have TF set, in which case, continue the remaining processing
|
||||
* of do_debug, as if this is not a probe hit.
|
||||
*/
|
||||
if (regs->eflags & TF_MASK)
|
||||
if (regs->flags & TF_MASK)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
@ -612,12 +612,12 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
/*
|
||||
* We are here because the instruction being single
|
||||
* stepped caused a page fault. We reset the current
|
||||
* kprobe and the eip points back to the probe address
|
||||
* kprobe and the ip points back to the probe address
|
||||
* and allow the page fault handler to continue as a
|
||||
* normal page fault.
|
||||
*/
|
||||
regs->eip = (unsigned long)cur->addr;
|
||||
regs->eflags |= kcb->kprobe_old_eflags;
|
||||
regs->ip = (unsigned long)cur->addr;
|
||||
regs->flags |= kcb->kprobe_old_eflags;
|
||||
if (kcb->kprobe_status == KPROBE_REENTER)
|
||||
restore_previous_kprobe(kcb);
|
||||
else
|
||||
|
@ -703,7 +703,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
kcb->jprobe_saved_esp = ®s->esp;
|
||||
kcb->jprobe_saved_esp = ®s->sp;
|
||||
addr = (unsigned long)(kcb->jprobe_saved_esp);
|
||||
|
||||
/*
|
||||
|
@ -715,9 +715,9 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
*/
|
||||
memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
|
||||
MIN_STACK_SIZE(addr));
|
||||
regs->eflags &= ~IF_MASK;
|
||||
regs->flags &= ~IF_MASK;
|
||||
trace_hardirqs_off();
|
||||
regs->eip = (unsigned long)(jp->entry);
|
||||
regs->ip = (unsigned long)(jp->entry);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -736,15 +736,15 @@ void __kprobes jprobe_return(void)
|
|||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
u8 *addr = (u8 *) (regs->eip - 1);
|
||||
u8 *addr = (u8 *) (regs->ip - 1);
|
||||
unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_esp);
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
|
||||
if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
|
||||
if (®s->esp != kcb->jprobe_saved_esp) {
|
||||
if (®s->sp != kcb->jprobe_saved_esp) {
|
||||
struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
|
||||
printk("current esp %p does not match saved esp %p\n",
|
||||
®s->esp, kcb->jprobe_saved_esp);
|
||||
printk("current sp %p does not match saved sp %p\n",
|
||||
®s->sp, kcb->jprobe_saved_esp);
|
||||
printk("Saved registers for jprobe %p\n", jp);
|
||||
show_registers(saved_regs);
|
||||
printk("Current registers\n");
|
||||
|
|
|
@ -251,7 +251,7 @@ static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
|
|||
{
|
||||
__get_cpu_var(current_kprobe) = p;
|
||||
kcb->kprobe_saved_rflags = kcb->kprobe_old_rflags
|
||||
= (regs->eflags & (TF_MASK | IF_MASK));
|
||||
= (regs->flags & (TF_MASK | IF_MASK));
|
||||
if (is_IF_modifier(p->ainsn.insn))
|
||||
kcb->kprobe_saved_rflags &= ~IF_MASK;
|
||||
}
|
||||
|
@ -271,20 +271,20 @@ static __always_inline void restore_btf(void)
|
|||
static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
clear_btf();
|
||||
regs->eflags |= TF_MASK;
|
||||
regs->eflags &= ~IF_MASK;
|
||||
regs->flags |= TF_MASK;
|
||||
regs->flags &= ~IF_MASK;
|
||||
/*single step inline if the instruction is an int3*/
|
||||
if (p->opcode == BREAKPOINT_INSTRUCTION)
|
||||
regs->rip = (unsigned long)p->addr;
|
||||
regs->ip = (unsigned long)p->addr;
|
||||
else
|
||||
regs->rip = (unsigned long)p->ainsn.insn;
|
||||
regs->ip = (unsigned long)p->ainsn.insn;
|
||||
}
|
||||
|
||||
/* Called with kretprobe_lock held */
|
||||
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
unsigned long *sara = (unsigned long *)regs->rsp;
|
||||
unsigned long *sara = (unsigned long *)regs->sp;
|
||||
|
||||
ri->ret_addr = (kprobe_opcode_t *) *sara;
|
||||
/* Replace the return addr with trampoline addr */
|
||||
|
@ -295,7 +295,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
{
|
||||
struct kprobe *p;
|
||||
int ret = 0;
|
||||
kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t));
|
||||
kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->ip - sizeof(kprobe_opcode_t));
|
||||
struct kprobe_ctlblk *kcb;
|
||||
|
||||
/*
|
||||
|
@ -311,8 +311,8 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
if (p) {
|
||||
if (kcb->kprobe_status == KPROBE_HIT_SS &&
|
||||
*p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->eflags |= kcb->kprobe_saved_rflags;
|
||||
regs->flags &= ~TF_MASK;
|
||||
regs->flags |= kcb->kprobe_saved_rflags;
|
||||
goto no_kprobe;
|
||||
} else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) {
|
||||
/* TODO: Provide re-entrancy from
|
||||
|
@ -321,7 +321,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
* the instruction of the new probe.
|
||||
*/
|
||||
arch_disarm_kprobe(p);
|
||||
regs->rip = (unsigned long)p->addr;
|
||||
regs->ip = (unsigned long)p->addr;
|
||||
reset_current_kprobe();
|
||||
ret = 1;
|
||||
} else {
|
||||
|
@ -345,7 +345,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
* another cpu right after we hit, no further
|
||||
* handling of this interrupt is appropriate
|
||||
*/
|
||||
regs->rip = (unsigned long)addr;
|
||||
regs->ip = (unsigned long)addr;
|
||||
ret = 1;
|
||||
goto no_kprobe;
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs)
|
|||
* Back up over the (now missing) int3 and run
|
||||
* the original instruction.
|
||||
*/
|
||||
regs->rip = (unsigned long)addr;
|
||||
regs->ip = (unsigned long)addr;
|
||||
ret = 1;
|
||||
}
|
||||
/* Not one of ours: let kernel handle it */
|
||||
|
@ -454,7 +454,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
}
|
||||
|
||||
kretprobe_assert(ri, orig_ret_address, trampoline_address);
|
||||
regs->rip = orig_ret_address;
|
||||
regs->ip = orig_ret_address;
|
||||
|
||||
reset_current_kprobe();
|
||||
spin_unlock_irqrestore(&kretprobe_lock, flags);
|
||||
|
@ -484,11 +484,11 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
* interrupt. We have to fix up the stack as follows:
|
||||
*
|
||||
* 0) Except in the case of absolute or indirect jump or call instructions,
|
||||
* the new rip is relative to the copied instruction. We need to make
|
||||
* the new ip is relative to the copied instruction. We need to make
|
||||
* it relative to the original instruction.
|
||||
*
|
||||
* 1) If the single-stepped instruction was pushfl, then the TF and IF
|
||||
* flags are set in the just-pushed eflags, and may need to be cleared.
|
||||
* flags are set in the just-pushed flags, and may need to be cleared.
|
||||
*
|
||||
* 2) If the single-stepped instruction was a call, the return address
|
||||
* that is atop the stack is the address following the copied instruction.
|
||||
|
@ -497,7 +497,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
static void __kprobes resume_execution(struct kprobe *p,
|
||||
struct pt_regs *regs, struct kprobe_ctlblk *kcb)
|
||||
{
|
||||
unsigned long *tos = (unsigned long *)regs->rsp;
|
||||
unsigned long *tos = (unsigned long *)regs->sp;
|
||||
unsigned long copy_rip = (unsigned long)p->ainsn.insn;
|
||||
unsigned long orig_rip = (unsigned long)p->addr;
|
||||
kprobe_opcode_t *insn = p->ainsn.insn;
|
||||
|
@ -506,7 +506,7 @@ static void __kprobes resume_execution(struct kprobe *p,
|
|||
if (*insn >= 0x40 && *insn <= 0x4f)
|
||||
insn++;
|
||||
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
switch (*insn) {
|
||||
case 0x9c: /* pushfl */
|
||||
*tos &= ~(TF_MASK | IF_MASK);
|
||||
|
@ -538,7 +538,8 @@ static void __kprobes resume_execution(struct kprobe *p,
|
|||
break;
|
||||
}
|
||||
|
||||
regs->rip = orig_rip + (regs->rip - copy_rip);
|
||||
regs->ip = orig_rip + (regs->ip - copy_rip);
|
||||
|
||||
no_change:
|
||||
restore_btf();
|
||||
|
||||
|
@ -559,8 +560,8 @@ int __kprobes post_kprobe_handler(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
resume_execution(cur, regs, kcb);
|
||||
regs->eflags |= kcb->kprobe_saved_rflags;
|
||||
trace_hardirqs_fixup_flags(regs->eflags);
|
||||
regs->flags |= kcb->kprobe_saved_rflags;
|
||||
trace_hardirqs_fixup_flags(regs->flags);
|
||||
|
||||
/* Restore the original saved kprobes variables and continue. */
|
||||
if (kcb->kprobe_status == KPROBE_REENTER) {
|
||||
|
@ -572,11 +573,11 @@ out:
|
|||
preempt_enable_no_resched();
|
||||
|
||||
/*
|
||||
* if somebody else is singlestepping across a probe point, eflags
|
||||
* if somebody else is singlestepping across a probe point, flags
|
||||
* will have TF set, in which case, continue the remaining processing
|
||||
* of do_debug, as if this is not a probe hit.
|
||||
*/
|
||||
if (regs->eflags & TF_MASK)
|
||||
if (regs->flags & TF_MASK)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
|
@ -594,12 +595,12 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
/*
|
||||
* We are here because the instruction being single
|
||||
* stepped caused a page fault. We reset the current
|
||||
* kprobe and the rip points back to the probe address
|
||||
* kprobe and the ip points back to the probe address
|
||||
* and allow the page fault handler to continue as a
|
||||
* normal page fault.
|
||||
*/
|
||||
regs->rip = (unsigned long)cur->addr;
|
||||
regs->eflags |= kcb->kprobe_old_rflags;
|
||||
regs->ip = (unsigned long)cur->addr;
|
||||
regs->flags |= kcb->kprobe_old_rflags;
|
||||
if (kcb->kprobe_status == KPROBE_REENTER)
|
||||
restore_previous_kprobe(kcb);
|
||||
else
|
||||
|
@ -629,9 +630,9 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
|
|||
* In case the user-specified fault handler returned
|
||||
* zero, try to fix up.
|
||||
*/
|
||||
fixup = search_exception_tables(regs->rip);
|
||||
fixup = search_exception_tables(regs->ip);
|
||||
if (fixup) {
|
||||
regs->rip = fixup->fixup;
|
||||
regs->ip = fixup->fixup;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -688,7 +689,7 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
|
||||
kcb->jprobe_saved_regs = *regs;
|
||||
kcb->jprobe_saved_rsp = (long *) regs->rsp;
|
||||
kcb->jprobe_saved_rsp = (long *) regs->sp;
|
||||
addr = (unsigned long)(kcb->jprobe_saved_rsp);
|
||||
/*
|
||||
* As Linus pointed out, gcc assumes that the callee
|
||||
|
@ -699,9 +700,9 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
|
|||
*/
|
||||
memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
|
||||
MIN_STACK_SIZE(addr));
|
||||
regs->eflags &= ~IF_MASK;
|
||||
regs->flags &= ~IF_MASK;
|
||||
trace_hardirqs_off();
|
||||
regs->rip = (unsigned long)(jp->entry);
|
||||
regs->ip = (unsigned long)(jp->entry);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -720,15 +721,15 @@ void __kprobes jprobe_return(void)
|
|||
int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
|
||||
{
|
||||
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
|
||||
u8 *addr = (u8 *) (regs->rip - 1);
|
||||
u8 *addr = (u8 *) (regs->ip - 1);
|
||||
unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_rsp);
|
||||
struct jprobe *jp = container_of(p, struct jprobe, kp);
|
||||
|
||||
if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) {
|
||||
if ((unsigned long *)regs->rsp != kcb->jprobe_saved_rsp) {
|
||||
if ((unsigned long *)regs->sp != kcb->jprobe_saved_rsp) {
|
||||
struct pt_regs *saved_regs = &kcb->jprobe_saved_regs;
|
||||
printk("current rsp %p does not match saved rsp %p\n",
|
||||
(long *)regs->rsp, kcb->jprobe_saved_rsp);
|
||||
printk("current sp %p does not match saved sp %p\n",
|
||||
(long *)regs->sp, kcb->jprobe_saved_rsp);
|
||||
printk("Saved registers for jprobe %p\n", jp);
|
||||
show_registers(saved_regs);
|
||||
printk("Current registers\n");
|
||||
|
|
|
@ -265,13 +265,13 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait);
|
|||
* New with Core Duo processors, MWAIT can take some hints based on CPU
|
||||
* capability.
|
||||
*/
|
||||
void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
|
||||
void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
|
||||
{
|
||||
if (!need_resched()) {
|
||||
__monitor((void *)¤t_thread_info()->flags, 0, 0);
|
||||
smp_mb();
|
||||
if (!need_resched())
|
||||
__mwait(eax, ecx);
|
||||
__mwait(ax, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,15 +320,15 @@ void __show_registers(struct pt_regs *regs, int all)
|
|||
{
|
||||
unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L;
|
||||
unsigned long d0, d1, d2, d3, d6, d7;
|
||||
unsigned long esp;
|
||||
unsigned long sp;
|
||||
unsigned short ss, gs;
|
||||
|
||||
if (user_mode_vm(regs)) {
|
||||
esp = regs->esp;
|
||||
ss = regs->xss & 0xffff;
|
||||
sp = regs->sp;
|
||||
ss = regs->ss & 0xffff;
|
||||
savesegment(gs, gs);
|
||||
} else {
|
||||
esp = (unsigned long) (®s->esp);
|
||||
sp = (unsigned long) (®s->sp);
|
||||
savesegment(ss, ss);
|
||||
savesegment(gs, gs);
|
||||
}
|
||||
|
@ -341,17 +341,17 @@ void __show_registers(struct pt_regs *regs, int all)
|
|||
init_utsname()->version);
|
||||
|
||||
printk("EIP: %04x:[<%08lx>] EFLAGS: %08lx CPU: %d\n",
|
||||
0xffff & regs->xcs, regs->eip, regs->eflags,
|
||||
0xffff & regs->cs, regs->ip, regs->flags,
|
||||
smp_processor_id());
|
||||
print_symbol("EIP is at %s\n", regs->eip);
|
||||
print_symbol("EIP is at %s\n", regs->ip);
|
||||
|
||||
printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n",
|
||||
regs->eax, regs->ebx, regs->ecx, regs->edx);
|
||||
regs->ax, regs->bx, regs->cx, regs->dx);
|
||||
printk("ESI: %08lx EDI: %08lx EBP: %08lx ESP: %08lx\n",
|
||||
regs->esi, regs->edi, regs->ebp, esp);
|
||||
regs->si, regs->di, regs->bp, sp);
|
||||
printk(" DS: %04x ES: %04x FS: %04x GS: %04x SS: %04x\n",
|
||||
regs->xds & 0xffff, regs->xes & 0xffff,
|
||||
regs->xfs & 0xffff, gs, ss);
|
||||
regs->ds & 0xffff, regs->es & 0xffff,
|
||||
regs->fs & 0xffff, gs, ss);
|
||||
|
||||
if (!all)
|
||||
return;
|
||||
|
@ -379,12 +379,12 @@ void __show_registers(struct pt_regs *regs, int all)
|
|||
void show_regs(struct pt_regs *regs)
|
||||
{
|
||||
__show_registers(regs, 1);
|
||||
show_trace(NULL, regs, ®s->esp);
|
||||
show_trace(NULL, regs, ®s->sp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets run with %ebx containing the
|
||||
* function to call, and %edx containing
|
||||
* This gets run with %bx containing the
|
||||
* function to call, and %dx containing
|
||||
* the "args".
|
||||
*/
|
||||
extern void kernel_thread_helper(void);
|
||||
|
@ -398,16 +398,16 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
|
|||
|
||||
memset(®s, 0, sizeof(regs));
|
||||
|
||||
regs.ebx = (unsigned long) fn;
|
||||
regs.edx = (unsigned long) arg;
|
||||
regs.bx = (unsigned long) fn;
|
||||
regs.dx = (unsigned long) arg;
|
||||
|
||||
regs.xds = __USER_DS;
|
||||
regs.xes = __USER_DS;
|
||||
regs.xfs = __KERNEL_PERCPU;
|
||||
regs.orig_eax = -1;
|
||||
regs.eip = (unsigned long) kernel_thread_helper;
|
||||
regs.xcs = __KERNEL_CS | get_kernel_rpl();
|
||||
regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
|
||||
regs.ds = __USER_DS;
|
||||
regs.es = __USER_DS;
|
||||
regs.fs = __KERNEL_PERCPU;
|
||||
regs.orig_ax = -1;
|
||||
regs.ip = (unsigned long) kernel_thread_helper;
|
||||
regs.cs = __KERNEL_CS | get_kernel_rpl();
|
||||
regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2;
|
||||
|
||||
/* Ok, create the new process.. */
|
||||
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL);
|
||||
|
@ -470,7 +470,7 @@ void prepare_to_copy(struct task_struct *tsk)
|
|||
unlazy_fpu(tsk);
|
||||
}
|
||||
|
||||
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
|
||||
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
|
||||
unsigned long unused,
|
||||
struct task_struct * p, struct pt_regs * regs)
|
||||
{
|
||||
|
@ -480,8 +480,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
|
|||
|
||||
childregs = task_pt_regs(p);
|
||||
*childregs = *regs;
|
||||
childregs->eax = 0;
|
||||
childregs->esp = esp;
|
||||
childregs->ax = 0;
|
||||
childregs->sp = sp;
|
||||
|
||||
p->thread.esp = (unsigned long) childregs;
|
||||
p->thread.esp0 = (unsigned long) (childregs+1);
|
||||
|
@ -508,7 +508,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
|
|||
*/
|
||||
if (clone_flags & CLONE_SETTLS)
|
||||
err = do_set_thread_area(p, -1,
|
||||
(struct user_desc __user *)childregs->esi, 0);
|
||||
(struct user_desc __user *)childregs->si, 0);
|
||||
|
||||
if (err && p->thread.io_bitmap_ptr) {
|
||||
kfree(p->thread.io_bitmap_ptr);
|
||||
|
@ -527,7 +527,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
|
|||
/* changed the size calculations - should hopefully work better. lbt */
|
||||
dump->magic = CMAGIC;
|
||||
dump->start_code = 0;
|
||||
dump->start_stack = regs->esp & ~(PAGE_SIZE - 1);
|
||||
dump->start_stack = regs->sp & ~(PAGE_SIZE - 1);
|
||||
dump->u_tsize = ((unsigned long) current->mm->end_code) >> PAGE_SHIFT;
|
||||
dump->u_dsize = ((unsigned long) (current->mm->brk + (PAGE_SIZE-1))) >> PAGE_SHIFT;
|
||||
dump->u_dsize -= dump->u_tsize;
|
||||
|
@ -538,23 +538,23 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
|
|||
if (dump->start_stack < TASK_SIZE)
|
||||
dump->u_ssize = ((unsigned long) (TASK_SIZE - dump->start_stack)) >> PAGE_SHIFT;
|
||||
|
||||
dump->regs.ebx = regs->ebx;
|
||||
dump->regs.ecx = regs->ecx;
|
||||
dump->regs.edx = regs->edx;
|
||||
dump->regs.esi = regs->esi;
|
||||
dump->regs.edi = regs->edi;
|
||||
dump->regs.ebp = regs->ebp;
|
||||
dump->regs.eax = regs->eax;
|
||||
dump->regs.ds = regs->xds;
|
||||
dump->regs.es = regs->xes;
|
||||
dump->regs.fs = regs->xfs;
|
||||
dump->regs.ebx = regs->bx;
|
||||
dump->regs.ecx = regs->cx;
|
||||
dump->regs.edx = regs->dx;
|
||||
dump->regs.esi = regs->si;
|
||||
dump->regs.edi = regs->di;
|
||||
dump->regs.ebp = regs->bp;
|
||||
dump->regs.eax = regs->ax;
|
||||
dump->regs.ds = regs->ds;
|
||||
dump->regs.es = regs->es;
|
||||
dump->regs.fs = regs->fs;
|
||||
savesegment(gs,dump->regs.gs);
|
||||
dump->regs.orig_eax = regs->orig_eax;
|
||||
dump->regs.eip = regs->eip;
|
||||
dump->regs.cs = regs->xcs;
|
||||
dump->regs.eflags = regs->eflags;
|
||||
dump->regs.esp = regs->esp;
|
||||
dump->regs.ss = regs->xss;
|
||||
dump->regs.orig_eax = regs->orig_ax;
|
||||
dump->regs.eip = regs->ip;
|
||||
dump->regs.cs = regs->cs;
|
||||
dump->regs.eflags = regs->flags;
|
||||
dump->regs.esp = regs->sp;
|
||||
dump->regs.ss = regs->ss;
|
||||
|
||||
dump->u_fpvalid = dump_fpu (regs, &dump->i387);
|
||||
}
|
||||
|
@ -566,10 +566,10 @@ EXPORT_SYMBOL(dump_thread);
|
|||
int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs)
|
||||
{
|
||||
struct pt_regs ptregs = *task_pt_regs(tsk);
|
||||
ptregs.xcs &= 0xffff;
|
||||
ptregs.xds &= 0xffff;
|
||||
ptregs.xes &= 0xffff;
|
||||
ptregs.xss &= 0xffff;
|
||||
ptregs.cs &= 0xffff;
|
||||
ptregs.ds &= 0xffff;
|
||||
ptregs.es &= 0xffff;
|
||||
ptregs.ss &= 0xffff;
|
||||
|
||||
elf_core_copy_regs(regs, &ptregs);
|
||||
|
||||
|
@ -684,7 +684,7 @@ __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p,
|
|||
* More important, however, is the fact that this allows us much
|
||||
* more flexibility.
|
||||
*
|
||||
* The return value (in %eax) will be the "prev" task after
|
||||
* The return value (in %ax) will be the "prev" task after
|
||||
* the task-switch, and shows up in ret_from_fork in entry.S,
|
||||
* for example.
|
||||
*/
|
||||
|
@ -771,7 +771,7 @@ struct task_struct fastcall * __switch_to(struct task_struct *prev_p, struct tas
|
|||
|
||||
asmlinkage int sys_fork(struct pt_regs regs)
|
||||
{
|
||||
return do_fork(SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
|
||||
return do_fork(SIGCHLD, regs.sp, ®s, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
asmlinkage int sys_clone(struct pt_regs regs)
|
||||
|
@ -780,12 +780,12 @@ asmlinkage int sys_clone(struct pt_regs regs)
|
|||
unsigned long newsp;
|
||||
int __user *parent_tidptr, *child_tidptr;
|
||||
|
||||
clone_flags = regs.ebx;
|
||||
newsp = regs.ecx;
|
||||
parent_tidptr = (int __user *)regs.edx;
|
||||
child_tidptr = (int __user *)regs.edi;
|
||||
clone_flags = regs.bx;
|
||||
newsp = regs.cx;
|
||||
parent_tidptr = (int __user *)regs.dx;
|
||||
child_tidptr = (int __user *)regs.di;
|
||||
if (!newsp)
|
||||
newsp = regs.esp;
|
||||
newsp = regs.sp;
|
||||
return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr);
|
||||
}
|
||||
|
||||
|
@ -801,7 +801,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
|
|||
*/
|
||||
asmlinkage int sys_vfork(struct pt_regs regs)
|
||||
{
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, 0, NULL, NULL);
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, ®s, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -812,13 +812,13 @@ asmlinkage int sys_execve(struct pt_regs regs)
|
|||
int error;
|
||||
char * filename;
|
||||
|
||||
filename = getname((char __user *) regs.ebx);
|
||||
filename = getname((char __user *) regs.bx);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
error = do_execve(filename,
|
||||
(char __user * __user *) regs.ecx,
|
||||
(char __user * __user *) regs.edx,
|
||||
(char __user * __user *) regs.cx,
|
||||
(char __user * __user *) regs.dx,
|
||||
®s);
|
||||
if (error == 0) {
|
||||
/* Make sure we don't return using sysenter.. */
|
||||
|
@ -834,24 +834,24 @@ out:
|
|||
|
||||
unsigned long get_wchan(struct task_struct *p)
|
||||
{
|
||||
unsigned long ebp, esp, eip;
|
||||
unsigned long bp, sp, ip;
|
||||
unsigned long stack_page;
|
||||
int count = 0;
|
||||
if (!p || p == current || p->state == TASK_RUNNING)
|
||||
return 0;
|
||||
stack_page = (unsigned long)task_stack_page(p);
|
||||
esp = p->thread.esp;
|
||||
if (!stack_page || esp < stack_page || esp > top_esp+stack_page)
|
||||
sp = p->thread.esp;
|
||||
if (!stack_page || sp < stack_page || sp > top_esp+stack_page)
|
||||
return 0;
|
||||
/* include/asm-i386/system.h:switch_to() pushes ebp last. */
|
||||
ebp = *(unsigned long *) esp;
|
||||
/* include/asm-i386/system.h:switch_to() pushes bp last. */
|
||||
bp = *(unsigned long *) sp;
|
||||
do {
|
||||
if (ebp < stack_page || ebp > top_ebp+stack_page)
|
||||
if (bp < stack_page || bp > top_ebp+stack_page)
|
||||
return 0;
|
||||
eip = *(unsigned long *) (ebp+4);
|
||||
if (!in_sched_functions(eip))
|
||||
return eip;
|
||||
ebp = *(unsigned long *) ebp;
|
||||
ip = *(unsigned long *) (bp+4);
|
||||
if (!in_sched_functions(ip))
|
||||
return ip;
|
||||
bp = *(unsigned long *) bp;
|
||||
} while (count++ < 16);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -257,13 +257,13 @@ void cpu_idle(void)
|
|||
* New with Core Duo processors, MWAIT can take some hints based on CPU
|
||||
* capability.
|
||||
*/
|
||||
void mwait_idle_with_hints(unsigned long eax, unsigned long ecx)
|
||||
void mwait_idle_with_hints(unsigned long ax, unsigned long cx)
|
||||
{
|
||||
if (!need_resched()) {
|
||||
__monitor((void *)¤t_thread_info()->flags, 0, 0);
|
||||
smp_mb();
|
||||
if (!need_resched())
|
||||
__mwait(eax, ecx);
|
||||
__mwait(ax, cx);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -330,16 +330,16 @@ void __show_regs(struct pt_regs * regs)
|
|||
init_utsname()->release,
|
||||
(int)strcspn(init_utsname()->version, " "),
|
||||
init_utsname()->version);
|
||||
printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
|
||||
printk_address(regs->rip);
|
||||
printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->rsp,
|
||||
regs->eflags);
|
||||
printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->ip);
|
||||
printk_address(regs->ip);
|
||||
printk("RSP: %04lx:%016lx EFLAGS: %08lx\n", regs->ss, regs->sp,
|
||||
regs->flags);
|
||||
printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
|
||||
regs->rax, regs->rbx, regs->rcx);
|
||||
regs->ax, regs->bx, regs->cx);
|
||||
printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
|
||||
regs->rdx, regs->rsi, regs->rdi);
|
||||
regs->dx, regs->si, regs->di);
|
||||
printk("RBP: %016lx R08: %016lx R09: %016lx\n",
|
||||
regs->rbp, regs->r8, regs->r9);
|
||||
regs->bp, regs->r8, regs->r9);
|
||||
printk("R10: %016lx R11: %016lx R12: %016lx\n",
|
||||
regs->r10, regs->r11, regs->r12);
|
||||
printk("R13: %016lx R14: %016lx R15: %016lx\n",
|
||||
|
@ -476,7 +476,7 @@ void prepare_to_copy(struct task_struct *tsk)
|
|||
unlazy_fpu(tsk);
|
||||
}
|
||||
|
||||
int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
|
||||
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
|
||||
unsigned long unused,
|
||||
struct task_struct * p, struct pt_regs * regs)
|
||||
{
|
||||
|
@ -488,10 +488,10 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
|
|||
(THREAD_SIZE + task_stack_page(p))) - 1;
|
||||
*childregs = *regs;
|
||||
|
||||
childregs->rax = 0;
|
||||
childregs->rsp = rsp;
|
||||
if (rsp == ~0UL)
|
||||
childregs->rsp = (unsigned long)childregs;
|
||||
childregs->ax = 0;
|
||||
childregs->sp = sp;
|
||||
if (sp == ~0UL)
|
||||
childregs->sp = (unsigned long)childregs;
|
||||
|
||||
p->thread.rsp = (unsigned long) childregs;
|
||||
p->thread.rsp0 = (unsigned long) (childregs+1);
|
||||
|
@ -525,7 +525,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long rsp,
|
|||
#ifdef CONFIG_IA32_EMULATION
|
||||
if (test_thread_flag(TIF_IA32))
|
||||
err = do_set_thread_area(p, -1,
|
||||
(struct user_desc __user *)childregs->rsi, 0);
|
||||
(struct user_desc __user *)childregs->si, 0);
|
||||
else
|
||||
#endif
|
||||
err = do_arch_prctl(p, ARCH_SET_FS, childregs->r8);
|
||||
|
@ -732,7 +732,7 @@ void set_personality_64bit(void)
|
|||
|
||||
asmlinkage long sys_fork(struct pt_regs *regs)
|
||||
{
|
||||
return do_fork(SIGCHLD, regs->rsp, regs, 0, NULL, NULL);
|
||||
return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
asmlinkage long
|
||||
|
@ -740,7 +740,7 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
|
|||
void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
|
||||
{
|
||||
if (!newsp)
|
||||
newsp = regs->rsp;
|
||||
newsp = regs->sp;
|
||||
return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
|
||||
}
|
||||
|
||||
|
@ -756,14 +756,14 @@ sys_clone(unsigned long clone_flags, unsigned long newsp,
|
|||
*/
|
||||
asmlinkage long sys_vfork(struct pt_regs *regs)
|
||||
{
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->rsp, regs, 0,
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0,
|
||||
NULL, NULL);
|
||||
}
|
||||
|
||||
unsigned long get_wchan(struct task_struct *p)
|
||||
{
|
||||
unsigned long stack;
|
||||
u64 fp,rip;
|
||||
u64 fp,ip;
|
||||
int count = 0;
|
||||
|
||||
if (!p || p == current || p->state==TASK_RUNNING)
|
||||
|
@ -776,9 +776,9 @@ unsigned long get_wchan(struct task_struct *p)
|
|||
if (fp < (unsigned long)stack ||
|
||||
fp > (unsigned long)stack+THREAD_SIZE)
|
||||
return 0;
|
||||
rip = *(u64 *)(fp+8);
|
||||
if (!in_sched_functions(rip))
|
||||
return rip;
|
||||
ip = *(u64 *)(fp+8);
|
||||
if (!in_sched_functions(ip))
|
||||
return ip;
|
||||
fp = *(u64 *)fp;
|
||||
} while (count++ < 16);
|
||||
return 0;
|
||||
|
|
|
@ -39,10 +39,10 @@
|
|||
|
||||
static long *pt_regs_access(struct pt_regs *regs, unsigned long regno)
|
||||
{
|
||||
BUILD_BUG_ON(offsetof(struct pt_regs, ebx) != 0);
|
||||
BUILD_BUG_ON(offsetof(struct pt_regs, bx) != 0);
|
||||
if (regno > FS)
|
||||
--regno;
|
||||
return ®s->ebx + regno;
|
||||
return ®s->bx + regno;
|
||||
}
|
||||
|
||||
static int putreg(struct task_struct *child,
|
||||
|
@ -80,7 +80,7 @@ static int putreg(struct task_struct *child,
|
|||
clear_tsk_thread_flag(child, TIF_FORCED_TF);
|
||||
else if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||
value |= X86_EFLAGS_TF;
|
||||
value |= regs->eflags & ~FLAG_MASK;
|
||||
value |= regs->flags & ~FLAG_MASK;
|
||||
break;
|
||||
}
|
||||
*pt_regs_access(regs, regno) = value;
|
||||
|
@ -98,7 +98,7 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
|
|||
/*
|
||||
* If the debugger set TF, hide it from the readout.
|
||||
*/
|
||||
retval = regs->eflags;
|
||||
retval = regs->flags;
|
||||
if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||
retval &= ~X86_EFLAGS_TF;
|
||||
break;
|
||||
|
@ -369,8 +369,8 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
|
|||
info.si_signo = SIGTRAP;
|
||||
info.si_code = TRAP_BRKPT;
|
||||
|
||||
/* User-mode eip? */
|
||||
info.si_addr = user_mode_vm(regs) ? (void __user *) regs->eip : NULL;
|
||||
/* User-mode ip? */
|
||||
info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
|
||||
|
||||
/* Send us the fake SIGTRAP */
|
||||
force_sig_info(SIGTRAP, &info, tsk);
|
||||
|
@ -392,12 +392,12 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
|
|||
|
||||
/* do the secure computing check first */
|
||||
if (!entryexit)
|
||||
secure_computing(regs->orig_eax);
|
||||
secure_computing(regs->orig_ax);
|
||||
|
||||
if (unlikely(current->audit_context)) {
|
||||
if (entryexit)
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->eax),
|
||||
regs->eax);
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->ax),
|
||||
regs->ax);
|
||||
/* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
|
||||
* on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
|
||||
* not used, entry.S will call us only on syscall exit, not
|
||||
|
@ -445,13 +445,13 @@ int do_syscall_trace(struct pt_regs *regs, int entryexit)
|
|||
ret = is_sysemu;
|
||||
out:
|
||||
if (unlikely(current->audit_context) && !entryexit)
|
||||
audit_syscall_entry(AUDIT_ARCH_I386, regs->orig_eax,
|
||||
regs->ebx, regs->ecx, regs->edx, regs->esi);
|
||||
audit_syscall_entry(AUDIT_ARCH_I386, regs->orig_ax,
|
||||
regs->bx, regs->cx, regs->dx, regs->si);
|
||||
if (ret == 0)
|
||||
return 0;
|
||||
|
||||
regs->orig_eax = -1; /* force skip of syscall restarting */
|
||||
regs->orig_ax = -1; /* force skip of syscall restarting */
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->eax), regs->eax);
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -119,7 +119,7 @@ static int putreg(struct task_struct *child,
|
|||
clear_tsk_thread_flag(child, TIF_FORCED_TF);
|
||||
else if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||
value |= X86_EFLAGS_TF;
|
||||
value |= regs->eflags & ~FLAG_MASK;
|
||||
value |= regs->flags & ~FLAG_MASK;
|
||||
break;
|
||||
case offsetof(struct user_regs_struct,cs):
|
||||
if ((value & 3) != 3)
|
||||
|
@ -168,7 +168,7 @@ static unsigned long getreg(struct task_struct *child, unsigned long regno)
|
|||
/*
|
||||
* If the debugger set TF, hide it from the readout.
|
||||
*/
|
||||
val = regs->eflags;
|
||||
val = regs->flags;
|
||||
if (test_tsk_thread_flag(child, TIF_IA32))
|
||||
val &= 0xffffffff;
|
||||
if (test_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||
|
@ -383,9 +383,9 @@ static void syscall_trace(struct pt_regs *regs)
|
|||
{
|
||||
|
||||
#if 0
|
||||
printk("trace %s rip %lx rsp %lx rax %d origrax %d caller %lx tiflags %x ptrace %x\n",
|
||||
printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
|
||||
current->comm,
|
||||
regs->rip, regs->rsp, regs->rax, regs->orig_rax, __builtin_return_address(0),
|
||||
regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
|
||||
current_thread_info()->flags, current->ptrace);
|
||||
#endif
|
||||
|
||||
|
@ -405,7 +405,7 @@ static void syscall_trace(struct pt_regs *regs)
|
|||
asmlinkage void syscall_trace_enter(struct pt_regs *regs)
|
||||
{
|
||||
/* do the secure computing check first */
|
||||
secure_computing(regs->orig_rax);
|
||||
secure_computing(regs->orig_ax);
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE)
|
||||
&& (current->ptrace & PT_PTRACED))
|
||||
|
@ -414,14 +414,14 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
|
|||
if (unlikely(current->audit_context)) {
|
||||
if (test_thread_flag(TIF_IA32)) {
|
||||
audit_syscall_entry(AUDIT_ARCH_I386,
|
||||
regs->orig_rax,
|
||||
regs->rbx, regs->rcx,
|
||||
regs->rdx, regs->rsi);
|
||||
regs->orig_ax,
|
||||
regs->bx, regs->cx,
|
||||
regs->dx, regs->si);
|
||||
} else {
|
||||
audit_syscall_entry(AUDIT_ARCH_X86_64,
|
||||
regs->orig_rax,
|
||||
regs->rdi, regs->rsi,
|
||||
regs->rdx, regs->r10);
|
||||
regs->orig_ax,
|
||||
regs->di, regs->si,
|
||||
regs->dx, regs->r10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -429,7 +429,7 @@ asmlinkage void syscall_trace_enter(struct pt_regs *regs)
|
|||
asmlinkage void syscall_trace_leave(struct pt_regs *regs)
|
||||
{
|
||||
if (unlikely(current->audit_context))
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->rax), regs->rax);
|
||||
audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
|
||||
|
||||
if ((test_thread_flag(TIF_SYSCALL_TRACE)
|
||||
|| test_thread_flag(TIF_SINGLESTEP))
|
||||
|
|
|
@ -82,14 +82,14 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
|
|||
}
|
||||
|
||||
asmlinkage int
|
||||
sys_sigaltstack(unsigned long ebx)
|
||||
sys_sigaltstack(unsigned long bx)
|
||||
{
|
||||
/* This is needed to make gcc realize it doesn't own the "struct pt_regs" */
|
||||
struct pt_regs *regs = (struct pt_regs *)&ebx;
|
||||
const stack_t __user *uss = (const stack_t __user *)ebx;
|
||||
stack_t __user *uoss = (stack_t __user *)regs->ecx;
|
||||
struct pt_regs *regs = (struct pt_regs *)&bx;
|
||||
const stack_t __user *uss = (const stack_t __user *)bx;
|
||||
stack_t __user *uoss = (stack_t __user *)regs->cx;
|
||||
|
||||
return do_sigaltstack(uss, uoss, regs->esp);
|
||||
return do_sigaltstack(uss, uoss, regs->sp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,17 +105,17 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
|
|||
/* Always make any pending restarted system calls return -EINTR */
|
||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||
|
||||
#define COPY(x) err |= __get_user(regs->x, &sc->x)
|
||||
#define COPY(x) err |= __get_user(regs->x, &sc->e ## x)
|
||||
|
||||
#define COPY_SEG(seg) \
|
||||
{ unsigned short tmp; \
|
||||
err |= __get_user(tmp, &sc->seg); \
|
||||
regs->x##seg = tmp; }
|
||||
regs->seg = tmp; }
|
||||
|
||||
#define COPY_SEG_STRICT(seg) \
|
||||
{ unsigned short tmp; \
|
||||
err |= __get_user(tmp, &sc->seg); \
|
||||
regs->x##seg = tmp|3; }
|
||||
regs->seg = tmp|3; }
|
||||
|
||||
#define GET_SEG(seg) \
|
||||
{ unsigned short tmp; \
|
||||
|
@ -131,22 +131,22 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
|
|||
COPY_SEG(fs);
|
||||
COPY_SEG(es);
|
||||
COPY_SEG(ds);
|
||||
COPY(edi);
|
||||
COPY(esi);
|
||||
COPY(ebp);
|
||||
COPY(esp);
|
||||
COPY(ebx);
|
||||
COPY(edx);
|
||||
COPY(ecx);
|
||||
COPY(eip);
|
||||
COPY(di);
|
||||
COPY(si);
|
||||
COPY(bp);
|
||||
COPY(sp);
|
||||
COPY(bx);
|
||||
COPY(dx);
|
||||
COPY(cx);
|
||||
COPY(ip);
|
||||
COPY_SEG_STRICT(cs);
|
||||
COPY_SEG_STRICT(ss);
|
||||
|
||||
{
|
||||
unsigned int tmpflags;
|
||||
err |= __get_user(tmpflags, &sc->eflags);
|
||||
regs->eflags = (regs->eflags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
|
||||
regs->orig_eax = -1; /* disable syscall checks */
|
||||
regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
|
||||
regs->orig_ax = -1; /* disable syscall checks */
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -175,9 +175,9 @@ badframe:
|
|||
asmlinkage int sys_sigreturn(unsigned long __unused)
|
||||
{
|
||||
struct pt_regs *regs = (struct pt_regs *) &__unused;
|
||||
struct sigframe __user *frame = (struct sigframe __user *)(regs->esp - 8);
|
||||
struct sigframe __user *frame = (struct sigframe __user *)(regs->sp - 8);
|
||||
sigset_t set;
|
||||
int eax;
|
||||
int ax;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
@ -193,17 +193,17 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->sc, &eax))
|
||||
if (restore_sigcontext(regs, &frame->sc, &ax))
|
||||
goto badframe;
|
||||
return eax;
|
||||
return ax;
|
||||
|
||||
badframe:
|
||||
if (show_unhandled_signals && printk_ratelimit())
|
||||
printk("%s%s[%d] bad frame in sigreturn frame:%p eip:%lx"
|
||||
" esp:%lx oeax:%lx\n",
|
||||
printk("%s%s[%d] bad frame in sigreturn frame:%p ip:%lx"
|
||||
" sp:%lx oeax:%lx\n",
|
||||
task_pid_nr(current) > 1 ? KERN_INFO : KERN_EMERG,
|
||||
current->comm, task_pid_nr(current), frame, regs->eip,
|
||||
regs->esp, regs->orig_eax);
|
||||
current->comm, task_pid_nr(current), frame, regs->ip,
|
||||
regs->sp, regs->orig_ax);
|
||||
|
||||
force_sig(SIGSEGV, current);
|
||||
return 0;
|
||||
|
@ -212,9 +212,9 @@ badframe:
|
|||
asmlinkage int sys_rt_sigreturn(unsigned long __unused)
|
||||
{
|
||||
struct pt_regs *regs = (struct pt_regs *) &__unused;
|
||||
struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs->esp - 4);
|
||||
struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(regs->sp - 4);
|
||||
sigset_t set;
|
||||
int eax;
|
||||
int ax;
|
||||
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
|
||||
goto badframe;
|
||||
|
@ -227,13 +227,13 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
|
||||
goto badframe;
|
||||
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->esp) == -EFAULT)
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return eax;
|
||||
return ax;
|
||||
|
||||
badframe:
|
||||
force_sig(SIGSEGV, current);
|
||||
|
@ -250,27 +250,27 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
|
|||
{
|
||||
int tmp, err = 0;
|
||||
|
||||
err |= __put_user(regs->xfs, (unsigned int __user *)&sc->fs);
|
||||
err |= __put_user(regs->fs, (unsigned int __user *)&sc->fs);
|
||||
savesegment(gs, tmp);
|
||||
err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
|
||||
|
||||
err |= __put_user(regs->xes, (unsigned int __user *)&sc->es);
|
||||
err |= __put_user(regs->xds, (unsigned int __user *)&sc->ds);
|
||||
err |= __put_user(regs->edi, &sc->edi);
|
||||
err |= __put_user(regs->esi, &sc->esi);
|
||||
err |= __put_user(regs->ebp, &sc->ebp);
|
||||
err |= __put_user(regs->esp, &sc->esp);
|
||||
err |= __put_user(regs->ebx, &sc->ebx);
|
||||
err |= __put_user(regs->edx, &sc->edx);
|
||||
err |= __put_user(regs->ecx, &sc->ecx);
|
||||
err |= __put_user(regs->eax, &sc->eax);
|
||||
err |= __put_user(regs->es, (unsigned int __user *)&sc->es);
|
||||
err |= __put_user(regs->ds, (unsigned int __user *)&sc->ds);
|
||||
err |= __put_user(regs->di, &sc->edi);
|
||||
err |= __put_user(regs->si, &sc->esi);
|
||||
err |= __put_user(regs->bp, &sc->ebp);
|
||||
err |= __put_user(regs->sp, &sc->esp);
|
||||
err |= __put_user(regs->bx, &sc->ebx);
|
||||
err |= __put_user(regs->dx, &sc->edx);
|
||||
err |= __put_user(regs->cx, &sc->ecx);
|
||||
err |= __put_user(regs->ax, &sc->eax);
|
||||
err |= __put_user(current->thread.trap_no, &sc->trapno);
|
||||
err |= __put_user(current->thread.error_code, &sc->err);
|
||||
err |= __put_user(regs->eip, &sc->eip);
|
||||
err |= __put_user(regs->xcs, (unsigned int __user *)&sc->cs);
|
||||
err |= __put_user(regs->eflags, &sc->eflags);
|
||||
err |= __put_user(regs->esp, &sc->esp_at_signal);
|
||||
err |= __put_user(regs->xss, (unsigned int __user *)&sc->ss);
|
||||
err |= __put_user(regs->ip, &sc->eip);
|
||||
err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
|
||||
err |= __put_user(regs->flags, &sc->eflags);
|
||||
err |= __put_user(regs->sp, &sc->esp_at_signal);
|
||||
err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
|
||||
|
||||
tmp = save_i387(fpstate);
|
||||
if (tmp < 0)
|
||||
|
@ -291,36 +291,36 @@ setup_sigcontext(struct sigcontext __user *sc, struct _fpstate __user *fpstate,
|
|||
static inline void __user *
|
||||
get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
|
||||
{
|
||||
unsigned long esp;
|
||||
unsigned long sp;
|
||||
|
||||
/* Default to using normal stack */
|
||||
esp = regs->esp;
|
||||
sp = regs->sp;
|
||||
|
||||
/*
|
||||
* If we are on the alternate signal stack and would overflow it, don't.
|
||||
* Return an always-bogus address instead so we will die with SIGSEGV.
|
||||
*/
|
||||
if (on_sig_stack(esp) && !likely(on_sig_stack(esp - frame_size)))
|
||||
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
|
||||
return (void __user *) -1L;
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if (ka->sa.sa_flags & SA_ONSTACK) {
|
||||
if (sas_ss_flags(esp) == 0)
|
||||
esp = current->sas_ss_sp + current->sas_ss_size;
|
||||
if (sas_ss_flags(sp) == 0)
|
||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
||||
}
|
||||
|
||||
/* This is the legacy signal stack switching. */
|
||||
else if ((regs->xss & 0xffff) != __USER_DS &&
|
||||
else if ((regs->ss & 0xffff) != __USER_DS &&
|
||||
!(ka->sa.sa_flags & SA_RESTORER) &&
|
||||
ka->sa.sa_restorer) {
|
||||
esp = (unsigned long) ka->sa.sa_restorer;
|
||||
sp = (unsigned long) ka->sa.sa_restorer;
|
||||
}
|
||||
|
||||
esp -= frame_size;
|
||||
sp -= frame_size;
|
||||
/* Align the stack pointer according to the i386 ABI,
|
||||
* i.e. so that on function entry ((sp + 4) & 15) == 0. */
|
||||
esp = ((esp + 4) & -16ul) - 4;
|
||||
return (void __user *) esp;
|
||||
sp = ((sp + 4) & -16ul) - 4;
|
||||
return (void __user *) sp;
|
||||
}
|
||||
|
||||
/* These symbols are defined with the addresses in the vsyscall page.
|
||||
|
@ -387,16 +387,16 @@ static int setup_frame(int sig, struct k_sigaction *ka,
|
|||
goto give_sigsegv;
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->esp = (unsigned long) frame;
|
||||
regs->eip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->eax = (unsigned long) sig;
|
||||
regs->edx = (unsigned long) 0;
|
||||
regs->ecx = (unsigned long) 0;
|
||||
regs->sp = (unsigned long) frame;
|
||||
regs->ip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->ax = (unsigned long) sig;
|
||||
regs->dx = (unsigned long) 0;
|
||||
regs->cx = (unsigned long) 0;
|
||||
|
||||
regs->xds = __USER_DS;
|
||||
regs->xes = __USER_DS;
|
||||
regs->xss = __USER_DS;
|
||||
regs->xcs = __USER_CS;
|
||||
regs->ds = __USER_DS;
|
||||
regs->es = __USER_DS;
|
||||
regs->ss = __USER_DS;
|
||||
regs->cs = __USER_CS;
|
||||
|
||||
/*
|
||||
* Clear TF when entering the signal handler, but
|
||||
|
@ -404,13 +404,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,
|
|||
* The tracer may want to single-step inside the
|
||||
* handler too.
|
||||
*/
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
if (test_thread_flag(TIF_SINGLESTEP))
|
||||
ptrace_notify(SIGTRAP);
|
||||
|
||||
#if DEBUG_SIG
|
||||
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
|
||||
current->comm, current->pid, frame, regs->eip, frame->pretcode);
|
||||
current->comm, current->pid, frame, regs->ip, frame->pretcode);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -450,7 +450,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
err |= __put_user(0, &frame->uc.uc_link);
|
||||
err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
|
||||
err |= __put_user(sas_ss_flags(regs->esp),
|
||||
err |= __put_user(sas_ss_flags(regs->sp),
|
||||
&frame->uc.uc_stack.ss_flags);
|
||||
err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
|
||||
err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
|
||||
|
@ -466,7 +466,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
err |= __put_user(restorer, &frame->pretcode);
|
||||
|
||||
/*
|
||||
* This is movl $,%eax ; int $0x80
|
||||
* This is movl $,%ax ; int $0x80
|
||||
*
|
||||
* WE DO NOT USE IT ANY MORE! It's only left here for historical
|
||||
* reasons and because gdb uses it as a signature to notice
|
||||
|
@ -480,16 +480,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
goto give_sigsegv;
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->esp = (unsigned long) frame;
|
||||
regs->eip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->eax = (unsigned long) usig;
|
||||
regs->edx = (unsigned long) &frame->info;
|
||||
regs->ecx = (unsigned long) &frame->uc;
|
||||
regs->sp = (unsigned long) frame;
|
||||
regs->ip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->ax = (unsigned long) usig;
|
||||
regs->dx = (unsigned long) &frame->info;
|
||||
regs->cx = (unsigned long) &frame->uc;
|
||||
|
||||
regs->xds = __USER_DS;
|
||||
regs->xes = __USER_DS;
|
||||
regs->xss = __USER_DS;
|
||||
regs->xcs = __USER_CS;
|
||||
regs->ds = __USER_DS;
|
||||
regs->es = __USER_DS;
|
||||
regs->ss = __USER_DS;
|
||||
regs->cs = __USER_CS;
|
||||
|
||||
/*
|
||||
* Clear TF when entering the signal handler, but
|
||||
|
@ -497,13 +497,13 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
* The tracer may want to single-step inside the
|
||||
* handler too.
|
||||
*/
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
if (test_thread_flag(TIF_SINGLESTEP))
|
||||
ptrace_notify(SIGTRAP);
|
||||
|
||||
#if DEBUG_SIG
|
||||
printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
|
||||
current->comm, current->pid, frame, regs->eip, frame->pretcode);
|
||||
current->comm, current->pid, frame, regs->ip, frame->pretcode);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -524,23 +524,23 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
|||
int ret;
|
||||
|
||||
/* Are we from a system call? */
|
||||
if (regs->orig_eax >= 0) {
|
||||
if (regs->orig_ax >= 0) {
|
||||
/* If so, check system call restarting.. */
|
||||
switch (regs->eax) {
|
||||
switch (regs->ax) {
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
case -ERESTARTNOHAND:
|
||||
regs->eax = -EINTR;
|
||||
regs->ax = -EINTR;
|
||||
break;
|
||||
|
||||
case -ERESTARTSYS:
|
||||
if (!(ka->sa.sa_flags & SA_RESTART)) {
|
||||
regs->eax = -EINTR;
|
||||
regs->ax = -EINTR;
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case -ERESTARTNOINTR:
|
||||
regs->eax = regs->orig_eax;
|
||||
regs->eip -= 2;
|
||||
regs->ax = regs->orig_ax;
|
||||
regs->ip -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -548,9 +548,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
|||
* If TF is set due to a debugger (TIF_FORCED_TF), clear the TF
|
||||
* flag so that register information in the sigcontext is correct.
|
||||
*/
|
||||
if (unlikely(regs->eflags & X86_EFLAGS_TF) &&
|
||||
if (unlikely(regs->flags & X86_EFLAGS_TF) &&
|
||||
likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
|
||||
regs->eflags &= ~X86_EFLAGS_TF;
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
|
||||
/* Set up the stack frame */
|
||||
if (ka->sa.sa_flags & SA_SIGINFO)
|
||||
|
@ -622,19 +622,19 @@ static void fastcall do_signal(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
/* Did we come from a system call? */
|
||||
if (regs->orig_eax >= 0) {
|
||||
if (regs->orig_ax >= 0) {
|
||||
/* Restart the system call - no handlers present */
|
||||
switch (regs->eax) {
|
||||
switch (regs->ax) {
|
||||
case -ERESTARTNOHAND:
|
||||
case -ERESTARTSYS:
|
||||
case -ERESTARTNOINTR:
|
||||
regs->eax = regs->orig_eax;
|
||||
regs->eip -= 2;
|
||||
regs->ax = regs->orig_ax;
|
||||
regs->ip -= 2;
|
||||
break;
|
||||
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
regs->eax = __NR_restart_syscall;
|
||||
regs->eip -= 2;
|
||||
regs->ax = __NR_restart_syscall;
|
||||
regs->ip -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -657,7 +657,7 @@ void do_notify_resume(struct pt_regs *regs, void *_unused,
|
|||
{
|
||||
/* Pending single-step? */
|
||||
if (thread_info_flags & _TIF_SINGLESTEP) {
|
||||
regs->eflags |= TF_MASK;
|
||||
regs->flags |= TF_MASK;
|
||||
clear_thread_flag(TIF_SINGLESTEP);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ asmlinkage long
|
|||
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
return do_sigaltstack(uss, uoss, regs->rsp);
|
||||
return do_sigaltstack(uss, uoss, regs->sp);
|
||||
}
|
||||
|
||||
|
||||
|
@ -62,10 +62,11 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned
|
|||
/* Always make any pending restarted system calls return -EINTR */
|
||||
current_thread_info()->restart_block.fn = do_no_restart_syscall;
|
||||
|
||||
#define COPYR(x) err |= __get_user(regs->x, &sc->r ## x)
|
||||
#define COPY(x) err |= __get_user(regs->x, &sc->x)
|
||||
|
||||
COPY(rdi); COPY(rsi); COPY(rbp); COPY(rsp); COPY(rbx);
|
||||
COPY(rdx); COPY(rcx); COPY(rip);
|
||||
COPYR(di); COPYR(si); COPYR(bp); COPYR(sp); COPYR(bx);
|
||||
COPYR(dx); COPYR(cx); COPYR(ip);
|
||||
COPY(r8);
|
||||
COPY(r9);
|
||||
COPY(r10);
|
||||
|
@ -87,8 +88,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, unsigned
|
|||
{
|
||||
unsigned int tmpflags;
|
||||
err |= __get_user(tmpflags, &sc->eflags);
|
||||
regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
|
||||
regs->orig_rax = -1; /* disable syscall checks */
|
||||
regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5);
|
||||
regs->orig_ax = -1; /* disable syscall checks */
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -119,9 +120,9 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
|||
{
|
||||
struct rt_sigframe __user *frame;
|
||||
sigset_t set;
|
||||
unsigned long eax;
|
||||
unsigned long ax;
|
||||
|
||||
frame = (struct rt_sigframe __user *)(regs->rsp - 8);
|
||||
frame = (struct rt_sigframe __user *)(regs->sp - 8);
|
||||
if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) {
|
||||
goto badframe;
|
||||
}
|
||||
|
@ -135,17 +136,17 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
|
|||
recalc_sigpending();
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
|
||||
goto badframe;
|
||||
|
||||
#ifdef DEBUG_SIG
|
||||
printk("%d sigreturn rip:%lx rsp:%lx frame:%p rax:%lx\n",current->pid,regs->rip,regs->rsp,frame,eax);
|
||||
printk("%d sigreturn ip:%lx sp:%lx frame:%p ax:%lx\n",current->pid,regs->ip,regs->sp,frame,ax);
|
||||
#endif
|
||||
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->rsp) == -EFAULT)
|
||||
if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT)
|
||||
goto badframe;
|
||||
|
||||
return eax;
|
||||
return ax;
|
||||
|
||||
badframe:
|
||||
signal_fault(regs,frame,"sigreturn");
|
||||
|
@ -165,14 +166,14 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
|
|||
err |= __put_user(0, &sc->gs);
|
||||
err |= __put_user(0, &sc->fs);
|
||||
|
||||
err |= __put_user(regs->rdi, &sc->rdi);
|
||||
err |= __put_user(regs->rsi, &sc->rsi);
|
||||
err |= __put_user(regs->rbp, &sc->rbp);
|
||||
err |= __put_user(regs->rsp, &sc->rsp);
|
||||
err |= __put_user(regs->rbx, &sc->rbx);
|
||||
err |= __put_user(regs->rdx, &sc->rdx);
|
||||
err |= __put_user(regs->rcx, &sc->rcx);
|
||||
err |= __put_user(regs->rax, &sc->rax);
|
||||
err |= __put_user(regs->di, &sc->rdi);
|
||||
err |= __put_user(regs->si, &sc->rsi);
|
||||
err |= __put_user(regs->bp, &sc->rbp);
|
||||
err |= __put_user(regs->sp, &sc->rsp);
|
||||
err |= __put_user(regs->bx, &sc->rbx);
|
||||
err |= __put_user(regs->dx, &sc->rdx);
|
||||
err |= __put_user(regs->cx, &sc->rcx);
|
||||
err |= __put_user(regs->ax, &sc->rax);
|
||||
err |= __put_user(regs->r8, &sc->r8);
|
||||
err |= __put_user(regs->r9, &sc->r9);
|
||||
err |= __put_user(regs->r10, &sc->r10);
|
||||
|
@ -183,8 +184,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
|
|||
err |= __put_user(regs->r15, &sc->r15);
|
||||
err |= __put_user(me->thread.trap_no, &sc->trapno);
|
||||
err |= __put_user(me->thread.error_code, &sc->err);
|
||||
err |= __put_user(regs->rip, &sc->rip);
|
||||
err |= __put_user(regs->eflags, &sc->eflags);
|
||||
err |= __put_user(regs->ip, &sc->rip);
|
||||
err |= __put_user(regs->flags, &sc->eflags);
|
||||
err |= __put_user(mask, &sc->oldmask);
|
||||
err |= __put_user(me->thread.cr2, &sc->cr2);
|
||||
|
||||
|
@ -198,18 +199,18 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned lo
|
|||
static void __user *
|
||||
get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size)
|
||||
{
|
||||
unsigned long rsp;
|
||||
unsigned long sp;
|
||||
|
||||
/* Default to using normal stack - redzone*/
|
||||
rsp = regs->rsp - 128;
|
||||
sp = regs->sp - 128;
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
if (ka->sa.sa_flags & SA_ONSTACK) {
|
||||
if (sas_ss_flags(rsp) == 0)
|
||||
rsp = current->sas_ss_sp + current->sas_ss_size;
|
||||
if (sas_ss_flags(sp) == 0)
|
||||
sp = current->sas_ss_sp + current->sas_ss_size;
|
||||
}
|
||||
|
||||
return (void __user *)round_down(rsp - size, 16);
|
||||
return (void __user *)round_down(sp - size, 16);
|
||||
}
|
||||
|
||||
static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
||||
|
@ -246,7 +247,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
err |= __put_user(0, &frame->uc.uc_flags);
|
||||
err |= __put_user(0, &frame->uc.uc_link);
|
||||
err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
|
||||
err |= __put_user(sas_ss_flags(regs->rsp),
|
||||
err |= __put_user(sas_ss_flags(regs->sp),
|
||||
&frame->uc.uc_stack.ss_flags);
|
||||
err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
|
||||
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me);
|
||||
|
@ -271,21 +272,21 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
goto give_sigsegv;
|
||||
|
||||
#ifdef DEBUG_SIG
|
||||
printk("%d old rip %lx old rsp %lx old rax %lx\n", current->pid,regs->rip,regs->rsp,regs->rax);
|
||||
printk("%d old ip %lx old sp %lx old ax %lx\n", current->pid,regs->ip,regs->sp,regs->ax);
|
||||
#endif
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
regs->rdi = sig;
|
||||
regs->di = sig;
|
||||
/* In case the signal handler was declared without prototypes */
|
||||
regs->rax = 0;
|
||||
regs->ax = 0;
|
||||
|
||||
/* This also works for non SA_SIGINFO handlers because they expect the
|
||||
next argument after the signal number on the stack. */
|
||||
regs->rsi = (unsigned long)&frame->info;
|
||||
regs->rdx = (unsigned long)&frame->uc;
|
||||
regs->rip = (unsigned long) ka->sa.sa_handler;
|
||||
regs->si = (unsigned long)&frame->info;
|
||||
regs->dx = (unsigned long)&frame->uc;
|
||||
regs->ip = (unsigned long) ka->sa.sa_handler;
|
||||
|
||||
regs->rsp = (unsigned long)frame;
|
||||
regs->sp = (unsigned long)frame;
|
||||
|
||||
/* Set up the CS register to run signal handlers in 64-bit mode,
|
||||
even if the handler happens to be interrupting 32-bit code. */
|
||||
|
@ -295,12 +296,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
|
|||
see include/asm-x86_64/uaccess.h for details. */
|
||||
set_fs(USER_DS);
|
||||
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
if (test_thread_flag(TIF_SINGLESTEP))
|
||||
ptrace_notify(SIGTRAP);
|
||||
#ifdef DEBUG_SIG
|
||||
printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%p\n",
|
||||
current->comm, current->pid, frame, regs->rip, frame->pretcode);
|
||||
current->comm, current->pid, frame, regs->ip, frame->pretcode);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
@ -321,29 +322,29 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
|||
int ret;
|
||||
|
||||
#ifdef DEBUG_SIG
|
||||
printk("handle_signal pid:%d sig:%lu rip:%lx rsp:%lx regs=%p\n",
|
||||
printk("handle_signal pid:%d sig:%lu ip:%lx sp:%lx regs=%p\n",
|
||||
current->pid, sig,
|
||||
regs->rip, regs->rsp, regs);
|
||||
regs->ip, regs->sp, regs);
|
||||
#endif
|
||||
|
||||
/* Are we from a system call? */
|
||||
if ((long)regs->orig_rax >= 0) {
|
||||
if ((long)regs->orig_ax >= 0) {
|
||||
/* If so, check system call restarting.. */
|
||||
switch (regs->rax) {
|
||||
switch (regs->ax) {
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
case -ERESTARTNOHAND:
|
||||
regs->rax = -EINTR;
|
||||
regs->ax = -EINTR;
|
||||
break;
|
||||
|
||||
case -ERESTARTSYS:
|
||||
if (!(ka->sa.sa_flags & SA_RESTART)) {
|
||||
regs->rax = -EINTR;
|
||||
regs->ax = -EINTR;
|
||||
break;
|
||||
}
|
||||
/* fallthrough */
|
||||
case -ERESTARTNOINTR:
|
||||
regs->rax = regs->orig_rax;
|
||||
regs->rip -= 2;
|
||||
regs->ax = regs->orig_ax;
|
||||
regs->ip -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -352,9 +353,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
|
|||
* If TF is set due to a debugger (TIF_FORCED_TF), clear the TF
|
||||
* flag so that register information in the sigcontext is correct.
|
||||
*/
|
||||
if (unlikely(regs->eflags & X86_EFLAGS_TF) &&
|
||||
if (unlikely(regs->flags & X86_EFLAGS_TF) &&
|
||||
likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
|
||||
regs->eflags &= ~X86_EFLAGS_TF;
|
||||
regs->flags &= ~X86_EFLAGS_TF;
|
||||
|
||||
#ifdef CONFIG_IA32_EMULATION
|
||||
if (test_thread_flag(TIF_IA32)) {
|
||||
|
@ -426,21 +427,21 @@ static void do_signal(struct pt_regs *regs)
|
|||
}
|
||||
|
||||
/* Did we come from a system call? */
|
||||
if ((long)regs->orig_rax >= 0) {
|
||||
if ((long)regs->orig_ax >= 0) {
|
||||
/* Restart the system call - no handlers present */
|
||||
long res = regs->rax;
|
||||
long res = regs->ax;
|
||||
switch (res) {
|
||||
case -ERESTARTNOHAND:
|
||||
case -ERESTARTSYS:
|
||||
case -ERESTARTNOINTR:
|
||||
regs->rax = regs->orig_rax;
|
||||
regs->rip -= 2;
|
||||
regs->ax = regs->orig_ax;
|
||||
regs->ip -= 2;
|
||||
break;
|
||||
case -ERESTART_RESTARTBLOCK:
|
||||
regs->rax = test_thread_flag(TIF_IA32) ?
|
||||
regs->ax = test_thread_flag(TIF_IA32) ?
|
||||
__NR_ia32_restart_syscall :
|
||||
__NR_restart_syscall;
|
||||
regs->rip -= 2;
|
||||
regs->ip -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -457,13 +458,13 @@ void
|
|||
do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
|
||||
{
|
||||
#ifdef DEBUG_SIG
|
||||
printk("do_notify_resume flags:%x rip:%lx rsp:%lx caller:%p pending:%x\n",
|
||||
thread_info_flags, regs->rip, regs->rsp, __builtin_return_address(0),signal_pending(current));
|
||||
printk("do_notify_resume flags:%x ip:%lx sp:%lx caller:%p pending:%x\n",
|
||||
thread_info_flags, regs->ip, regs->sp, __builtin_return_address(0),signal_pending(current));
|
||||
#endif
|
||||
|
||||
/* Pending single-step? */
|
||||
if (thread_info_flags & _TIF_SINGLESTEP) {
|
||||
regs->eflags |= TF_MASK;
|
||||
regs->flags |= TF_MASK;
|
||||
clear_thread_flag(TIF_SINGLESTEP);
|
||||
}
|
||||
|
||||
|
@ -485,8 +486,8 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
|
|||
{
|
||||
struct task_struct *me = current;
|
||||
if (show_unhandled_signals && printk_ratelimit())
|
||||
printk("%s[%d] bad frame in %s frame:%p rip:%lx rsp:%lx orax:%lx\n",
|
||||
me->comm,me->pid,where,frame,regs->rip,regs->rsp,regs->orig_rax);
|
||||
printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx\n",
|
||||
me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax);
|
||||
|
||||
force_sig(SIGSEGV, me);
|
||||
}
|
||||
|
|
|
@ -136,7 +136,7 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
|
|||
* orig_rax contains the negated interrupt vector.
|
||||
* Use that to determine where the sender put the data.
|
||||
*/
|
||||
sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
|
||||
sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
|
||||
f = &per_cpu(flush_state, sender);
|
||||
|
||||
if (!cpu_isset(cpu, f->flush_cpumask))
|
||||
|
|
|
@ -447,7 +447,7 @@ void __devinit initialize_secondary(void)
|
|||
{
|
||||
/*
|
||||
* We don't actually need to load the full TSS,
|
||||
* basically just the stack pointer and the eip.
|
||||
* basically just the stack pointer and the ip.
|
||||
*/
|
||||
|
||||
asm volatile(
|
||||
|
@ -459,7 +459,7 @@ void __devinit initialize_secondary(void)
|
|||
|
||||
/* Static state in head.S used to set up a CPU */
|
||||
extern struct {
|
||||
void * esp;
|
||||
void * sp;
|
||||
unsigned short ss;
|
||||
} stack_start;
|
||||
|
||||
|
@ -667,7 +667,7 @@ wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip)
|
|||
* target processor state.
|
||||
*/
|
||||
startup_ipi_hook(phys_apicid, (unsigned long) start_secondary,
|
||||
(unsigned long) stack_start.esp);
|
||||
(unsigned long) stack_start.sp);
|
||||
|
||||
/*
|
||||
* Run STARTUP IPI loop.
|
||||
|
@ -806,9 +806,9 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
|
|||
alternatives_smp_switch(1);
|
||||
|
||||
/* So we see what's up */
|
||||
printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);
|
||||
printk("Booting processor %d/%d ip %lx\n", cpu, apicid, start_eip);
|
||||
/* Stack for startup_32 can be just as for start_secondary onwards */
|
||||
stack_start.esp = (void *) idle->thread.esp;
|
||||
stack_start.sp = (void *) idle->thread.esp;
|
||||
|
||||
irq_ctx_init(cpu);
|
||||
|
||||
|
|
|
@ -12,17 +12,12 @@ unsigned long convert_rip_to_linear(struct task_struct *child, struct pt_regs *r
|
|||
{
|
||||
unsigned long addr, seg;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
addr = regs->rip;
|
||||
addr = regs->ip;
|
||||
seg = regs->cs & 0xffff;
|
||||
#else
|
||||
addr = regs->eip;
|
||||
seg = regs->xcs & 0xffff;
|
||||
if (regs->eflags & X86_EFLAGS_VM) {
|
||||
if (v8086_mode(regs)) {
|
||||
addr = (addr & 0xffff) + (seg << 4);
|
||||
return addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We'll assume that the code segments in the GDT
|
||||
|
@ -124,11 +119,11 @@ static int enable_single_step(struct task_struct *child)
|
|||
/*
|
||||
* If TF was already set, don't do anything else
|
||||
*/
|
||||
if (regs->eflags & X86_EFLAGS_TF)
|
||||
if (regs->flags & X86_EFLAGS_TF)
|
||||
return 0;
|
||||
|
||||
/* Set TF on the kernel stack.. */
|
||||
regs->eflags |= X86_EFLAGS_TF;
|
||||
regs->flags |= X86_EFLAGS_TF;
|
||||
|
||||
/*
|
||||
* ..but if TF is changed by the instruction we will trace,
|
||||
|
@ -203,5 +198,5 @@ void user_disable_single_step(struct task_struct *child)
|
|||
|
||||
/* But touch TF only if it was set by us.. */
|
||||
if (test_and_clear_tsk_thread_flag(child, TIF_FORCED_TF))
|
||||
task_pt_regs(child)->eflags &= ~X86_EFLAGS_TF;
|
||||
task_pt_regs(child)->flags &= ~X86_EFLAGS_TF;
|
||||
}
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
ENTRY(swsusp_arch_suspend)
|
||||
movq $saved_context, %rax
|
||||
movq %rsp, pt_regs_rsp(%rax)
|
||||
movq %rbp, pt_regs_rbp(%rax)
|
||||
movq %rsi, pt_regs_rsi(%rax)
|
||||
movq %rdi, pt_regs_rdi(%rax)
|
||||
movq %rbx, pt_regs_rbx(%rax)
|
||||
movq %rcx, pt_regs_rcx(%rax)
|
||||
movq %rdx, pt_regs_rdx(%rax)
|
||||
movq %rsp, pt_regs_sp(%rax)
|
||||
movq %rbp, pt_regs_bp(%rax)
|
||||
movq %rsi, pt_regs_si(%rax)
|
||||
movq %rdi, pt_regs_di(%rax)
|
||||
movq %rbx, pt_regs_bx(%rax)
|
||||
movq %rcx, pt_regs_cx(%rax)
|
||||
movq %rdx, pt_regs_dx(%rax)
|
||||
movq %r8, pt_regs_r8(%rax)
|
||||
movq %r9, pt_regs_r9(%rax)
|
||||
movq %r10, pt_regs_r10(%rax)
|
||||
|
@ -34,7 +34,7 @@ ENTRY(swsusp_arch_suspend)
|
|||
movq %r14, pt_regs_r14(%rax)
|
||||
movq %r15, pt_regs_r15(%rax)
|
||||
pushfq
|
||||
popq pt_regs_eflags(%rax)
|
||||
popq pt_regs_flags(%rax)
|
||||
|
||||
/* save the address of restore_registers */
|
||||
movq $restore_registers, %rax
|
||||
|
@ -115,13 +115,13 @@ ENTRY(restore_registers)
|
|||
|
||||
/* We don't restore %rax, it must be 0 anyway */
|
||||
movq $saved_context, %rax
|
||||
movq pt_regs_rsp(%rax), %rsp
|
||||
movq pt_regs_rbp(%rax), %rbp
|
||||
movq pt_regs_rsi(%rax), %rsi
|
||||
movq pt_regs_rdi(%rax), %rdi
|
||||
movq pt_regs_rbx(%rax), %rbx
|
||||
movq pt_regs_rcx(%rax), %rcx
|
||||
movq pt_regs_rdx(%rax), %rdx
|
||||
movq pt_regs_sp(%rax), %rsp
|
||||
movq pt_regs_bp(%rax), %rbp
|
||||
movq pt_regs_si(%rax), %rsi
|
||||
movq pt_regs_di(%rax), %rdi
|
||||
movq pt_regs_bx(%rax), %rbx
|
||||
movq pt_regs_cx(%rax), %rcx
|
||||
movq pt_regs_dx(%rax), %rdx
|
||||
movq pt_regs_r8(%rax), %r8
|
||||
movq pt_regs_r9(%rax), %r9
|
||||
movq pt_regs_r10(%rax), %r10
|
||||
|
@ -130,7 +130,7 @@ ENTRY(restore_registers)
|
|||
movq pt_regs_r13(%rax), %r13
|
||||
movq pt_regs_r14(%rax), %r14
|
||||
movq pt_regs_r15(%rax), %r15
|
||||
pushq pt_regs_eflags(%rax)
|
||||
pushq pt_regs_flags(%rax)
|
||||
popfq
|
||||
|
||||
xorq %rax, %rax
|
||||
|
|
|
@ -49,15 +49,15 @@ unsigned long profile_pc(struct pt_regs *regs)
|
|||
unsigned long pc = instruction_pointer(regs);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->xcs) &&
|
||||
if (!v8086_mode(regs) && SEGMENT_IS_KERNEL_CODE(regs->cs) &&
|
||||
in_lock_functions(pc)) {
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
return *(unsigned long *)(regs->ebp + 4);
|
||||
return *(unsigned long *)(regs->bp + 4);
|
||||
#else
|
||||
unsigned long *sp = (unsigned long *)®s->esp;
|
||||
unsigned long *sp = (unsigned long *)®s->sp;
|
||||
|
||||
/* Return address is either directly at stack pointer
|
||||
or above a saved eflags. Eflags has bits 22-31 zero,
|
||||
or above a saved flags. Eflags has bits 22-31 zero,
|
||||
kernel addresses don't. */
|
||||
if (sp[0] >> 22)
|
||||
return sp[0];
|
||||
|
|
|
@ -29,10 +29,10 @@ unsigned long profile_pc(struct pt_regs *regs)
|
|||
unsigned long pc = instruction_pointer(regs);
|
||||
|
||||
/* Assume the lock function has either no stack frame or a copy
|
||||
of eflags from PUSHF
|
||||
of flags from PUSHF
|
||||
Eflags always has bits 22 and up cleared unlike kernel addresses. */
|
||||
if (!user_mode(regs) && in_lock_functions(pc)) {
|
||||
unsigned long *sp = (unsigned long *)regs->rsp;
|
||||
unsigned long *sp = (unsigned long *)regs->sp;
|
||||
if (sp[0] >> 22)
|
||||
return sp[0];
|
||||
if (sp[1] >> 22)
|
||||
|
|
|
@ -114,11 +114,11 @@ struct stack_frame {
|
|||
};
|
||||
|
||||
static inline unsigned long print_context_stack(struct thread_info *tinfo,
|
||||
unsigned long *stack, unsigned long ebp,
|
||||
unsigned long *stack, unsigned long bp,
|
||||
const struct stacktrace_ops *ops, void *data)
|
||||
{
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
struct stack_frame *frame = (struct stack_frame *)ebp;
|
||||
struct stack_frame *frame = (struct stack_frame *)bp;
|
||||
while (valid_stack_ptr(tinfo, frame, sizeof(*frame))) {
|
||||
struct stack_frame *next;
|
||||
unsigned long addr;
|
||||
|
@ -145,7 +145,7 @@ static inline unsigned long print_context_stack(struct thread_info *tinfo,
|
|||
ops->address(data, addr);
|
||||
}
|
||||
#endif
|
||||
return ebp;
|
||||
return bp;
|
||||
}
|
||||
|
||||
#define MSG(msg) ops->warning(data, msg)
|
||||
|
@ -154,7 +154,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
|||
unsigned long *stack,
|
||||
const struct stacktrace_ops *ops, void *data)
|
||||
{
|
||||
unsigned long ebp = 0;
|
||||
unsigned long bp = 0;
|
||||
|
||||
if (!task)
|
||||
task = current;
|
||||
|
@ -167,13 +167,13 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
|||
}
|
||||
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
if (!ebp) {
|
||||
if (!bp) {
|
||||
if (task == current) {
|
||||
/* Grab ebp right from our regs */
|
||||
asm ("movl %%ebp, %0" : "=r" (ebp) : );
|
||||
/* Grab bp right from our regs */
|
||||
asm ("movl %%ebp, %0" : "=r" (bp) : );
|
||||
} else {
|
||||
/* ebp is the last reg pushed by switch_to */
|
||||
ebp = *(unsigned long *) task->thread.esp;
|
||||
/* bp is the last reg pushed by switch_to */
|
||||
bp = *(unsigned long *) task->thread.esp;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -182,7 +182,7 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
|
|||
struct thread_info *context;
|
||||
context = (struct thread_info *)
|
||||
((unsigned long)stack & (~(THREAD_SIZE - 1)));
|
||||
ebp = print_context_stack(context, stack, ebp, ops, data);
|
||||
bp = print_context_stack(context, stack, bp, ops, data);
|
||||
/* Should be after the line below, but somewhere
|
||||
in early boot context comes out corrupted and we
|
||||
can't reference it -AK */
|
||||
|
@ -246,19 +246,19 @@ void show_trace(struct task_struct *task, struct pt_regs *regs,
|
|||
}
|
||||
|
||||
static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
|
||||
unsigned long *esp, char *log_lvl)
|
||||
unsigned long *sp, char *log_lvl)
|
||||
{
|
||||
unsigned long *stack;
|
||||
int i;
|
||||
|
||||
if (esp == NULL) {
|
||||
if (sp == NULL) {
|
||||
if (task)
|
||||
esp = (unsigned long*)task->thread.esp;
|
||||
sp = (unsigned long*)task->thread.esp;
|
||||
else
|
||||
esp = (unsigned long *)&esp;
|
||||
sp = (unsigned long *)&sp;
|
||||
}
|
||||
|
||||
stack = esp;
|
||||
stack = sp;
|
||||
for(i = 0; i < kstack_depth_to_print; i++) {
|
||||
if (kstack_end(stack))
|
||||
break;
|
||||
|
@ -267,13 +267,13 @@ static void show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
|
|||
printk("%08lx ", *stack++);
|
||||
}
|
||||
printk("\n%sCall Trace:\n", log_lvl);
|
||||
show_trace_log_lvl(task, regs, esp, log_lvl);
|
||||
show_trace_log_lvl(task, regs, sp, log_lvl);
|
||||
}
|
||||
|
||||
void show_stack(struct task_struct *task, unsigned long *esp)
|
||||
void show_stack(struct task_struct *task, unsigned long *sp)
|
||||
{
|
||||
printk(" ");
|
||||
show_stack_log_lvl(task, NULL, esp, "");
|
||||
show_stack_log_lvl(task, NULL, sp, "");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -307,30 +307,30 @@ void show_registers(struct pt_regs *regs)
|
|||
* time of the fault..
|
||||
*/
|
||||
if (!user_mode_vm(regs)) {
|
||||
u8 *eip;
|
||||
u8 *ip;
|
||||
unsigned int code_prologue = code_bytes * 43 / 64;
|
||||
unsigned int code_len = code_bytes;
|
||||
unsigned char c;
|
||||
|
||||
printk("\n" KERN_EMERG "Stack: ");
|
||||
show_stack_log_lvl(NULL, regs, ®s->esp, KERN_EMERG);
|
||||
show_stack_log_lvl(NULL, regs, ®s->sp, KERN_EMERG);
|
||||
|
||||
printk(KERN_EMERG "Code: ");
|
||||
|
||||
eip = (u8 *)regs->eip - code_prologue;
|
||||
if (eip < (u8 *)PAGE_OFFSET ||
|
||||
probe_kernel_address(eip, c)) {
|
||||
ip = (u8 *)regs->ip - code_prologue;
|
||||
if (ip < (u8 *)PAGE_OFFSET ||
|
||||
probe_kernel_address(ip, c)) {
|
||||
/* try starting at EIP */
|
||||
eip = (u8 *)regs->eip;
|
||||
ip = (u8 *)regs->ip;
|
||||
code_len = code_len - code_prologue + 1;
|
||||
}
|
||||
for (i = 0; i < code_len; i++, eip++) {
|
||||
if (eip < (u8 *)PAGE_OFFSET ||
|
||||
probe_kernel_address(eip, c)) {
|
||||
for (i = 0; i < code_len; i++, ip++) {
|
||||
if (ip < (u8 *)PAGE_OFFSET ||
|
||||
probe_kernel_address(ip, c)) {
|
||||
printk(" Bad EIP value.");
|
||||
break;
|
||||
}
|
||||
if (eip == (u8 *)regs->eip)
|
||||
if (ip == (u8 *)regs->ip)
|
||||
printk("<%02x> ", c);
|
||||
else
|
||||
printk("%02x ", c);
|
||||
|
@ -339,13 +339,13 @@ void show_registers(struct pt_regs *regs)
|
|||
printk("\n");
|
||||
}
|
||||
|
||||
int is_valid_bugaddr(unsigned long eip)
|
||||
int is_valid_bugaddr(unsigned long ip)
|
||||
{
|
||||
unsigned short ud2;
|
||||
|
||||
if (eip < PAGE_OFFSET)
|
||||
if (ip < PAGE_OFFSET)
|
||||
return 0;
|
||||
if (probe_kernel_address((unsigned short *)eip, ud2))
|
||||
if (probe_kernel_address((unsigned short *)ip, ud2))
|
||||
return 0;
|
||||
|
||||
return ud2 == 0x0b0f;
|
||||
|
@ -382,10 +382,10 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
raw_local_irq_save(flags);
|
||||
|
||||
if (++die.lock_owner_depth < 3) {
|
||||
unsigned long esp;
|
||||
unsigned long sp;
|
||||
unsigned short ss;
|
||||
|
||||
report_bug(regs->eip, regs);
|
||||
report_bug(regs->ip, regs);
|
||||
|
||||
printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff,
|
||||
++die_counter);
|
||||
|
@ -405,15 +405,15 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
NOTIFY_STOP) {
|
||||
show_registers(regs);
|
||||
/* Executive summary in case the oops scrolled away */
|
||||
esp = (unsigned long) (®s->esp);
|
||||
sp = (unsigned long) (®s->sp);
|
||||
savesegment(ss, ss);
|
||||
if (user_mode(regs)) {
|
||||
esp = regs->esp;
|
||||
ss = regs->xss & 0xffff;
|
||||
sp = regs->sp;
|
||||
ss = regs->ss & 0xffff;
|
||||
}
|
||||
printk(KERN_EMERG "EIP: [<%08lx>] ", regs->eip);
|
||||
print_symbol("%s", regs->eip);
|
||||
printk(" SS:ESP %04x:%08lx\n", ss, esp);
|
||||
printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip);
|
||||
print_symbol("%s", regs->ip);
|
||||
printk(" SS:ESP %04x:%08lx\n", ss, sp);
|
||||
}
|
||||
else
|
||||
regs = NULL;
|
||||
|
@ -454,7 +454,7 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, int vm86,
|
|||
{
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
if (regs->eflags & VM_MASK) {
|
||||
if (regs->flags & VM_MASK) {
|
||||
if (vm86)
|
||||
goto vm86_trap;
|
||||
goto trap_signal;
|
||||
|
@ -548,13 +548,13 @@ fastcall void do_##name(struct pt_regs * regs, long error_code) \
|
|||
do_trap(trapnr, signr, str, 1, regs, error_code, &info); \
|
||||
}
|
||||
|
||||
DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->eip)
|
||||
DO_VM86_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
|
||||
#ifndef CONFIG_KPROBES
|
||||
DO_VM86_ERROR( 3, SIGTRAP, "int3", int3)
|
||||
#endif
|
||||
DO_VM86_ERROR( 4, SIGSEGV, "overflow", overflow)
|
||||
DO_VM86_ERROR( 5, SIGSEGV, "bounds", bounds)
|
||||
DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->eip, 0)
|
||||
DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip, 0)
|
||||
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
|
||||
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
|
||||
DO_ERROR(11, SIGBUS, "segment not present", segment_not_present)
|
||||
|
@ -596,7 +596,7 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
|
|||
}
|
||||
put_cpu();
|
||||
|
||||
if (regs->eflags & VM_MASK)
|
||||
if (regs->flags & VM_MASK)
|
||||
goto gp_in_vm86;
|
||||
|
||||
if (!user_mode(regs))
|
||||
|
@ -607,9 +607,9 @@ fastcall void __kprobes do_general_protection(struct pt_regs * regs,
|
|||
if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) &&
|
||||
printk_ratelimit())
|
||||
printk(KERN_INFO
|
||||
"%s[%d] general protection eip:%lx esp:%lx error:%lx\n",
|
||||
"%s[%d] general protection ip:%lx sp:%lx error:%lx\n",
|
||||
current->comm, task_pid_nr(current),
|
||||
regs->eip, regs->esp, error_code);
|
||||
regs->ip, regs->sp, error_code);
|
||||
|
||||
force_sig(SIGSEGV, current);
|
||||
return;
|
||||
|
@ -705,8 +705,8 @@ void __kprobes die_nmi(struct pt_regs *regs, const char *msg)
|
|||
*/
|
||||
bust_spinlocks(1);
|
||||
printk(KERN_EMERG "%s", msg);
|
||||
printk(" on CPU%d, eip %08lx, registers:\n",
|
||||
smp_processor_id(), regs->eip);
|
||||
printk(" on CPU%d, ip %08lx, registers:\n",
|
||||
smp_processor_id(), regs->ip);
|
||||
show_registers(regs);
|
||||
console_silent();
|
||||
spin_unlock(&nmi_print_lock);
|
||||
|
@ -847,7 +847,7 @@ fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
|
|||
SIGTRAP) == NOTIFY_STOP)
|
||||
return;
|
||||
/* It's safe to allow irq's after DR6 has been saved */
|
||||
if (regs->eflags & X86_EFLAGS_IF)
|
||||
if (regs->flags & X86_EFLAGS_IF)
|
||||
local_irq_enable();
|
||||
|
||||
/* Mask out spurious debug traps due to lazy DR7 setting */
|
||||
|
@ -856,7 +856,7 @@ fastcall void __kprobes do_debug(struct pt_regs * regs, long error_code)
|
|||
goto clear_dr7;
|
||||
}
|
||||
|
||||
if (regs->eflags & VM_MASK)
|
||||
if (regs->flags & VM_MASK)
|
||||
goto debug_vm86;
|
||||
|
||||
/* Save debug status register where ptrace can see it */
|
||||
|
@ -892,7 +892,7 @@ debug_vm86:
|
|||
|
||||
clear_TF_reenable:
|
||||
set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -901,7 +901,7 @@ clear_TF_reenable:
|
|||
* the correct behaviour even in the presence of the asynchronous
|
||||
* IRQ13 behaviour
|
||||
*/
|
||||
void math_error(void __user *eip)
|
||||
void math_error(void __user *ip)
|
||||
{
|
||||
struct task_struct * task;
|
||||
siginfo_t info;
|
||||
|
@ -917,7 +917,7 @@ void math_error(void __user *eip)
|
|||
info.si_signo = SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = __SI_FAULT;
|
||||
info.si_addr = eip;
|
||||
info.si_addr = ip;
|
||||
/*
|
||||
* (~cwd & swd) will mask out exceptions that are not set to unmasked
|
||||
* status. 0x3f is the exception bits in these regs, 0x200 is the
|
||||
|
@ -963,10 +963,10 @@ void math_error(void __user *eip)
|
|||
fastcall void do_coprocessor_error(struct pt_regs * regs, long error_code)
|
||||
{
|
||||
ignore_fpu_irq = 1;
|
||||
math_error((void __user *)regs->eip);
|
||||
math_error((void __user *)regs->ip);
|
||||
}
|
||||
|
||||
static void simd_math_error(void __user *eip)
|
||||
static void simd_math_error(void __user *ip)
|
||||
{
|
||||
struct task_struct * task;
|
||||
siginfo_t info;
|
||||
|
@ -982,7 +982,7 @@ static void simd_math_error(void __user *eip)
|
|||
info.si_signo = SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = __SI_FAULT;
|
||||
info.si_addr = eip;
|
||||
info.si_addr = ip;
|
||||
/*
|
||||
* The SIMD FPU exceptions are handled a little differently, as there
|
||||
* is only a single status/control register. Thus, to determine which
|
||||
|
@ -1020,13 +1020,13 @@ fastcall void do_simd_coprocessor_error(struct pt_regs * regs,
|
|||
if (cpu_has_xmm) {
|
||||
/* Handle SIMD FPU exceptions on PIII+ processors. */
|
||||
ignore_fpu_irq = 1;
|
||||
simd_math_error((void __user *)regs->eip);
|
||||
simd_math_error((void __user *)regs->ip);
|
||||
} else {
|
||||
/*
|
||||
* Handle strange cache flush from user space exception
|
||||
* in all other cases. This is undocumented behaviour.
|
||||
*/
|
||||
if (regs->eflags & VM_MASK) {
|
||||
if (regs->flags & VM_MASK) {
|
||||
handle_vm86_fault((struct kernel_vm86_regs *)regs,
|
||||
error_code);
|
||||
return;
|
||||
|
|
|
@ -76,20 +76,20 @@ asmlinkage void spurious_interrupt_bug(void);
|
|||
|
||||
static inline void conditional_sti(struct pt_regs *regs)
|
||||
{
|
||||
if (regs->eflags & X86_EFLAGS_IF)
|
||||
if (regs->flags & X86_EFLAGS_IF)
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static inline void preempt_conditional_sti(struct pt_regs *regs)
|
||||
{
|
||||
preempt_disable();
|
||||
if (regs->eflags & X86_EFLAGS_IF)
|
||||
if (regs->flags & X86_EFLAGS_IF)
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
static inline void preempt_conditional_cli(struct pt_regs *regs)
|
||||
{
|
||||
if (regs->eflags & X86_EFLAGS_IF)
|
||||
if (regs->flags & X86_EFLAGS_IF)
|
||||
local_irq_disable();
|
||||
/* Make sure to not schedule here because we could be running
|
||||
on an exception stack. */
|
||||
|
@ -353,7 +353,7 @@ show_trace(struct task_struct *tsk, struct pt_regs *regs, unsigned long *stack)
|
|||
}
|
||||
|
||||
static void
|
||||
_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
|
||||
_show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *sp)
|
||||
{
|
||||
unsigned long *stack;
|
||||
int i;
|
||||
|
@ -364,14 +364,14 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
|
|||
// debugging aid: "show_stack(NULL, NULL);" prints the
|
||||
// back trace for this cpu.
|
||||
|
||||
if (rsp == NULL) {
|
||||
if (sp == NULL) {
|
||||
if (tsk)
|
||||
rsp = (unsigned long *)tsk->thread.rsp;
|
||||
sp = (unsigned long *)tsk->thread.rsp;
|
||||
else
|
||||
rsp = (unsigned long *)&rsp;
|
||||
sp = (unsigned long *)&sp;
|
||||
}
|
||||
|
||||
stack = rsp;
|
||||
stack = sp;
|
||||
for(i=0; i < kstack_depth_to_print; i++) {
|
||||
if (stack >= irqstack && stack <= irqstack_end) {
|
||||
if (stack == irqstack_end) {
|
||||
|
@ -387,12 +387,12 @@ _show_stack(struct task_struct *tsk, struct pt_regs *regs, unsigned long *rsp)
|
|||
printk(" %016lx", *stack++);
|
||||
touch_nmi_watchdog();
|
||||
}
|
||||
show_trace(tsk, regs, rsp);
|
||||
show_trace(tsk, regs, sp);
|
||||
}
|
||||
|
||||
void show_stack(struct task_struct *tsk, unsigned long * rsp)
|
||||
void show_stack(struct task_struct *tsk, unsigned long * sp)
|
||||
{
|
||||
_show_stack(tsk, NULL, rsp);
|
||||
_show_stack(tsk, NULL, sp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -416,11 +416,11 @@ void show_registers(struct pt_regs *regs)
|
|||
{
|
||||
int i;
|
||||
int in_kernel = !user_mode(regs);
|
||||
unsigned long rsp;
|
||||
unsigned long sp;
|
||||
const int cpu = smp_processor_id();
|
||||
struct task_struct *cur = cpu_pda(cpu)->pcurrent;
|
||||
|
||||
rsp = regs->rsp;
|
||||
sp = regs->sp;
|
||||
printk("CPU %d ", cpu);
|
||||
__show_regs(regs);
|
||||
printk("Process %s (pid: %d, threadinfo %p, task %p)\n",
|
||||
|
@ -432,15 +432,15 @@ void show_registers(struct pt_regs *regs)
|
|||
*/
|
||||
if (in_kernel) {
|
||||
printk("Stack: ");
|
||||
_show_stack(NULL, regs, (unsigned long*)rsp);
|
||||
_show_stack(NULL, regs, (unsigned long*)sp);
|
||||
|
||||
printk("\nCode: ");
|
||||
if (regs->rip < PAGE_OFFSET)
|
||||
if (regs->ip < PAGE_OFFSET)
|
||||
goto bad;
|
||||
|
||||
for (i=0; i<20; i++) {
|
||||
unsigned char c;
|
||||
if (__get_user(c, &((unsigned char*)regs->rip)[i])) {
|
||||
if (__get_user(c, &((unsigned char*)regs->ip)[i])) {
|
||||
bad:
|
||||
printk(" Bad RIP value.");
|
||||
break;
|
||||
|
@ -451,11 +451,11 @@ bad:
|
|||
printk("\n");
|
||||
}
|
||||
|
||||
int is_valid_bugaddr(unsigned long rip)
|
||||
int is_valid_bugaddr(unsigned long ip)
|
||||
{
|
||||
unsigned short ud2;
|
||||
|
||||
if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2)))
|
||||
if (__copy_from_user(&ud2, (const void __user *) ip, sizeof(ud2)))
|
||||
return 0;
|
||||
|
||||
return ud2 == 0x0b0f;
|
||||
|
@ -521,8 +521,8 @@ void __kprobes __die(const char * str, struct pt_regs * regs, long err)
|
|||
add_taint(TAINT_DIE);
|
||||
/* Executive summary in case the oops scrolled away */
|
||||
printk(KERN_ALERT "RIP ");
|
||||
printk_address(regs->rip);
|
||||
printk(" RSP <%016lx>\n", regs->rsp);
|
||||
printk_address(regs->ip);
|
||||
printk(" RSP <%016lx>\n", regs->sp);
|
||||
if (kexec_should_crash(current))
|
||||
crash_kexec(regs);
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||
unsigned long flags = oops_begin();
|
||||
|
||||
if (!user_mode(regs))
|
||||
report_bug(regs->rip, regs);
|
||||
report_bug(regs->ip, regs);
|
||||
|
||||
__die(str, regs, err);
|
||||
oops_end(flags);
|
||||
|
@ -582,9 +582,9 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
|
|||
if (show_unhandled_signals && unhandled_signal(tsk, signr) &&
|
||||
printk_ratelimit())
|
||||
printk(KERN_INFO
|
||||
"%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n",
|
||||
"%s[%d] trap %s ip:%lx sp:%lx error:%lx\n",
|
||||
tsk->comm, tsk->pid, str,
|
||||
regs->rip, regs->rsp, error_code);
|
||||
regs->ip, regs->sp, error_code);
|
||||
|
||||
if (info)
|
||||
force_sig_info(signr, info, tsk);
|
||||
|
@ -597,9 +597,9 @@ static void __kprobes do_trap(int trapnr, int signr, char *str,
|
|||
/* kernel trap */
|
||||
{
|
||||
const struct exception_table_entry *fixup;
|
||||
fixup = search_exception_tables(regs->rip);
|
||||
fixup = search_exception_tables(regs->ip);
|
||||
if (fixup)
|
||||
regs->rip = fixup->fixup;
|
||||
regs->ip = fixup->fixup;
|
||||
else {
|
||||
tsk->thread.error_code = error_code;
|
||||
tsk->thread.trap_no = trapnr;
|
||||
|
@ -635,10 +635,10 @@ asmlinkage void do_##name(struct pt_regs * regs, long error_code) \
|
|||
do_trap(trapnr, signr, str, regs, error_code, &info); \
|
||||
}
|
||||
|
||||
DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->rip)
|
||||
DO_ERROR_INFO( 0, SIGFPE, "divide error", divide_error, FPE_INTDIV, regs->ip)
|
||||
DO_ERROR( 4, SIGSEGV, "overflow", overflow)
|
||||
DO_ERROR( 5, SIGSEGV, "bounds", bounds)
|
||||
DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->rip)
|
||||
DO_ERROR_INFO( 6, SIGILL, "invalid opcode", invalid_op, ILL_ILLOPN, regs->ip)
|
||||
DO_ERROR( 7, SIGSEGV, "device not available", device_not_available)
|
||||
DO_ERROR( 9, SIGFPE, "coprocessor segment overrun", coprocessor_segment_overrun)
|
||||
DO_ERROR(10, SIGSEGV, "invalid TSS", invalid_TSS)
|
||||
|
@ -688,9 +688,9 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
|
|||
if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
|
||||
printk_ratelimit())
|
||||
printk(KERN_INFO
|
||||
"%s[%d] general protection rip:%lx rsp:%lx error:%lx\n",
|
||||
"%s[%d] general protection ip:%lx sp:%lx error:%lx\n",
|
||||
tsk->comm, tsk->pid,
|
||||
regs->rip, regs->rsp, error_code);
|
||||
regs->ip, regs->sp, error_code);
|
||||
|
||||
force_sig(SIGSEGV, tsk);
|
||||
return;
|
||||
|
@ -699,9 +699,9 @@ asmlinkage void __kprobes do_general_protection(struct pt_regs * regs,
|
|||
/* kernel gp */
|
||||
{
|
||||
const struct exception_table_entry *fixup;
|
||||
fixup = search_exception_tables(regs->rip);
|
||||
fixup = search_exception_tables(regs->ip);
|
||||
if (fixup) {
|
||||
regs->rip = fixup->fixup;
|
||||
regs->ip = fixup->fixup;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -824,15 +824,15 @@ asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs)
|
|||
{
|
||||
struct pt_regs *regs = eregs;
|
||||
/* Did already sync */
|
||||
if (eregs == (struct pt_regs *)eregs->rsp)
|
||||
if (eregs == (struct pt_regs *)eregs->sp)
|
||||
;
|
||||
/* Exception from user space */
|
||||
else if (user_mode(eregs))
|
||||
regs = task_pt_regs(current);
|
||||
/* Exception from kernel and interrupts are enabled. Move to
|
||||
kernel process stack. */
|
||||
else if (eregs->eflags & X86_EFLAGS_IF)
|
||||
regs = (struct pt_regs *)(eregs->rsp -= sizeof(struct pt_regs));
|
||||
else if (eregs->flags & X86_EFLAGS_IF)
|
||||
regs = (struct pt_regs *)(eregs->sp -= sizeof(struct pt_regs));
|
||||
if (eregs != regs)
|
||||
*regs = *eregs;
|
||||
return regs;
|
||||
|
@ -887,7 +887,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs * regs,
|
|||
info.si_signo = SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TRAP_BRKPT;
|
||||
info.si_addr = user_mode(regs) ? (void __user *)regs->rip : NULL;
|
||||
info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
|
||||
force_sig_info(SIGTRAP, &info, tsk);
|
||||
|
||||
clear_dr7:
|
||||
|
@ -897,16 +897,16 @@ clear_dr7:
|
|||
|
||||
clear_TF_reenable:
|
||||
set_tsk_thread_flag(tsk, TIF_SINGLESTEP);
|
||||
regs->eflags &= ~TF_MASK;
|
||||
regs->flags &= ~TF_MASK;
|
||||
preempt_conditional_cli(regs);
|
||||
}
|
||||
|
||||
static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
|
||||
{
|
||||
const struct exception_table_entry *fixup;
|
||||
fixup = search_exception_tables(regs->rip);
|
||||
fixup = search_exception_tables(regs->ip);
|
||||
if (fixup) {
|
||||
regs->rip = fixup->fixup;
|
||||
regs->ip = fixup->fixup;
|
||||
return 1;
|
||||
}
|
||||
notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE);
|
||||
|
@ -923,7 +923,7 @@ static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr)
|
|||
*/
|
||||
asmlinkage void do_coprocessor_error(struct pt_regs *regs)
|
||||
{
|
||||
void __user *rip = (void __user *)(regs->rip);
|
||||
void __user *ip = (void __user *)(regs->ip);
|
||||
struct task_struct * task;
|
||||
siginfo_t info;
|
||||
unsigned short cwd, swd;
|
||||
|
@ -943,7 +943,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs)
|
|||
info.si_signo = SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = __SI_FAULT;
|
||||
info.si_addr = rip;
|
||||
info.si_addr = ip;
|
||||
/*
|
||||
* (~cwd & swd) will mask out exceptions that are not set to unmasked
|
||||
* status. 0x3f is the exception bits in these regs, 0x200 is the
|
||||
|
@ -992,7 +992,7 @@ asmlinkage void bad_intr(void)
|
|||
|
||||
asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
|
||||
{
|
||||
void __user *rip = (void __user *)(regs->rip);
|
||||
void __user *ip = (void __user *)(regs->ip);
|
||||
struct task_struct * task;
|
||||
siginfo_t info;
|
||||
unsigned short mxcsr;
|
||||
|
@ -1012,7 +1012,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs)
|
|||
info.si_signo = SIGFPE;
|
||||
info.si_errno = 0;
|
||||
info.si_code = __SI_FAULT;
|
||||
info.si_addr = rip;
|
||||
info.si_addr = ip;
|
||||
/*
|
||||
* The SIMD FPU exceptions are handled a little differently, as there
|
||||
* is only a single status/control register. Thus, to determine which
|
||||
|
|
|
@ -70,10 +70,10 @@
|
|||
/*
|
||||
* 8- and 16-bit register defines..
|
||||
*/
|
||||
#define AL(regs) (((unsigned char *)&((regs)->pt.eax))[0])
|
||||
#define AH(regs) (((unsigned char *)&((regs)->pt.eax))[1])
|
||||
#define IP(regs) (*(unsigned short *)&((regs)->pt.eip))
|
||||
#define SP(regs) (*(unsigned short *)&((regs)->pt.esp))
|
||||
#define AL(regs) (((unsigned char *)&((regs)->pt.ax))[0])
|
||||
#define AH(regs) (((unsigned char *)&((regs)->pt.ax))[1])
|
||||
#define IP(regs) (*(unsigned short *)&((regs)->pt.ip))
|
||||
#define SP(regs) (*(unsigned short *)&((regs)->pt.sp))
|
||||
|
||||
/*
|
||||
* virtual flags (16 and 32-bit versions)
|
||||
|
@ -93,12 +93,12 @@ static int copy_vm86_regs_to_user(struct vm86_regs __user *user,
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
/* kernel_vm86_regs is missing xgs, so copy everything up to
|
||||
/* kernel_vm86_regs is missing gs, so copy everything up to
|
||||
(but not including) orig_eax, and then rest including orig_eax. */
|
||||
ret += copy_to_user(user, regs, offsetof(struct kernel_vm86_regs, pt.orig_eax));
|
||||
ret += copy_to_user(&user->orig_eax, ®s->pt.orig_eax,
|
||||
ret += copy_to_user(user, regs, offsetof(struct kernel_vm86_regs, pt.orig_ax));
|
||||
ret += copy_to_user(&user->orig_eax, ®s->pt.orig_ax,
|
||||
sizeof(struct kernel_vm86_regs) -
|
||||
offsetof(struct kernel_vm86_regs, pt.orig_eax));
|
||||
offsetof(struct kernel_vm86_regs, pt.orig_ax));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -110,12 +110,12 @@ static int copy_vm86_regs_from_user(struct kernel_vm86_regs *regs,
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
/* copy eax-xfs inclusive */
|
||||
ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.orig_eax));
|
||||
/* copy orig_eax-__gsh+extra */
|
||||
ret += copy_from_user(®s->pt.orig_eax, &user->orig_eax,
|
||||
/* copy ax-fs inclusive */
|
||||
ret += copy_from_user(regs, user, offsetof(struct kernel_vm86_regs, pt.orig_ax));
|
||||
/* copy orig_ax-__gsh+extra */
|
||||
ret += copy_from_user(®s->pt.orig_ax, &user->orig_eax,
|
||||
sizeof(struct kernel_vm86_regs) -
|
||||
offsetof(struct kernel_vm86_regs, pt.orig_eax) +
|
||||
offsetof(struct kernel_vm86_regs, pt.orig_ax) +
|
||||
extra);
|
||||
return ret;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
|
|||
printk("no vm86_info: BAD\n");
|
||||
do_exit(SIGSEGV);
|
||||
}
|
||||
set_flags(regs->pt.eflags, VEFLAGS, VIF_MASK | current->thread.v86mask);
|
||||
set_flags(regs->pt.flags, VEFLAGS, VIF_MASK | current->thread.v86mask);
|
||||
tmp = copy_vm86_regs_to_user(¤t->thread.vm86_info->regs,regs);
|
||||
tmp += put_user(current->thread.screen_bitmap,¤t->thread.vm86_info->screen_bitmap);
|
||||
if (tmp) {
|
||||
|
@ -155,7 +155,7 @@ struct pt_regs * fastcall save_v86_state(struct kernel_vm86_regs * regs)
|
|||
|
||||
ret = KVM86->regs32;
|
||||
|
||||
ret->xfs = current->thread.saved_fs;
|
||||
ret->fs = current->thread.saved_fs;
|
||||
loadsegment(gs, current->thread.saved_gs);
|
||||
|
||||
return ret;
|
||||
|
@ -197,7 +197,7 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
|
|||
|
||||
asmlinkage int sys_vm86old(struct pt_regs regs)
|
||||
{
|
||||
struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.ebx;
|
||||
struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs.bx;
|
||||
struct kernel_vm86_struct info; /* declare this _on top_,
|
||||
* this avoids wasting of stack space.
|
||||
* This remains on the stack until we
|
||||
|
@ -237,12 +237,12 @@ asmlinkage int sys_vm86(struct pt_regs regs)
|
|||
struct vm86plus_struct __user *v86;
|
||||
|
||||
tsk = current;
|
||||
switch (regs.ebx) {
|
||||
switch (regs.bx) {
|
||||
case VM86_REQUEST_IRQ:
|
||||
case VM86_FREE_IRQ:
|
||||
case VM86_GET_IRQ_BITS:
|
||||
case VM86_GET_AND_RESET_IRQ:
|
||||
ret = do_vm86_irq_handling(regs.ebx, (int)regs.ecx);
|
||||
ret = do_vm86_irq_handling(regs.bx, (int)regs.cx);
|
||||
goto out;
|
||||
case VM86_PLUS_INSTALL_CHECK:
|
||||
/* NOTE: on old vm86 stuff this will return the error
|
||||
|
@ -258,7 +258,7 @@ asmlinkage int sys_vm86(struct pt_regs regs)
|
|||
ret = -EPERM;
|
||||
if (tsk->thread.saved_esp0)
|
||||
goto out;
|
||||
v86 = (struct vm86plus_struct __user *)regs.ecx;
|
||||
v86 = (struct vm86plus_struct __user *)regs.cx;
|
||||
tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
|
||||
offsetof(struct kernel_vm86_struct, regs32) -
|
||||
sizeof(info.regs));
|
||||
|
@ -281,23 +281,23 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
|
|||
/*
|
||||
* make sure the vm86() system call doesn't try to do anything silly
|
||||
*/
|
||||
info->regs.pt.xds = 0;
|
||||
info->regs.pt.xes = 0;
|
||||
info->regs.pt.xfs = 0;
|
||||
info->regs.pt.ds = 0;
|
||||
info->regs.pt.es = 0;
|
||||
info->regs.pt.fs = 0;
|
||||
|
||||
/* we are clearing gs later just before "jmp resume_userspace",
|
||||
* because it is not saved/restored.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The eflags register is also special: we cannot trust that the user
|
||||
* The flags register is also special: we cannot trust that the user
|
||||
* has set it up safely, so this makes sure interrupt etc flags are
|
||||
* inherited from protected mode.
|
||||
*/
|
||||
VEFLAGS = info->regs.pt.eflags;
|
||||
info->regs.pt.eflags &= SAFE_MASK;
|
||||
info->regs.pt.eflags |= info->regs32->eflags & ~SAFE_MASK;
|
||||
info->regs.pt.eflags |= VM_MASK;
|
||||
VEFLAGS = info->regs.pt.flags;
|
||||
info->regs.pt.flags &= SAFE_MASK;
|
||||
info->regs.pt.flags |= info->regs32->flags & ~SAFE_MASK;
|
||||
info->regs.pt.flags |= VM_MASK;
|
||||
|
||||
switch (info->cpu_type) {
|
||||
case CPU_286:
|
||||
|
@ -315,11 +315,11 @@ static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk
|
|||
}
|
||||
|
||||
/*
|
||||
* Save old state, set default return value (%eax) to 0
|
||||
* Save old state, set default return value (%ax) to 0
|
||||
*/
|
||||
info->regs32->eax = 0;
|
||||
info->regs32->ax = 0;
|
||||
tsk->thread.saved_esp0 = tsk->thread.esp0;
|
||||
tsk->thread.saved_fs = info->regs32->xfs;
|
||||
tsk->thread.saved_fs = info->regs32->fs;
|
||||
savesegment(gs, tsk->thread.saved_gs);
|
||||
|
||||
tss = &per_cpu(init_tss, get_cpu());
|
||||
|
@ -352,7 +352,7 @@ static inline void return_to_32bit(struct kernel_vm86_regs * regs16, int retval)
|
|||
struct pt_regs * regs32;
|
||||
|
||||
regs32 = save_v86_state(regs16);
|
||||
regs32->eax = retval;
|
||||
regs32->ax = retval;
|
||||
__asm__ __volatile__("movl %0,%%esp\n\t"
|
||||
"movl %1,%%ebp\n\t"
|
||||
"jmp resume_userspace"
|
||||
|
@ -373,12 +373,12 @@ static inline void clear_IF(struct kernel_vm86_regs * regs)
|
|||
|
||||
static inline void clear_TF(struct kernel_vm86_regs * regs)
|
||||
{
|
||||
regs->pt.eflags &= ~TF_MASK;
|
||||
regs->pt.flags &= ~TF_MASK;
|
||||
}
|
||||
|
||||
static inline void clear_AC(struct kernel_vm86_regs * regs)
|
||||
{
|
||||
regs->pt.eflags &= ~AC_MASK;
|
||||
regs->pt.flags &= ~AC_MASK;
|
||||
}
|
||||
|
||||
/* It is correct to call set_IF(regs) from the set_vflags_*
|
||||
|
@ -392,11 +392,11 @@ static inline void clear_AC(struct kernel_vm86_regs * regs)
|
|||
* [KD]
|
||||
*/
|
||||
|
||||
static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs * regs)
|
||||
static inline void set_vflags_long(unsigned long flags, struct kernel_vm86_regs * regs)
|
||||
{
|
||||
set_flags(VEFLAGS, eflags, current->thread.v86mask);
|
||||
set_flags(regs->pt.eflags, eflags, SAFE_MASK);
|
||||
if (eflags & IF_MASK)
|
||||
set_flags(VEFLAGS, flags, current->thread.v86mask);
|
||||
set_flags(regs->pt.flags, flags, SAFE_MASK);
|
||||
if (flags & IF_MASK)
|
||||
set_IF(regs);
|
||||
else
|
||||
clear_IF(regs);
|
||||
|
@ -405,7 +405,7 @@ static inline void set_vflags_long(unsigned long eflags, struct kernel_vm86_regs
|
|||
static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_regs * regs)
|
||||
{
|
||||
set_flags(VFLAGS, flags, current->thread.v86mask);
|
||||
set_flags(regs->pt.eflags, flags, SAFE_MASK);
|
||||
set_flags(regs->pt.flags, flags, SAFE_MASK);
|
||||
if (flags & IF_MASK)
|
||||
set_IF(regs);
|
||||
else
|
||||
|
@ -414,7 +414,7 @@ static inline void set_vflags_short(unsigned short flags, struct kernel_vm86_reg
|
|||
|
||||
static inline unsigned long get_vflags(struct kernel_vm86_regs * regs)
|
||||
{
|
||||
unsigned long flags = regs->pt.eflags & RETURN_MASK;
|
||||
unsigned long flags = regs->pt.flags & RETURN_MASK;
|
||||
|
||||
if (VEFLAGS & VIF_MASK)
|
||||
flags |= IF_MASK;
|
||||
|
@ -518,7 +518,7 @@ static void do_int(struct kernel_vm86_regs *regs, int i,
|
|||
unsigned long __user *intr_ptr;
|
||||
unsigned long segoffs;
|
||||
|
||||
if (regs->pt.xcs == BIOSSEG)
|
||||
if (regs->pt.cs == BIOSSEG)
|
||||
goto cannot_handle;
|
||||
if (is_revectored(i, &KVM86->int_revectored))
|
||||
goto cannot_handle;
|
||||
|
@ -530,9 +530,9 @@ static void do_int(struct kernel_vm86_regs *regs, int i,
|
|||
if ((segoffs >> 16) == BIOSSEG)
|
||||
goto cannot_handle;
|
||||
pushw(ssp, sp, get_vflags(regs), cannot_handle);
|
||||
pushw(ssp, sp, regs->pt.xcs, cannot_handle);
|
||||
pushw(ssp, sp, regs->pt.cs, cannot_handle);
|
||||
pushw(ssp, sp, IP(regs), cannot_handle);
|
||||
regs->pt.xcs = segoffs >> 16;
|
||||
regs->pt.cs = segoffs >> 16;
|
||||
SP(regs) -= 6;
|
||||
IP(regs) = segoffs & 0xffff;
|
||||
clear_TF(regs);
|
||||
|
@ -549,7 +549,7 @@ int handle_vm86_trap(struct kernel_vm86_regs * regs, long error_code, int trapno
|
|||
if (VMPI.is_vm86pus) {
|
||||
if ( (trapno==3) || (trapno==1) )
|
||||
return_to_32bit(regs, VM86_TRAP + (trapno << 8));
|
||||
do_int(regs, trapno, (unsigned char __user *) (regs->pt.xss << 4), SP(regs));
|
||||
do_int(regs, trapno, (unsigned char __user *) (regs->pt.ss << 4), SP(regs));
|
||||
return 0;
|
||||
}
|
||||
if (trapno !=1)
|
||||
|
@ -585,10 +585,10 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
|
|||
handle_vm86_trap(regs, 0, 1); \
|
||||
return; } while (0)
|
||||
|
||||
orig_flags = *(unsigned short *)®s->pt.eflags;
|
||||
orig_flags = *(unsigned short *)®s->pt.flags;
|
||||
|
||||
csp = (unsigned char __user *) (regs->pt.xcs << 4);
|
||||
ssp = (unsigned char __user *) (regs->pt.xss << 4);
|
||||
csp = (unsigned char __user *) (regs->pt.cs << 4);
|
||||
ssp = (unsigned char __user *) (regs->pt.ss << 4);
|
||||
sp = SP(regs);
|
||||
ip = IP(regs);
|
||||
|
||||
|
@ -675,7 +675,7 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
|
|||
SP(regs) += 6;
|
||||
}
|
||||
IP(regs) = newip;
|
||||
regs->pt.xcs = newcs;
|
||||
regs->pt.cs = newcs;
|
||||
CHECK_IF_IN_TRAP;
|
||||
if (data32) {
|
||||
set_vflags_long(newflags, regs);
|
||||
|
|
|
@ -88,13 +88,13 @@ struct vmi_timer_ops vmi_timer_ops;
|
|||
#define IRQ_PATCH_DISABLE 5
|
||||
|
||||
static inline void patch_offset(void *insnbuf,
|
||||
unsigned long eip, unsigned long dest)
|
||||
unsigned long ip, unsigned long dest)
|
||||
{
|
||||
*(unsigned long *)(insnbuf+1) = dest-eip-5;
|
||||
*(unsigned long *)(insnbuf+1) = dest-ip-5;
|
||||
}
|
||||
|
||||
static unsigned patch_internal(int call, unsigned len, void *insnbuf,
|
||||
unsigned long eip)
|
||||
unsigned long ip)
|
||||
{
|
||||
u64 reloc;
|
||||
struct vmi_relocation_info *const rel = (struct vmi_relocation_info *)&reloc;
|
||||
|
@ -103,13 +103,13 @@ static unsigned patch_internal(int call, unsigned len, void *insnbuf,
|
|||
case VMI_RELOCATION_CALL_REL:
|
||||
BUG_ON(len < 5);
|
||||
*(char *)insnbuf = MNEM_CALL;
|
||||
patch_offset(insnbuf, eip, (unsigned long)rel->eip);
|
||||
patch_offset(insnbuf, ip, (unsigned long)rel->eip);
|
||||
return 5;
|
||||
|
||||
case VMI_RELOCATION_JUMP_REL:
|
||||
BUG_ON(len < 5);
|
||||
*(char *)insnbuf = MNEM_JMP;
|
||||
patch_offset(insnbuf, eip, (unsigned long)rel->eip);
|
||||
patch_offset(insnbuf, ip, (unsigned long)rel->eip);
|
||||
return 5;
|
||||
|
||||
case VMI_RELOCATION_NOP:
|
||||
|
@ -131,25 +131,25 @@ static unsigned patch_internal(int call, unsigned len, void *insnbuf,
|
|||
* sequence. The callee does nop padding for us.
|
||||
*/
|
||||
static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
|
||||
unsigned long eip, unsigned len)
|
||||
unsigned long ip, unsigned len)
|
||||
{
|
||||
switch (type) {
|
||||
case PARAVIRT_PATCH(pv_irq_ops.irq_disable):
|
||||
return patch_internal(VMI_CALL_DisableInterrupts, len,
|
||||
insns, eip);
|
||||
insns, ip);
|
||||
case PARAVIRT_PATCH(pv_irq_ops.irq_enable):
|
||||
return patch_internal(VMI_CALL_EnableInterrupts, len,
|
||||
insns, eip);
|
||||
insns, ip);
|
||||
case PARAVIRT_PATCH(pv_irq_ops.restore_fl):
|
||||
return patch_internal(VMI_CALL_SetInterruptMask, len,
|
||||
insns, eip);
|
||||
insns, ip);
|
||||
case PARAVIRT_PATCH(pv_irq_ops.save_fl):
|
||||
return patch_internal(VMI_CALL_GetInterruptMask, len,
|
||||
insns, eip);
|
||||
insns, ip);
|
||||
case PARAVIRT_PATCH(pv_cpu_ops.iret):
|
||||
return patch_internal(VMI_CALL_IRET, len, insns, eip);
|
||||
return patch_internal(VMI_CALL_IRET, len, insns, ip);
|
||||
case PARAVIRT_PATCH(pv_cpu_ops.irq_enable_syscall_ret):
|
||||
return patch_internal(VMI_CALL_SYSEXIT, len, insns, eip);
|
||||
return patch_internal(VMI_CALL_SYSEXIT, len, insns, ip);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -157,29 +157,29 @@ static unsigned vmi_patch(u8 type, u16 clobbers, void *insns,
|
|||
}
|
||||
|
||||
/* CPUID has non-C semantics, and paravirt-ops API doesn't match hardware ISA */
|
||||
static void vmi_cpuid(unsigned int *eax, unsigned int *ebx,
|
||||
unsigned int *ecx, unsigned int *edx)
|
||||
static void vmi_cpuid(unsigned int *ax, unsigned int *bx,
|
||||
unsigned int *cx, unsigned int *dx)
|
||||
{
|
||||
int override = 0;
|
||||
if (*eax == 1)
|
||||
if (*ax == 1)
|
||||
override = 1;
|
||||
asm volatile ("call *%6"
|
||||
: "=a" (*eax),
|
||||
"=b" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "0" (*eax), "2" (*ecx), "r" (vmi_ops.cpuid));
|
||||
: "=a" (*ax),
|
||||
"=b" (*bx),
|
||||
"=c" (*cx),
|
||||
"=d" (*dx)
|
||||
: "0" (*ax), "2" (*cx), "r" (vmi_ops.cpuid));
|
||||
if (override) {
|
||||
if (disable_pse)
|
||||
*edx &= ~X86_FEATURE_PSE;
|
||||
*dx &= ~X86_FEATURE_PSE;
|
||||
if (disable_pge)
|
||||
*edx &= ~X86_FEATURE_PGE;
|
||||
*dx &= ~X86_FEATURE_PGE;
|
||||
if (disable_sep)
|
||||
*edx &= ~X86_FEATURE_SEP;
|
||||
*dx &= ~X86_FEATURE_SEP;
|
||||
if (disable_tsc)
|
||||
*edx &= ~X86_FEATURE_TSC;
|
||||
*dx &= ~X86_FEATURE_TSC;
|
||||
if (disable_mtrr)
|
||||
*edx &= ~X86_FEATURE_MTRR;
|
||||
*dx &= ~X86_FEATURE_MTRR;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
#include <asm/vgtod.h>
|
||||
|
||||
#define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr)))
|
||||
#define __syscall_clobber "r11","rcx","memory"
|
||||
#define __syscall_clobber "r11","cx","memory"
|
||||
#define __pa_vsymbol(x) \
|
||||
({unsigned long v; \
|
||||
extern char __vsyscall_0; \
|
||||
|
|
|
@ -175,8 +175,8 @@ static void lguest_leave_lazy_mode(void)
|
|||
* check there when it wants to deliver an interrupt.
|
||||
*/
|
||||
|
||||
/* save_flags() is expected to return the processor state (ie. "eflags"). The
|
||||
* eflags word contains all kind of stuff, but in practice Linux only cares
|
||||
/* save_flags() is expected to return the processor state (ie. "flags"). The
|
||||
* flags word contains all kind of stuff, but in practice Linux only cares
|
||||
* about the interrupt flag. Our "save_flags()" just returns that. */
|
||||
static unsigned long save_fl(void)
|
||||
{
|
||||
|
@ -323,30 +323,30 @@ static void lguest_load_tr_desc(void)
|
|||
* anyone (including userspace) can just use the raw "cpuid" instruction and
|
||||
* the Host won't even notice since it isn't privileged. So we try not to get
|
||||
* too worked up about it. */
|
||||
static void lguest_cpuid(unsigned int *eax, unsigned int *ebx,
|
||||
unsigned int *ecx, unsigned int *edx)
|
||||
static void lguest_cpuid(unsigned int *ax, unsigned int *bx,
|
||||
unsigned int *cx, unsigned int *dx)
|
||||
{
|
||||
int function = *eax;
|
||||
int function = *ax;
|
||||
|
||||
native_cpuid(eax, ebx, ecx, edx);
|
||||
native_cpuid(ax, bx, cx, dx);
|
||||
switch (function) {
|
||||
case 1: /* Basic feature request. */
|
||||
/* We only allow kernel to see SSE3, CMPXCHG16B and SSSE3 */
|
||||
*ecx &= 0x00002201;
|
||||
*cx &= 0x00002201;
|
||||
/* SSE, SSE2, FXSR, MMX, CMOV, CMPXCHG8B, FPU. */
|
||||
*edx &= 0x07808101;
|
||||
*dx &= 0x07808101;
|
||||
/* The Host can do a nice optimization if it knows that the
|
||||
* kernel mappings (addresses above 0xC0000000 or whatever
|
||||
* PAGE_OFFSET is set to) haven't changed. But Linux calls
|
||||
* flush_tlb_user() for both user and kernel mappings unless
|
||||
* the Page Global Enable (PGE) feature bit is set. */
|
||||
*edx |= 0x00002000;
|
||||
*dx |= 0x00002000;
|
||||
break;
|
||||
case 0x80000000:
|
||||
/* Futureproof this a little: if they ask how much extended
|
||||
* processor information there is, limit it to known fields. */
|
||||
if (*eax > 0x80000008)
|
||||
*eax = 0x80000008;
|
||||
if (*ax > 0x80000008)
|
||||
*ax = 0x80000008;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -526,7 +526,7 @@ static void __init do_boot_cpu(__u8 cpu)
|
|||
* initial kernel stack. We need to alter this to give the
|
||||
* booting CPU a new stack (taken from its idle process) */
|
||||
extern struct {
|
||||
__u8 *esp;
|
||||
__u8 *sp;
|
||||
unsigned short ss;
|
||||
} stack_start;
|
||||
/* This is the format of the CPI IDT gate (in real mode) which
|
||||
|
@ -555,9 +555,9 @@ static void __init do_boot_cpu(__u8 cpu)
|
|||
idle = fork_idle(cpu);
|
||||
if (IS_ERR(idle))
|
||||
panic("failed fork for CPU%d", cpu);
|
||||
idle->thread.eip = (unsigned long)start_secondary;
|
||||
idle->thread.ip = (unsigned long)start_secondary;
|
||||
/* init_tasks (in sched.c) is indexed logically */
|
||||
stack_start.esp = (void *)idle->thread.esp;
|
||||
stack_start.sp = (void *)idle->thread.sp;
|
||||
|
||||
init_gdt(cpu);
|
||||
per_cpu(current_task, cpu) = idle;
|
||||
|
@ -567,7 +567,7 @@ static void __init do_boot_cpu(__u8 cpu)
|
|||
/* Note: Don't modify initial ss override */
|
||||
VDEBUG(("VOYAGER SMP: Booting CPU%d at 0x%lx[%x:%x], stack %p\n", cpu,
|
||||
(unsigned long)hijack_source.val, hijack_source.idt.Segment,
|
||||
hijack_source.idt.Offset, stack_start.esp));
|
||||
hijack_source.idt.Offset, stack_start.sp));
|
||||
|
||||
/* init lowmem identity mapping */
|
||||
clone_pgd_range(swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS,
|
||||
|
@ -745,8 +745,8 @@ void __init initialize_secondary(void)
|
|||
*/
|
||||
|
||||
asm volatile ("movl %0,%%esp\n\t"
|
||||
"jmp *%1"::"r" (current->thread.esp),
|
||||
"r"(current->thread.eip));
|
||||
"jmp *%1"::"r" (current->thread.sp),
|
||||
"r"(current->thread.ip));
|
||||
}
|
||||
|
||||
/* handle a Voyager SYS_INT -- If we don't, the base board will
|
||||
|
|
|
@ -11,7 +11,7 @@ int fixup_exception(struct pt_regs *regs)
|
|||
const struct exception_table_entry *fixup;
|
||||
|
||||
#ifdef CONFIG_PNPBIOS
|
||||
if (unlikely(SEGMENT_IS_PNP_CODE(regs->xcs)))
|
||||
if (unlikely(SEGMENT_IS_PNP_CODE(regs->cs)))
|
||||
{
|
||||
extern u32 pnp_bios_fault_eip, pnp_bios_fault_esp;
|
||||
extern u32 pnp_bios_is_utter_crap;
|
||||
|
@ -25,9 +25,9 @@ int fixup_exception(struct pt_regs *regs)
|
|||
}
|
||||
#endif
|
||||
|
||||
fixup = search_exception_tables(regs->eip);
|
||||
fixup = search_exception_tables(regs->ip);
|
||||
if (fixup) {
|
||||
regs->eip = fixup->fixup;
|
||||
regs->ip = fixup->fixup;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -72,15 +72,15 @@ static inline int notify_page_fault(struct pt_regs *regs)
|
|||
static inline unsigned long get_segment_eip(struct pt_regs *regs,
|
||||
unsigned long *eip_limit)
|
||||
{
|
||||
unsigned long eip = regs->eip;
|
||||
unsigned seg = regs->xcs & 0xffff;
|
||||
unsigned long ip = regs->ip;
|
||||
unsigned seg = regs->cs & 0xffff;
|
||||
u32 seg_ar, seg_limit, base, *desc;
|
||||
|
||||
/* Unlikely, but must come before segment checks. */
|
||||
if (unlikely(regs->eflags & VM_MASK)) {
|
||||
if (unlikely(regs->flags & VM_MASK)) {
|
||||
base = seg << 4;
|
||||
*eip_limit = base + 0xffff;
|
||||
return base + (eip & 0xffff);
|
||||
return base + (ip & 0xffff);
|
||||
}
|
||||
|
||||
/* The standard kernel/user address space limit. */
|
||||
|
@ -88,16 +88,16 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
|
|||
|
||||
/* By far the most common cases. */
|
||||
if (likely(SEGMENT_IS_FLAT_CODE(seg)))
|
||||
return eip;
|
||||
return ip;
|
||||
|
||||
/* Check the segment exists, is within the current LDT/GDT size,
|
||||
that kernel/user (ring 0..3) has the appropriate privilege,
|
||||
that it's a code segment, and get the limit. */
|
||||
__asm__ ("larl %3,%0; lsll %3,%1"
|
||||
: "=&r" (seg_ar), "=r" (seg_limit) : "0" (0), "rm" (seg));
|
||||
if ((~seg_ar & 0x9800) || eip > seg_limit) {
|
||||
if ((~seg_ar & 0x9800) || ip > seg_limit) {
|
||||
*eip_limit = 0;
|
||||
return 1; /* So that returned eip > *eip_limit. */
|
||||
return 1; /* So that returned ip > *eip_limit. */
|
||||
}
|
||||
|
||||
/* Get the GDT/LDT descriptor base.
|
||||
|
@ -127,7 +127,7 @@ static inline unsigned long get_segment_eip(struct pt_regs *regs,
|
|||
seg_limit += base;
|
||||
if (seg_limit < *eip_limit && seg_limit >= base)
|
||||
*eip_limit = seg_limit;
|
||||
return eip + base;
|
||||
return ip + base;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -345,7 +345,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
|
|||
|
||||
/* It's safe to allow irq's after cr2 has been saved and the vmalloc
|
||||
fault has been handled. */
|
||||
if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
|
||||
if (regs->flags & (X86_EFLAGS_IF|VM_MASK))
|
||||
local_irq_enable();
|
||||
|
||||
mm = tsk->mm;
|
||||
|
@ -374,7 +374,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
|
|||
*/
|
||||
if (!down_read_trylock(&mm->mmap_sem)) {
|
||||
if ((error_code & 4) == 0 &&
|
||||
!search_exception_tables(regs->eip))
|
||||
!search_exception_tables(regs->ip))
|
||||
goto bad_area_nosemaphore;
|
||||
down_read(&mm->mmap_sem);
|
||||
}
|
||||
|
@ -388,12 +388,12 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
|
|||
goto bad_area;
|
||||
if (error_code & 4) {
|
||||
/*
|
||||
* Accessing the stack below %esp is always a bug.
|
||||
* Accessing the stack below %sp is always a bug.
|
||||
* The large cushion allows instructions like enter
|
||||
* and pusha to work. ("enter $65535,$31" pushes
|
||||
* 32 pointers and then decrements %esp by 65535.)
|
||||
* 32 pointers and then decrements %sp by 65535.)
|
||||
*/
|
||||
if (address + 65536 + 32 * sizeof(unsigned long) < regs->esp)
|
||||
if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
|
||||
goto bad_area;
|
||||
}
|
||||
if (expand_stack(vma, address))
|
||||
|
@ -442,7 +442,7 @@ good_area:
|
|||
/*
|
||||
* Did it hit the DOS screen memory VA from vm86 mode?
|
||||
*/
|
||||
if (regs->eflags & VM_MASK) {
|
||||
if (regs->flags & VM_MASK) {
|
||||
unsigned long bit = (address - 0xA0000) >> PAGE_SHIFT;
|
||||
if (bit < 32)
|
||||
tsk->thread.screen_bitmap |= 1 << bit;
|
||||
|
@ -474,11 +474,11 @@ bad_area_nosemaphore:
|
|||
|
||||
if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
|
||||
printk_ratelimit()) {
|
||||
printk("%s%s[%d]: segfault at %08lx eip %08lx "
|
||||
"esp %08lx error %lx\n",
|
||||
printk("%s%s[%d]: segfault at %08lx ip %08lx "
|
||||
"sp %08lx error %lx\n",
|
||||
task_pid_nr(tsk) > 1 ? KERN_INFO : KERN_EMERG,
|
||||
tsk->comm, task_pid_nr(tsk), address, regs->eip,
|
||||
regs->esp, error_code);
|
||||
tsk->comm, task_pid_nr(tsk), address, regs->ip,
|
||||
regs->sp, error_code);
|
||||
}
|
||||
tsk->thread.cr2 = address;
|
||||
/* Kernel addresses are always protection faults */
|
||||
|
@ -544,7 +544,7 @@ no_context:
|
|||
printk(KERN_ALERT "BUG: unable to handle kernel paging"
|
||||
" request");
|
||||
printk(" at virtual address %08lx\n",address);
|
||||
printk(KERN_ALERT "printing eip: %08lx ", regs->eip);
|
||||
printk(KERN_ALERT "printing ip: %08lx ", regs->ip);
|
||||
|
||||
page = read_cr3();
|
||||
page = ((__typeof__(page) *) __va(page))[address >> PGDIR_SHIFT];
|
||||
|
|
|
@ -198,7 +198,7 @@ KERN_ERR "******* Disabling USB legacy in the BIOS may also help.\n";
|
|||
static int is_errata93(struct pt_regs *regs, unsigned long address)
|
||||
{
|
||||
static int warned;
|
||||
if (address != regs->rip)
|
||||
if (address != regs->ip)
|
||||
return 0;
|
||||
if ((address >> 32) != 0)
|
||||
return 0;
|
||||
|
@ -209,7 +209,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address)
|
|||
printk(errata93_warning);
|
||||
warned = 1;
|
||||
}
|
||||
regs->rip = address;
|
||||
regs->ip = address;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
@ -355,7 +355,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
|
|||
if (notify_page_fault(regs))
|
||||
return;
|
||||
|
||||
if (likely(regs->eflags & X86_EFLAGS_IF))
|
||||
if (likely(regs->flags & X86_EFLAGS_IF))
|
||||
local_irq_enable();
|
||||
|
||||
if (unlikely(error_code & PF_RSVD))
|
||||
|
@ -393,7 +393,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
|
|||
*/
|
||||
if (!down_read_trylock(&mm->mmap_sem)) {
|
||||
if ((error_code & PF_USER) == 0 &&
|
||||
!search_exception_tables(regs->rip))
|
||||
!search_exception_tables(regs->ip))
|
||||
goto bad_area_nosemaphore;
|
||||
down_read(&mm->mmap_sem);
|
||||
}
|
||||
|
@ -409,7 +409,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
|
|||
/* Allow userspace just enough access below the stack pointer
|
||||
* to let the 'enter' instruction work.
|
||||
*/
|
||||
if (address + 65536 + 32 * sizeof(unsigned long) < regs->rsp)
|
||||
if (address + 65536 + 32 * sizeof(unsigned long) < regs->sp)
|
||||
goto bad_area;
|
||||
}
|
||||
if (expand_stack(vma, address))
|
||||
|
@ -488,10 +488,10 @@ bad_area_nosemaphore:
|
|||
if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) &&
|
||||
printk_ratelimit()) {
|
||||
printk(
|
||||
"%s%s[%d]: segfault at %lx rip %lx rsp %lx error %lx\n",
|
||||
"%s%s[%d]: segfault at %lx ip %lx sp %lx error %lx\n",
|
||||
tsk->pid > 1 ? KERN_INFO : KERN_EMERG,
|
||||
tsk->comm, tsk->pid, address, regs->rip,
|
||||
regs->rsp, error_code);
|
||||
tsk->comm, tsk->pid, address, regs->ip,
|
||||
regs->sp, error_code);
|
||||
}
|
||||
|
||||
tsk->thread.cr2 = address;
|
||||
|
@ -509,9 +509,9 @@ bad_area_nosemaphore:
|
|||
no_context:
|
||||
|
||||
/* Are we prepared to handle this kernel fault? */
|
||||
fixup = search_exception_tables(regs->rip);
|
||||
fixup = search_exception_tables(regs->ip);
|
||||
if (fixup) {
|
||||
regs->rip = fixup->fixup;
|
||||
regs->ip = fixup->fixup;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -537,7 +537,7 @@ no_context:
|
|||
else
|
||||
printk(KERN_ALERT "Unable to handle kernel paging request");
|
||||
printk(" at %016lx RIP: \n" KERN_ALERT,address);
|
||||
printk_address(regs->rip);
|
||||
printk_address(regs->ip);
|
||||
dump_pagetable(address);
|
||||
tsk->thread.cr2 = address;
|
||||
tsk->thread.trap_no = 14;
|
||||
|
|
|
@ -48,7 +48,7 @@ static struct stacktrace_ops backtrace_ops = {
|
|||
};
|
||||
|
||||
struct frame_head {
|
||||
struct frame_head *ebp;
|
||||
struct frame_head *bp;
|
||||
unsigned long ret;
|
||||
} __attribute__((packed));
|
||||
|
||||
|
@ -67,10 +67,10 @@ dump_user_backtrace(struct frame_head * head)
|
|||
|
||||
/* frame pointers should strictly progress back up the stack
|
||||
* (towards higher addresses) */
|
||||
if (head >= bufhead[0].ebp)
|
||||
if (head >= bufhead[0].bp)
|
||||
return NULL;
|
||||
|
||||
return bufhead[0].ebp;
|
||||
return bufhead[0].bp;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -141,8 +141,8 @@ static void __init xen_banner(void)
|
|||
printk(KERN_INFO "Hypervisor signature: %s\n", xen_start_info->magic);
|
||||
}
|
||||
|
||||
static void xen_cpuid(unsigned int *eax, unsigned int *ebx,
|
||||
unsigned int *ecx, unsigned int *edx)
|
||||
static void xen_cpuid(unsigned int *ax, unsigned int *bx,
|
||||
unsigned int *cx, unsigned int *dx)
|
||||
{
|
||||
unsigned maskedx = ~0;
|
||||
|
||||
|
@ -150,18 +150,18 @@ static void xen_cpuid(unsigned int *eax, unsigned int *ebx,
|
|||
* Mask out inconvenient features, to try and disable as many
|
||||
* unsupported kernel subsystems as possible.
|
||||
*/
|
||||
if (*eax == 1)
|
||||
if (*ax == 1)
|
||||
maskedx = ~((1 << X86_FEATURE_APIC) | /* disable APIC */
|
||||
(1 << X86_FEATURE_ACPI) | /* disable ACPI */
|
||||
(1 << X86_FEATURE_ACC)); /* thermal monitoring */
|
||||
|
||||
asm(XEN_EMULATE_PREFIX "cpuid"
|
||||
: "=a" (*eax),
|
||||
"=b" (*ebx),
|
||||
"=c" (*ecx),
|
||||
"=d" (*edx)
|
||||
: "0" (*eax), "2" (*ecx));
|
||||
*edx &= maskedx;
|
||||
: "=a" (*ax),
|
||||
"=b" (*bx),
|
||||
"=c" (*cx),
|
||||
"=d" (*dx)
|
||||
: "0" (*ax), "2" (*cx));
|
||||
*dx &= maskedx;
|
||||
}
|
||||
|
||||
static void xen_set_debugreg(int reg, unsigned long val)
|
||||
|
|
|
@ -487,7 +487,7 @@ fastcall void xen_evtchn_do_upcall(struct pt_regs *regs)
|
|||
int irq = evtchn_to_irq[port];
|
||||
|
||||
if (irq != -1) {
|
||||
regs->orig_eax = ~irq;
|
||||
regs->orig_ax = ~irq;
|
||||
do_IRQ(regs);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -207,7 +207,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
|||
static __inline__ void __user *compat_alloc_user_space(long len)
|
||||
{
|
||||
struct pt_regs *regs = task_pt_regs(current);
|
||||
return (void __user *)regs->rsp - len;
|
||||
return (void __user *)regs->sp - len;
|
||||
}
|
||||
|
||||
static inline int is_compat_task(void)
|
||||
|
|
|
@ -99,32 +99,32 @@ typedef struct user_fxsr_struct elf_fpxregset_t;
|
|||
just to make things more deterministic.
|
||||
*/
|
||||
#define ELF_PLAT_INIT(_r, load_addr) do { \
|
||||
_r->ebx = 0; _r->ecx = 0; _r->edx = 0; \
|
||||
_r->esi = 0; _r->edi = 0; _r->ebp = 0; \
|
||||
_r->eax = 0; \
|
||||
_r->bx = 0; _r->cx = 0; _r->dx = 0; \
|
||||
_r->si = 0; _r->di = 0; _r->bp = 0; \
|
||||
_r->ax = 0; \
|
||||
} while (0)
|
||||
|
||||
/* regs is struct pt_regs, pr_reg is elf_gregset_t (which is
|
||||
now struct_user_regs, they are different) */
|
||||
|
||||
#define ELF_CORE_COPY_REGS(pr_reg, regs) \
|
||||
pr_reg[0] = regs->ebx; \
|
||||
pr_reg[1] = regs->ecx; \
|
||||
pr_reg[2] = regs->edx; \
|
||||
pr_reg[3] = regs->esi; \
|
||||
pr_reg[4] = regs->edi; \
|
||||
pr_reg[5] = regs->ebp; \
|
||||
pr_reg[6] = regs->eax; \
|
||||
pr_reg[7] = regs->xds & 0xffff; \
|
||||
pr_reg[8] = regs->xes & 0xffff; \
|
||||
pr_reg[9] = regs->xfs & 0xffff; \
|
||||
pr_reg[0] = regs->bx; \
|
||||
pr_reg[1] = regs->cx; \
|
||||
pr_reg[2] = regs->dx; \
|
||||
pr_reg[3] = regs->si; \
|
||||
pr_reg[4] = regs->di; \
|
||||
pr_reg[5] = regs->bp; \
|
||||
pr_reg[6] = regs->ax; \
|
||||
pr_reg[7] = regs->ds & 0xffff; \
|
||||
pr_reg[8] = regs->es & 0xffff; \
|
||||
pr_reg[9] = regs->fs & 0xffff; \
|
||||
savesegment(gs,pr_reg[10]); \
|
||||
pr_reg[11] = regs->orig_eax; \
|
||||
pr_reg[12] = regs->eip; \
|
||||
pr_reg[13] = regs->xcs & 0xffff; \
|
||||
pr_reg[14] = regs->eflags; \
|
||||
pr_reg[15] = regs->esp; \
|
||||
pr_reg[16] = regs->xss & 0xffff;
|
||||
pr_reg[11] = regs->orig_ax; \
|
||||
pr_reg[12] = regs->ip; \
|
||||
pr_reg[13] = regs->cs & 0xffff; \
|
||||
pr_reg[14] = regs->flags; \
|
||||
pr_reg[15] = regs->sp; \
|
||||
pr_reg[16] = regs->ss & 0xffff;
|
||||
|
||||
#define ELF_PLATFORM (utsname()->machine)
|
||||
#define set_personality_64bit() do { } while (0)
|
||||
|
@ -142,9 +142,9 @@ extern unsigned int vdso_enabled;
|
|||
|
||||
#define ELF_PLAT_INIT(_r, load_addr) do { \
|
||||
struct task_struct *cur = current; \
|
||||
(_r)->rbx = 0; (_r)->rcx = 0; (_r)->rdx = 0; \
|
||||
(_r)->rsi = 0; (_r)->rdi = 0; (_r)->rbp = 0; \
|
||||
(_r)->rax = 0; \
|
||||
(_r)->bx = 0; (_r)->cx = 0; (_r)->dx = 0; \
|
||||
(_r)->si = 0; (_r)->di = 0; (_r)->bp = 0; \
|
||||
(_r)->ax = 0; \
|
||||
(_r)->r8 = 0; \
|
||||
(_r)->r9 = 0; \
|
||||
(_r)->r10 = 0; \
|
||||
|
@ -169,22 +169,22 @@ extern unsigned int vdso_enabled;
|
|||
(pr_reg)[1] = (regs)->r14; \
|
||||
(pr_reg)[2] = (regs)->r13; \
|
||||
(pr_reg)[3] = (regs)->r12; \
|
||||
(pr_reg)[4] = (regs)->rbp; \
|
||||
(pr_reg)[5] = (regs)->rbx; \
|
||||
(pr_reg)[4] = (regs)->bp; \
|
||||
(pr_reg)[5] = (regs)->bx; \
|
||||
(pr_reg)[6] = (regs)->r11; \
|
||||
(pr_reg)[7] = (regs)->r10; \
|
||||
(pr_reg)[8] = (regs)->r9; \
|
||||
(pr_reg)[9] = (regs)->r8; \
|
||||
(pr_reg)[10] = (regs)->rax; \
|
||||
(pr_reg)[11] = (regs)->rcx; \
|
||||
(pr_reg)[12] = (regs)->rdx; \
|
||||
(pr_reg)[13] = (regs)->rsi; \
|
||||
(pr_reg)[14] = (regs)->rdi; \
|
||||
(pr_reg)[15] = (regs)->orig_rax; \
|
||||
(pr_reg)[16] = (regs)->rip; \
|
||||
(pr_reg)[10] = (regs)->ax; \
|
||||
(pr_reg)[11] = (regs)->cx; \
|
||||
(pr_reg)[12] = (regs)->dx; \
|
||||
(pr_reg)[13] = (regs)->si; \
|
||||
(pr_reg)[14] = (regs)->di; \
|
||||
(pr_reg)[15] = (regs)->orig_ax; \
|
||||
(pr_reg)[16] = (regs)->ip; \
|
||||
(pr_reg)[17] = (regs)->cs; \
|
||||
(pr_reg)[18] = (regs)->eflags; \
|
||||
(pr_reg)[19] = (regs)->rsp; \
|
||||
(pr_reg)[18] = (regs)->flags; \
|
||||
(pr_reg)[19] = (regs)->sp; \
|
||||
(pr_reg)[20] = (regs)->ss; \
|
||||
(pr_reg)[21] = current->thread.fs; \
|
||||
(pr_reg)[22] = current->thread.gs; \
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
/* We can also handle crash dumps from 64 bit kernel. */
|
||||
#define vmcore_elf_check_arch_cross(x) ((x)->e_machine == EM_X86_64)
|
||||
|
||||
/* CPU does not save ss and esp on stack if execution is already
|
||||
/* CPU does not save ss and sp on stack if execution is already
|
||||
* running in kernel mode at the time of NMI occurrence. This code
|
||||
* fixes it.
|
||||
*/
|
||||
|
@ -53,16 +53,16 @@ static inline void crash_fixup_ss_esp(struct pt_regs *newregs,
|
|||
struct pt_regs *oldregs)
|
||||
{
|
||||
memcpy(newregs, oldregs, sizeof(*newregs));
|
||||
newregs->esp = (unsigned long)&(oldregs->esp);
|
||||
newregs->sp = (unsigned long)&(oldregs->sp);
|
||||
__asm__ __volatile__(
|
||||
"xorl %%eax, %%eax\n\t"
|
||||
"movw %%ss, %%ax\n\t"
|
||||
:"=a"(newregs->xss));
|
||||
:"=a"(newregs->ss));
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is responsible for capturing register states if coming
|
||||
* via panic otherwise just fix up the ss and esp if coming via kernel
|
||||
* via panic otherwise just fix up the ss and sp if coming via kernel
|
||||
* mode exception.
|
||||
*/
|
||||
static inline void crash_setup_regs(struct pt_regs *newregs,
|
||||
|
@ -71,21 +71,21 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
|
|||
if (oldregs)
|
||||
crash_fixup_ss_esp(newregs, oldregs);
|
||||
else {
|
||||
__asm__ __volatile__("movl %%ebx,%0" : "=m"(newregs->ebx));
|
||||
__asm__ __volatile__("movl %%ecx,%0" : "=m"(newregs->ecx));
|
||||
__asm__ __volatile__("movl %%edx,%0" : "=m"(newregs->edx));
|
||||
__asm__ __volatile__("movl %%esi,%0" : "=m"(newregs->esi));
|
||||
__asm__ __volatile__("movl %%edi,%0" : "=m"(newregs->edi));
|
||||
__asm__ __volatile__("movl %%ebp,%0" : "=m"(newregs->ebp));
|
||||
__asm__ __volatile__("movl %%eax,%0" : "=m"(newregs->eax));
|
||||
__asm__ __volatile__("movl %%esp,%0" : "=m"(newregs->esp));
|
||||
__asm__ __volatile__("movw %%ss, %%ax;" :"=a"(newregs->xss));
|
||||
__asm__ __volatile__("movw %%cs, %%ax;" :"=a"(newregs->xcs));
|
||||
__asm__ __volatile__("movw %%ds, %%ax;" :"=a"(newregs->xds));
|
||||
__asm__ __volatile__("movw %%es, %%ax;" :"=a"(newregs->xes));
|
||||
__asm__ __volatile__("pushfl; popl %0" :"=m"(newregs->eflags));
|
||||
__asm__ __volatile__("movl %%ebx,%0" : "=m"(newregs->bx));
|
||||
__asm__ __volatile__("movl %%ecx,%0" : "=m"(newregs->cx));
|
||||
__asm__ __volatile__("movl %%edx,%0" : "=m"(newregs->dx));
|
||||
__asm__ __volatile__("movl %%esi,%0" : "=m"(newregs->si));
|
||||
__asm__ __volatile__("movl %%edi,%0" : "=m"(newregs->di));
|
||||
__asm__ __volatile__("movl %%ebp,%0" : "=m"(newregs->bp));
|
||||
__asm__ __volatile__("movl %%eax,%0" : "=m"(newregs->ax));
|
||||
__asm__ __volatile__("movl %%esp,%0" : "=m"(newregs->sp));
|
||||
__asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss));
|
||||
__asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs));
|
||||
__asm__ __volatile__("movl %%ds, %%eax;" :"=a"(newregs->ds));
|
||||
__asm__ __volatile__("movl %%es, %%eax;" :"=a"(newregs->es));
|
||||
__asm__ __volatile__("pushfl; popl %0" :"=m"(newregs->flags));
|
||||
|
||||
newregs->eip = (unsigned long)current_text_addr();
|
||||
newregs->ip = (unsigned long)current_text_addr();
|
||||
}
|
||||
}
|
||||
asmlinkage NORET_TYPE void
|
||||
|
|
|
@ -60,14 +60,14 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
|
|||
if (oldregs)
|
||||
memcpy(newregs, oldregs, sizeof(*newregs));
|
||||
else {
|
||||
__asm__ __volatile__("movq %%rbx,%0" : "=m"(newregs->rbx));
|
||||
__asm__ __volatile__("movq %%rcx,%0" : "=m"(newregs->rcx));
|
||||
__asm__ __volatile__("movq %%rdx,%0" : "=m"(newregs->rdx));
|
||||
__asm__ __volatile__("movq %%rsi,%0" : "=m"(newregs->rsi));
|
||||
__asm__ __volatile__("movq %%rdi,%0" : "=m"(newregs->rdi));
|
||||
__asm__ __volatile__("movq %%rbp,%0" : "=m"(newregs->rbp));
|
||||
__asm__ __volatile__("movq %%rax,%0" : "=m"(newregs->rax));
|
||||
__asm__ __volatile__("movq %%rsp,%0" : "=m"(newregs->rsp));
|
||||
__asm__ __volatile__("movq %%rbx,%0" : "=m"(newregs->bx));
|
||||
__asm__ __volatile__("movq %%rcx,%0" : "=m"(newregs->cx));
|
||||
__asm__ __volatile__("movq %%rdx,%0" : "=m"(newregs->dx));
|
||||
__asm__ __volatile__("movq %%rsi,%0" : "=m"(newregs->si));
|
||||
__asm__ __volatile__("movq %%rdi,%0" : "=m"(newregs->di));
|
||||
__asm__ __volatile__("movq %%rbp,%0" : "=m"(newregs->bp));
|
||||
__asm__ __volatile__("movq %%rax,%0" : "=m"(newregs->ax));
|
||||
__asm__ __volatile__("movq %%rsp,%0" : "=m"(newregs->sp));
|
||||
__asm__ __volatile__("movq %%r8,%0" : "=m"(newregs->r8));
|
||||
__asm__ __volatile__("movq %%r9,%0" : "=m"(newregs->r9));
|
||||
__asm__ __volatile__("movq %%r10,%0" : "=m"(newregs->r10));
|
||||
|
@ -78,9 +78,9 @@ static inline void crash_setup_regs(struct pt_regs *newregs,
|
|||
__asm__ __volatile__("movq %%r15,%0" : "=m"(newregs->r15));
|
||||
__asm__ __volatile__("movl %%ss, %%eax;" :"=a"(newregs->ss));
|
||||
__asm__ __volatile__("movl %%cs, %%eax;" :"=a"(newregs->cs));
|
||||
__asm__ __volatile__("pushfq; popq %0" :"=m"(newregs->eflags));
|
||||
__asm__ __volatile__("pushfq; popq %0" :"=m"(newregs->flags));
|
||||
|
||||
newregs->rip = (unsigned long)current_text_addr();
|
||||
newregs->ip = (unsigned long)current_text_addr();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ struct kprobe_ctlblk {
|
|||
*/
|
||||
static inline void restore_interrupts(struct pt_regs *regs)
|
||||
{
|
||||
if (regs->eflags & IF_MASK)
|
||||
if (regs->flags & IF_MASK)
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ struct kprobe_ctlblk {
|
|||
*/
|
||||
static inline void restore_interrupts(struct pt_regs *regs)
|
||||
{
|
||||
if (regs->eflags & IF_MASK)
|
||||
if (regs->flags & IF_MASK)
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#define MCG_CTL_P (1UL<<8) /* MCG_CAP register available */
|
||||
|
||||
#define MCG_STATUS_RIPV (1UL<<0) /* restart ip valid */
|
||||
#define MCG_STATUS_EIPV (1UL<<1) /* eip points to correct instruction */
|
||||
#define MCG_STATUS_EIPV (1UL<<1) /* ip points to correct instruction */
|
||||
#define MCG_STATUS_MCIP (1UL<<2) /* machine check in progress */
|
||||
|
||||
#define MCI_STATUS_VAL (1UL<<63) /* valid error */
|
||||
|
@ -30,7 +30,7 @@ struct mce {
|
|||
__u64 misc;
|
||||
__u64 addr;
|
||||
__u64 mcgstatus;
|
||||
__u64 rip;
|
||||
__u64 ip;
|
||||
__u64 tsc; /* cpu time stamp counter */
|
||||
__u64 res1; /* for future extension */
|
||||
__u64 res2; /* dito. */
|
||||
|
|
|
@ -398,14 +398,14 @@ struct thread_struct {
|
|||
|
||||
#define start_thread(regs, new_eip, new_esp) do { \
|
||||
__asm__("movl %0,%%gs": :"r" (0)); \
|
||||
regs->xfs = 0; \
|
||||
regs->fs = 0; \
|
||||
set_fs(USER_DS); \
|
||||
regs->xds = __USER_DS; \
|
||||
regs->xes = __USER_DS; \
|
||||
regs->xss = __USER_DS; \
|
||||
regs->xcs = __USER_CS; \
|
||||
regs->eip = new_eip; \
|
||||
regs->esp = new_esp; \
|
||||
regs->ds = __USER_DS; \
|
||||
regs->es = __USER_DS; \
|
||||
regs->ss = __USER_DS; \
|
||||
regs->cs = __USER_CS; \
|
||||
regs->ip = new_eip; \
|
||||
regs->sp = new_esp; \
|
||||
} while (0)
|
||||
|
||||
/* Forward declaration, a strange C thing */
|
||||
|
@ -440,7 +440,7 @@ unsigned long get_wchan(struct task_struct *p);
|
|||
* is accessable even if the CPU haven't stored the SS/ESP registers
|
||||
* on the stack (interrupt gate does not save these registers
|
||||
* when switching to the same priv ring).
|
||||
* Therefore beware: accessing the xss/esp fields of the
|
||||
* Therefore beware: accessing the ss/esp fields of the
|
||||
* "struct pt_regs" is possible, but they may contain the
|
||||
* completely wrong values.
|
||||
*/
|
||||
|
@ -451,8 +451,8 @@ unsigned long get_wchan(struct task_struct *p);
|
|||
__regs__ - 1; \
|
||||
})
|
||||
|
||||
#define KSTK_EIP(task) (task_pt_regs(task)->eip)
|
||||
#define KSTK_ESP(task) (task_pt_regs(task)->esp)
|
||||
#define KSTK_EIP(task) (task_pt_regs(task)->ip)
|
||||
#define KSTK_ESP(task) (task_pt_regs(task)->sp)
|
||||
|
||||
|
||||
struct microcode_header {
|
||||
|
|
|
@ -258,12 +258,12 @@ struct thread_struct {
|
|||
#define start_thread(regs,new_rip,new_rsp) do { \
|
||||
asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0)); \
|
||||
load_gs_index(0); \
|
||||
(regs)->rip = (new_rip); \
|
||||
(regs)->rsp = (new_rsp); \
|
||||
(regs)->ip = (new_rip); \
|
||||
(regs)->sp = (new_rsp); \
|
||||
write_pda(oldrsp, (new_rsp)); \
|
||||
(regs)->cs = __USER_CS; \
|
||||
(regs)->ss = __USER_DS; \
|
||||
(regs)->eflags = 0x200; \
|
||||
(regs)->flags = 0x200; \
|
||||
set_fs(USER_DS); \
|
||||
} while(0)
|
||||
|
||||
|
@ -297,7 +297,7 @@ extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
|
|||
|
||||
extern unsigned long get_wchan(struct task_struct *p);
|
||||
#define task_pt_regs(tsk) ((struct pt_regs *)(tsk)->thread.rsp0 - 1)
|
||||
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->rip)
|
||||
#define KSTK_EIP(tsk) (task_pt_regs(tsk)->ip)
|
||||
#define KSTK_ESP(tsk) -1 /* sorry. doesn't work for syscall. */
|
||||
|
||||
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
/* this struct defines the way the registers are stored on the
|
||||
stack during a system call. */
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
struct pt_regs {
|
||||
long ebx;
|
||||
long ecx;
|
||||
|
@ -21,7 +23,7 @@ struct pt_regs {
|
|||
int xds;
|
||||
int xes;
|
||||
int xfs;
|
||||
/* int xgs; */
|
||||
/* int gs; */
|
||||
long orig_eax;
|
||||
long eip;
|
||||
int xcs;
|
||||
|
@ -30,7 +32,27 @@ struct pt_regs {
|
|||
int xss;
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#else /* __KERNEL__ */
|
||||
|
||||
struct pt_regs {
|
||||
long bx;
|
||||
long cx;
|
||||
long dx;
|
||||
long si;
|
||||
long di;
|
||||
long bp;
|
||||
long ax;
|
||||
int ds;
|
||||
int es;
|
||||
int fs;
|
||||
/* int gs; */
|
||||
long orig_ax;
|
||||
long ip;
|
||||
int cs;
|
||||
long flags;
|
||||
long sp;
|
||||
int ss;
|
||||
};
|
||||
|
||||
#include <asm/vm86.h>
|
||||
#include <asm/segment.h>
|
||||
|
@ -47,27 +69,30 @@ extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int erro
|
|||
*/
|
||||
static inline int user_mode(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->xcs & SEGMENT_RPL_MASK) == USER_RPL;
|
||||
return (regs->cs & SEGMENT_RPL_MASK) == USER_RPL;
|
||||
}
|
||||
static inline int user_mode_vm(struct pt_regs *regs)
|
||||
{
|
||||
return ((regs->xcs & SEGMENT_RPL_MASK) | (regs->eflags & VM_MASK)) >= USER_RPL;
|
||||
return ((regs->cs & SEGMENT_RPL_MASK) |
|
||||
(regs->flags & VM_MASK)) >= USER_RPL;
|
||||
}
|
||||
static inline int v8086_mode(struct pt_regs *regs)
|
||||
{
|
||||
return (regs->eflags & VM_MASK);
|
||||
return (regs->flags & VM_MASK);
|
||||
}
|
||||
|
||||
#define instruction_pointer(regs) ((regs)->eip)
|
||||
#define frame_pointer(regs) ((regs)->ebp)
|
||||
#define instruction_pointer(regs) ((regs)->ip)
|
||||
#define frame_pointer(regs) ((regs)->bp)
|
||||
#define stack_pointer(regs) ((unsigned long)(regs))
|
||||
#define regs_return_value(regs) ((regs)->eax)
|
||||
#define regs_return_value(regs) ((regs)->ax)
|
||||
|
||||
extern unsigned long profile_pc(struct pt_regs *regs);
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#else /* __i386__ */
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
struct pt_regs {
|
||||
unsigned long r15;
|
||||
unsigned long r14;
|
||||
|
@ -96,14 +121,43 @@ struct pt_regs {
|
|||
/* top of stack page */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#else /* __KERNEL__ */
|
||||
|
||||
struct pt_regs {
|
||||
unsigned long r15;
|
||||
unsigned long r14;
|
||||
unsigned long r13;
|
||||
unsigned long r12;
|
||||
unsigned long bp;
|
||||
unsigned long bx;
|
||||
/* arguments: non interrupts/non tracing syscalls only save upto here*/
|
||||
unsigned long r11;
|
||||
unsigned long r10;
|
||||
unsigned long r9;
|
||||
unsigned long r8;
|
||||
unsigned long ax;
|
||||
unsigned long cx;
|
||||
unsigned long dx;
|
||||
unsigned long si;
|
||||
unsigned long di;
|
||||
unsigned long orig_ax;
|
||||
/* end of arguments */
|
||||
/* cpu exception frame or undefined */
|
||||
unsigned long ip;
|
||||
unsigned long cs;
|
||||
unsigned long flags;
|
||||
unsigned long sp;
|
||||
unsigned long ss;
|
||||
/* top of stack page */
|
||||
};
|
||||
|
||||
#define user_mode(regs) (!!((regs)->cs & 3))
|
||||
#define user_mode_vm(regs) user_mode(regs)
|
||||
#define instruction_pointer(regs) ((regs)->rip)
|
||||
#define frame_pointer(regs) ((regs)->rbp)
|
||||
#define stack_pointer(regs) ((regs)->rsp)
|
||||
#define regs_return_value(regs) ((regs)->rax)
|
||||
#define v8086_mode(regs) 0 /* No V86 mode support in long mode */
|
||||
#define instruction_pointer(regs) ((regs)->ip)
|
||||
#define frame_pointer(regs) ((regs)->bp)
|
||||
#define stack_pointer(regs) ((regs)->sp)
|
||||
#define regs_return_value(regs) ((regs)->ax)
|
||||
|
||||
extern unsigned long profile_pc(struct pt_regs *regs);
|
||||
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
|
||||
|
|
|
@ -733,13 +733,13 @@ static void print_fatal_signal(struct pt_regs *regs, int signr)
|
|||
current->comm, task_pid_nr(current), signr);
|
||||
|
||||
#if defined(__i386__) && !defined(__arch_um__)
|
||||
printk("code at %08lx: ", regs->eip);
|
||||
printk("code at %08lx: ", regs->ip);
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
unsigned char insn;
|
||||
|
||||
__get_user(insn, (unsigned char *)(regs->eip + i));
|
||||
__get_user(insn, (unsigned char *)(regs->ip + i));
|
||||
printk("%02x ", insn);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue