使用向用户空间返回值的自旋锁的linux系统调用

使用向用户空间返回值的自旋锁的linux系统调用,linux,kernel,spinlock,kernel-mode,userspace,Linux,Kernel,Spinlock,Kernel Mode,Userspace,我目前正在努力将内核自旋锁与返回语句结合起来正确实现,该语句应该向用户空间返回一个值。我实现了一个内核系统调用“sys\u kernel\u entropy\u is\u recording”,它应该返回内核变量“is\u kernel\u entropy\u recording”的值: asmlinkage bool sys_kernel_entropy_is_recording(void) { spin_lock(&entropy_analysis_l

我目前正在努力将内核自旋锁与返回语句结合起来正确实现,该语句应该向用户空间返回一个值。我实现了一个内核系统调用“sys\u kernel\u entropy\u is\u recording”,它应该返回内核变量“is\u kernel\u entropy\u 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\u kernel\u entropy\u recording”的正确值是否会返回到用户空间,然后释放自旋锁

我关注的是:

  • a) 是否允许以这种方式将值从kernelspace返回到userspace
  • b) return语句位于spin_unlock语句之前,因此会调用spin_unlock吗
Q2:为了自己回答这些问题,我对编译的.o文件进行了反汇编,但确定(至少在我看来)编译器完全忽略了spin_lock/spin_unlock调用,因为它只是将“sys_kernel_entropy_is_recording”的值移动到eax和calls ret(我不确定行“callq 0xa5”):

(gdb)反汇编/m系统内核熵正在记录
函数sys\u kernel\u entropy\u的汇编代码转储正在记录:
49  {
0x00000000000000a0:callq 0xa5
0x00000000000000a5:推送%rbp
0x00000000000000ad:mov%rsp,%rbp
50自旋锁(熵分析锁);
51返回为内核熵记录;
52自旋解锁(熵分析锁定);
53  }
0x00000000000000b5:movzbl0x0(%rip),%eax#0xbc
0x00000000000000bc:弹出%rbp
0x00000000000000bd:retq
因此,我猜spinlock的应用是不正确的。。有人能给我一个合适的建议吗?
提前多谢

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

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

bool ret;

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

return ret;

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

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

bool ret;

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

return ret;

对于反汇编代码,
callq
实际上是一个函数调用。在您的情况下,它可能会调用
spin\u lock
(或者,如果
spin\u lock
是宏或内联函数,它会调用其内部函数)。您可以通过要求gdb对反汇编代码应用重定位来检查这一点。至于
spin\u unlock
调用,编译器可能会发现它不可访问,并简单地将其删除。作为补充说明,您是否考虑过在
return
语句不可访问后使用原子锁定单个可变代码。我很惊讶你没有收到编译器警告(不是吗?)至于反汇编代码,
callq
实际上是一个函数调用。在您的情况下,它可能会调用
spin\u lock
(或者,如果
spin\u lock
是宏或内联函数,它会调用其内部函数)。您可以通过要求gdb对反汇编代码应用重定位来检查这一点。至于
spin\u unlock
调用,编译器可能会发现它不可访问,并简单地将其删除。作为补充说明,您是否考虑过在
return
语句不可访问后使用原子锁定单个可变代码。我很惊讶你没有收到编译器警告(不是吗?)