On Wed, Feb 19, 2020 at 04:57:15PM +0100, Peter Zijlstra wrote: > Something like so, I suppose... > > diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c > index 6ef00eb6fbb9..543de932dc7c 100644 > --- a/arch/x86/kernel/traps.c > +++ b/arch/x86/kernel/traps.c > @@ -350,14 +350,20 @@ dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code, unsign > regs->ip == (unsigned long)native_irq_return_iret) > { > struct pt_regs *gpregs = (struct pt_regs *)this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1; > + unsigned long *dst = &gpregs->ip; > + unsigned long *src = (void *)regs->dp; > + int i, count = 5; > > /* > * regs->sp points to the failing IRET frame on the > * ESPFIX64 stack. Copy it to the entry stack. This fills > * in gpregs->ss through gpregs->ip. > - * > */ > - memmove(&gpregs->ip, (void *)regs->sp, 5*8); > + for (i = 0; i < count; i++) { > + int idx = (dst <= src) ? i : count - i; That's an off-by-one for going backward; 'count - 1 - i' should work better, or I should just stop typing for today ;-) > + dst[idx] = src[idx]; > + } > + > gpregs->orig_ax = 0; /* Missing (lost) #GP error code */ > > /*