title: Making a call to a kernel module function while context saving/restoring using SWAPGS instruction?
body: <p>I'm currently working on a project where a function "A" inside the linux kernel makes a call to another function "B" in a kernel module. </p>
  
  <p>The basic idea was to provide the address of the target function "B" in the kernel module, via a newly-created syscall which writes the received address to a kernel global variable. Function "A" reads this value and makes a call to that address.</p>
  
  <p>Calling function "B" turned out to be a success, as we verified by inserting a bunch of printk's at the prolog of the function "B".</p>
  
  <p>But the system freezes a while after function "B" is called, presumably because only the control flow is transferred from the kernel to the kernel module so all the other context (stack frame, etc) remains the same as it was in the kernel function "A"</p>
  
  <p>By going through some references, I wrote some x86_64 asm code that should save/restore the context.</p>
  
  <pre><code>    .macro SAVE
          swapgs
          mov (old_rsp), %r11
          mov %rsp,%gs:(%r11)
          mov (kernel_stack), %r11
          mov %gs:(%r11),%rsp
          sti
  
          sub $0x50,%rsp
          mov 0x50(%rsp),%rcx
          mov 0x48(%rsp),%rbx
          mov (%rsp),%r11
          mov 0x8(%rsp),%r10
          mov 0x10(%rsp),%r9
          mov 0x18(%rsp),%r8
          mov 0x20(%rsp),%rax
          mov 0x30(%rsp),%rdx
          mov 0x38(%rsp),%rsi
          mov 0x40(%rsp),%rdi
      .endm
  
      .macro RESTORE
          cli
          mov %rdi,0x40(%rsp)
          mov %rsi,0x38(%rsp)
          mov %rdx,0x30(%rsp)
          mov %rax,0x20(%rsp)
          mov %r8,0x18(%rsp)
          mov %r9,0x10(%rsp)
          mov %r10,0x8(%rsp)
          mov %r11,(%rsp)
          mov %rbx,0x48(%rsp)
          mov %rcx,0x50(%rsp)
  
          add $0x50,%rsp
          mov (old_rsp), %r11
          mov %gs:(%r11),%rsp
          jmp *syscall_after_swapgs
      .endm
  </code></pre>
  
  <p>the values old_rsp and kernel_stack are PER_CPU_VAR's in the kernel symbol. (linux 3.14)
  SAVE goes right before calling B, and RESTORE comes right after that.
  But the system still freezes.</p>
  
  <p>Is there something I'm getting wrong? Or some problem in the code perhaps?</p>
  
  <p>Thanks in advance..</p>