为什么需要将flags参数作为堆栈变量传递给local_irq_save?

时间:2017-01-09 07:46:56

标签: linux-kernel

Robert Love" Linux内核开发"本书说我们需要将标志作为堆栈变量传递给local_irq_save()

为什么需要这个?可以在x86中绕过这个要求吗?

1 个答案:

答案 0 :(得分:0)

您可能会参考LKD3的这句话:

local_irq_save(flags);    /* interrupts are now disabled */
/* ... */
local_irq_restore(flags); /* interrupts are restored to their previous state */
     

请注意,这些方法至少部分实现为宏,因此标志   参数(必须定义为unsigned long)似乎是按值传递的。   此参数包含特定于体系结构的数据,其中包含中断系统的状态。因为至少有一个支持的体系结构将堆栈信息合并到了   value(ahem, SPARC ),标志不能传递给另一个函数(具体来说,它必须保留在同一个堆栈帧中)。因此,保存调用和恢复中断的调用必须在同一个函数中进行。

我没有看到要在堆栈上声明flags变量的任何要求。 书中说的是:

  • 某些体系结构(例如SPARC)在执行flags时向local_irq_save()变量添加一些特定于堆栈的信息以及中断信息
  • 所以你不应该将flags变量传递给另一个函数
  • 您应该在同一堆栈框架中运行local_irq_save() / local_irq_restore()

你必须对这句话感到困惑:

  

具体来说,它必须保持在同一个堆栈框架

我会稍微改变一下:

  

具体而言,它必须保留在保存/恢复呼叫

之间的相同堆栈帧

不仅如此,如果你这样做:

$ git grep --all-match -e 'local_irq_save(\*' -- kernel/ include/linux/

你会发现即使是核心内核代码也会在堆上声明flags

至于SPARC架构上提到的实现:book可能是指this代码。因此,在SPARC体系结构中,flags变量将包含PSR寄存器,而该寄存器又包含CWP字段,它可能与堆栈有关,不知何故。

  

是否可以在x86中绕过此要求?

当您编写与体系结构无关的代码(如驱动程序)时,您应该考虑所有体系结构上的行为。因此,在使用独立于架构的API时,通常不应该考虑某些特定平台上的怪癖。但同样,您可以随时在堆上声明flags