byWind
byWind

Reputation: 21

Which stack does hardware interrupt use?

I don't quite understand the interrupt stack switch mechanism in x86_64. From Intel's developer's manual, when a hardware interrupt occurs, the current context will be stored on interrupt stack for later iret use. I have the following questions:

  1. Is this stack hardirq_stack in Linux kernel? If it is, this stack is also used by softirq; so how does the stack keep consistency when an interrupt occurs during handling softirq? If it is not, which stack is used?
  2. Only a part of the context is saved on the stack (e.g., RSP, CS, RIP), what about the other part (e.g., registers)?

Upvotes: 2

Views: 963

Answers (1)

user123
user123

Reputation: 2884

If you read the following: https://www.kernel.org/doc/Documentation/x86/kernel-stacks, you have information on what Linux does for the different stacks.

Like all other architectures, x86_64 has a kernel stack for every active thread.

This means that each process/thread has one kernel stack which is used to handle syscalls. The libstdc++/libc (standard C++/C implementations) use the syscall assembly instruction directly to make system calls. The entry point to the kernel is arch/x86/entry/entry_64.S. This assembly file will switch the stack of the user mode process to its kernel counterpart. This is during a syscall not during an external interrupt. This paragraph is just to clear misconceptions.

In addition to the per thread stacks, there are specialized stacks associated with each CPU. These stacks are only used while the kernel is in control on that CPU; when a CPU returns to user space the specialized stacks contain no useful data. The main CPU stacks are:

  • Interrupt stack. IRQ_STACK_SIZE

Used for external hardware interrupts. If this is the first external hardware interrupt (i.e. not a nested hardware interrupt) then the kernel switches from the current task to the interrupt stack. Like the split thread and interrupt stacks on i386, this gives more room for kernel interrupt processing without having to increase the size of every per thread stack.

The interrupt stack is also used when processing a softirq.

Switching to the kernel interrupt stack is done by software based on a per CPU interrupt nest counter.

This means that each CPU has some specialized stacks which are used to handle some special events. The specialized stacks don't contain valid data when in user mode.

The kernel maintains a nest counter (interrupt of an interrupt). If the nest counter is 0, it will switch the user mode stack to the interrupt kernel stack. Otherwise, it will remain on the same stack.

Is this stack hardirq_stack in Linux kernel? If it is, this stack is also used by softirq; so how does the stack keep consistency when an interrupt occurs during handling softirq? If it is not, which stack is used?

The stack used is the interrupt stack for both the hardirq (hardware irq) and softirq (software irq). The stack remains consistent because the irq handler pushes all registers that could be used by a nested interrupt and maintains a nest counter. The TSS is used for irq going from ring 3 to ring 0 to switch the stacks. This is necessary because the switch to kernel mode (ring 0) cannot be done by software. It must be done by hardware. The TSS is a mechanism which allows safe switch to kernel mode on interrupt.

Only a part of the context is saved on the stack (e.g., RSP, CS, RIP), what about the other part (e.g., registers)?

The registers are also saved on the stack.

Upvotes: 1

Related Questions