В функции 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, если прерывание произошло во время обработки другого прерывания, и, следовательно, не было никаких изменений в другом стеке, поскольку ЦП уже выполнялся в режиме ядра.