131
社区成员




Dovetail通过对中断屏蔽的虚拟化,其实是放弃了对CPU物理中断开关的操纵,并且只是操纵内存中特殊结构的一个比特位INBAND_STALL_BIT来表示中断的开关。
在关中断的时候,设置了INBAND_STALL_BIT。
static __always_inline void stall_inband_nocheck(void)
{
__set_bit(INBAND_STALL_BIT, ¤t->stall_bits);
barrier();
}
/**
* inband_irq_disable - disable interrupts for the inband stage
*
* Disable interrupts for the inband stage, disabling in-band
* interrupts. Out-of-band interrupts can still be taken and
* delivered to their respective handlers though.
*/
notrace void inband_irq_disable(void)
{
check_inband_stage();
stall_inband_nocheck();
}
static inline notrace void arch_local_irq_disable(void)
{
inband_irq_disable();
barrier();
}
在打开中断的时候清掉了对应的bit 位 INBAND_STALL_BIT
static __always_inline void unstall_inband_nocheck(void)
{
barrier();
__clear_bit(INBAND_STALL_BIT, ¤t->stall_bits);
}
/**
* inband_irq_disable - disable interrupts for the inband stage
*
* Disable interrupts for the inband stage, disabling in-band
* interrupts. Out-of-band interrupts can still be taken and
* delivered to their respective handlers though.
*/
notrace void inband_irq_disable(void)
{
check_inband_stage();
stall_inband_nocheck();
}
static inline notrace void arch_local_irq_disable(void)
{
inband_irq_disable();
barrier();
}
对CPU状态寄存器的中断位的虚拟化,也是通过利用这个BIT来实现的。
static inline notrace
unsigned long arch_irqs_virtual_to_native_flags(int stalled)
{
return (!stalled) << X86_EFLAGS_IF_BIT;
}
static __always_inline int test_and_stall_inband_nocheck(void)
{
return __test_and_set_bit(INBAND_STALL_BIT, ¤t->stall_bits);
}
/**
* inband_irq_save - test and disable (virtual) interrupts
*
* Save the virtual interrupt state then disables interrupts for
* the inband stage.
*
* Returns the original interrupt state.
*/
trace_on_debug unsigned long inband_irq_save(void)
{
check_inband_stage();
return test_and_stall_inband_nocheck();
}
EXPORT_SYMBOL(inband_irq_save);
static inline notrace unsigned long arch_local_irq_save(void)
{
int stalled = inband_irq_save();
barrier();
return arch_irqs_virtual_to_native_flags(stalled);
}
通过test_and_stall_inband_nocheck获取到这个BIT是否设置,然后把它的状态虚拟成CPU状态寄存器的中断状态位。