【问题标题】:linux syscall using spinlock returning value to userspacelinux系统调用使用自旋锁将值返回给用户空间
【发布时间】:2017-10-16 18:06:41
【问题描述】:

我目前正在努力正确实现内核自旋锁以及应该向用户空间返回值的返回语句。我实现了一个内核系统调用“sys_kernel_entropy_is_recording”,它应该返回一个内核变量“is_kernel_entropy_recording”的值:

    asmlinkage bool sys_kernel_entropy_is_recording(void)
    {
        spin_lock(&entropy_analysis_lock);
        return is_kernel_entropy_recording;
        spin_unlock(&entropy_analysis_lock);
    }

此时出现两个问题:

Q1:这个实现是否正确,意味着'is_kernel_entropy_recording'的正确值会返回到用户空间,然后释放自旋锁?

我的担忧是:

  • a) 是否允许以这种方式将值从内核空间返回到用户空间?
  • b) return 语句位于spin_unlock 语句之前,因此spin_unlock 会被调用吗?

Q2:为了自己回答这些问题,我反汇编了编译后的 .o 文件,但确定(至少在我看来)spin_lock/spin_unlock 调用被编译器完全忽略,因为它只是将 'sys_kernel_entropy_is_recording' 的值移动到 eax 调用 ret(我不确定行 'callq 0xa5'):

    (gdb) disassemble /m sys_kernel_entropy_is_recording
    Dump of assembler code for function sys_kernel_entropy_is_recording:
    49  {
       0x00000000000000a0 <+0>: callq  0xa5 <sys_kernel_entropy_is_recording+5>
       0x00000000000000a5 <+5>: push   %rbp
       0x00000000000000ad <+13>:    mov    %rsp,%rbp

    50      spin_lock(&entropy_analysis_lock);
    51      return is_kernel_entropy_recording;
    52      spin_unlock(&entropy_analysis_lock);
    53  }
       0x00000000000000b5 <+21>:    movzbl 0x0(%rip),%eax        # 0xbc <sys_kernel_entropy_is_recording+28>
       0x00000000000000bc <+28>:    pop    %rbp
       0x00000000000000bd <+29>:    retq 

因此我猜自旋锁的应用是不正确的。有人可以给我一个合适的方法的建议吗? 提前非常感谢!

【问题讨论】:

  • 反汇编代码,callq其实是一个函数调用。在您的情况下,它可能会调用spin_lock(或者,如果spin_lock 是宏或内联函数,它会调用其内部函数)。您可以通过要求 gdb 对反汇编代码应用重定位来检查这一点。至于spin_unlock 调用,编译器可能会发现它为无法访问,然后直接将其丢弃。
  • 作为旁注,您是否考虑过使用 atomics 来锁定单个变量
  • return 语句之后的代码无法访问。我很惊讶您没有收到编译器警告(不是吗?)

标签: linux kernel spinlock kernel-mode userspace


【解决方案1】:

禁止从持有自旋锁的系统调用返回。而且,与 C 代码一样,return 语句之后不会执行任何指令。

通常的做法是将lock下得到的值保存到局部变量中,解锁后返回这个变量的值:

bool ret;

spin_lock(&entropy_analysis_lock);
ret = is_kernel_entropy_recording;
spin_unlock(&entropy_analysis_lock);

return ret;

【讨论】:

    猜你喜欢
    • 2012-02-11
    • 2017-12-30
    • 2014-08-02
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    相关资源
    最近更新 更多