2017-10-16 80 views
0

我正在努力正确实现内核螺旋锁与返回语句的结合,该语句应该向用户空间返回一个值。我实现了一个内核系统调用“sys_kernel_entropy_is_recording”这应该返回的内核变量“is_kernel_entropy_recording”的值:使用螺旋锁返回值给用户空间的linux系统调用

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)返回语句位于之前 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 

因此,我猜自旋锁的应用是不正确的..可能有人请给我一个建议为了一个合适的方法? 非常感谢!

+0

至于反汇编代码,'callq'实际上是一个函数调用。在你的情况下,它可能会调用'spin_lock'(或者'spin_lock'是一个宏或一个内联函数,它调用它的内*函数*)。您可以通过要求gdb将重定位应用于反汇编代码来检查。至于'spin_unlock'调用,编译器可能会发现它是* unreachable *,并简单地删除它。 – Tsyvarev

+0

作为一个便笺,你有没有考虑过使用_atomics_来锁定一个变量 – myaut

+0

“return”语句无法访问后的代码。我很惊讶你没有得到编译器的警告(不是吗?) – Kaz

回答

2

禁止使用spinlock从系统调用返回。并且,与通常的C代码一样,在return语句后没有执行任何指令。

常见的做法是,以节省下锁得到的数值为局部变量,并解锁后返回该变量的值:

bool ret; 

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

return ret;