我已经阅读了有关Linux如何在每个内核的编译时间确定异常堆栈仅为4KB的情况下如何在每个CPU上使用硬IRQ堆栈和软IRQ堆栈的信息。
现在,我知道在8KB内核模式堆栈的情况下,当CPU在IDT中查找中断处理程序并发现需要更改特权时,他会从TSS获取内核模式堆栈的地址。过程的一部分。 同样在4KB内核模式堆栈的情况下,CPU从TSS段获取异常堆栈的地址。
我不清楚的是在处理中断的情况下CPU如何获取hard_irq堆栈或soft_irq堆栈的地址。
有人可以向我解释吗?
答案 0 :(得分:0)
在将cpu寄存器保存到堆栈后立即调用的do_IRQ()函数中,检查当前中断处理程序执行的堆栈是否为硬IRQ堆栈。它是通过以下代码(摘自https://elixir.bootlin.com/linux/latest/source/arch/powerpc/kernel/irq.c#L659)
void *cursp, *irqsp, *sirqsp;
cursp = (void *)(current_stack_pointer() & ~(THREAD_SIZE - 1));
irqsp = hardirq_ctx[raw_smp_processor_id()];
sirqsp = softirq_ctx[raw_smp_processor_id()];
/* Already there ? */
if (unlikely(cursp == irqsp || cursp == sirqsp)) {
__do_irq(regs);
set_irq_regs(old_regs);
return;
}
如果它尚未在硬IRQ堆栈中执行,那么它将不在异常堆栈中执行,因为这是TSS段包含的堆栈(能够切换到内核模式)。 在那种情况下,函数将明确切换到该堆栈。
注意:
如果在处理另一个中断的过程中发生了中断,则处理程序可能在硬IRQ堆栈中开始执行,因此对另一个堆栈没有任何更改,因为CPU已经在内核模式下执行了。