From 3ce94072b438eb55d835e517fdc6c6e5a8f63c32 Mon Sep 17 00:00:00 2001 From: "Balazs Gerofi bgerofi@riken.jp" Date: Wed, 2 Apr 2014 14:02:20 +0900 Subject: [PATCH] save/restore rbp when entering/leaving kernel (required for fork() in glibc) --- arch/x86/kernel/include/registers.h | 2 +- arch/x86/kernel/interrupt.S | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/include/registers.h b/arch/x86/kernel/include/registers.h index c12925b6..94f1f68b 100644 --- a/arch/x86/kernel/include/registers.h +++ b/arch/x86/kernel/include/registers.h @@ -137,7 +137,7 @@ struct tss64 { struct x86_regs { unsigned long r11, r10, r9, r8; - unsigned long rdi, rsi, rdx, rcx, rbx, rax; + unsigned long rdi, rsi, rdx, rcx, rbx, rax, rbp; unsigned long error, rip, cs, rflags, rsp, ss; }; diff --git a/arch/x86/kernel/interrupt.S b/arch/x86/kernel/interrupt.S index da0d87c6..e814afa4 100644 --- a/arch/x86/kernel/interrupt.S +++ b/arch/x86/kernel/interrupt.S @@ -8,6 +8,9 @@ */ /* * HISTORY + * + * 2014/04 - bgerofi: save/restore rbp when entering/leaving kernel (for glibc) + * 2013/?? - bgerofi + shimosawa: handle rsp correctly for nested interrupts */ #define X86_CPU_LOCAL_OFFSET_TSS 128 @@ -22,6 +25,7 @@ #define USER_DS (56 + 3) #define PUSH_ALL_REGS \ + pushq %rbp; \ pushq %rax; \ pushq %rbx; \ pushq %rcx; \ @@ -42,7 +46,8 @@ popq %rdx; \ popq %rcx; \ popq %rbx; \ - popq %rax + popq %rax; \ + popq %rbp .data .globl generic_common_handlers @@ -62,7 +67,7 @@ vector=vector+1 common_interrupt: PUSH_ALL_REGS - movq 80(%rsp), %rdi + movq 88(%rsp), %rdi movq %rsp, %rsi call handle_interrupt /* Enter C code */ POP_ALL_REGS @@ -78,7 +83,7 @@ page_fault: cld PUSH_ALL_REGS movq %cr2, %rdi - movq 80(%rsp),%rsi + movq 88(%rsp),%rsi movq %rsp,%rdx movq __page_fault_handler_address(%rip), %rax andq %rax, %rax