【问题标题】:Linux Kernel should I use asmlinkage for a function that implements a system call?Linux Kernel 我应该将 asmlinkage 用于实现系统调用的函数吗?
【发布时间】:2021-08-01 05:44:45
【问题描述】:

我正在尝试在 linux 内核中实现一个新的系统调用,所以我写道:

asmlinkage int my_func(void) {
    return my_func_internal();
}

我的问题,我应该将my_func_internal 定义为 asmlinkage 吗?

换句话说,我应该写A还是B?

A)asmlinkage int my_func_internal(void) {return 1;}

B)int my_func_internal(void) {return 1;}

我也想解释一下

注意:我已将 my_func 添加到 syscalls.h 中,我是否也应该添加内部的(可能答案是否定的)

【问题讨论】:

  • 与其直接用asmlinkage 声明系统调用函数,不如使用SYSCALL_DEFINE 宏,例如SYSCALL_DEFINE0(my_func){return my_func_internal();}。这是与使用系统调用包装器的架构兼容所必需的。注意:宏会将函数的名称设置为sys_my_func,除非它使用系统调用包装器,在这种情况下,名称将以_my_func 结尾。

标签: c assembly linux-kernel system-calls calling-convention


【解决方案1】:

对于不通过手写 asm直接调用的函数使用什么调用约定并不重要(为了正确性)。 (哪些系统调用实现函数可能在某些架构上,这就是为什么它们应该是asmlinkage。)只要所有调用者都能看到与定义匹配的原型,它就可以工作。

如果asmlinkinkage 是与默认调用约定不同的调用约定(例如,在 i386 上,asmlinkage 表示使用堆栈参数,覆盖使内部函数使用寄存器参数的 -mregparm=3 构建选项),编译器将具有为my_func 发出一个定义,如果它调用一个不是asmlinkage 的函数来处理差异。或者简单地将my_func_internal() 内联到其中。

如果它们使用相同的调用约定,并且编译器选择不内联,它可以只对my_func_internal 进行优化的尾调用,例如在 x86 jmp my_func_internal。因此,使用相同的调用约定可能会带来效率优势如果存在优化尾调用的可能性。否则不要; asmlinkage 使 i386 上的调用约定效率降低。

(IIRC, asmlinkage 对 x86-64 和大多数其他具有 register-args 调用约定的现代 ISA 没有影响;x86 上的默认调用约定已经很好,因此内核不需要用 @987654332 覆盖它@ 就像在 i386 上一样。)

在没有参数的示例中,没有区别。


顺便说一句,函数名称的通常命名约定是sys_foo,以实现称为foo 的系统调用。即当用户空间传递 __NR_foo 作为调用号时将调用的函数。


注意:我已经将 my_func 添加到 syscalls.h 中,我是否也应该添加内部的(可能答案是否定的)

当然不是,除非my_func_internal 实现了一个不同的系统调用,你希望用户空间能够直接调用。

【讨论】:

  • 所以为了安全起见,我应该添加“asmlinkage”以防我不关心性能? (我不能用 inline 代替还是错了,忘了说 my_func_internal 是递归函数)
  • @mr_calc:不,在foo_internal 上使用asmlinkage 完全没有正确的理由。除非您将其添加到系统调用表中,以便用户空间可以直接调用它,从而实现不同的系统调用。假设您不想这样做,请尽可能使用static foo_internal 来鼓励编译器内联,尤其是在只有一个调用者的情况下。
  • 所以你能写一个最后的建议吗,你在这里提到了很多静态而不是静态的东西。是的,这是我调用内部函数的唯一方法,它只被 my_func 调用一次
  • @mr_calc:我假设您了解static 在普通 C 中的含义,并且您通常希望在可能的情况下将其用于函数(即,使它们仅在单个文件中可见)。所以是的,在你的情况下,让它static int foo_internal(void)
猜你喜欢
  • 2016-05-25
  • 1970-01-01
  • 2019-09-04
  • 2012-09-19
  • 2014-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
相关资源
最近更新 更多