Skip to content

IRQs

struct irq_action (3 fields) source
§ irq_handler_t handler
§ void *data
§ struct list_node list
struct irq_chip (6 fields) source
§ const char *name
§ void (*mask)(struct irq_desc *)
§ void (*unmask)(struct irq_desc *)
§ void (*eoi)(struct irq_desc *)
§ void (*set_affinity)(struct irq_desc *, struct cpu_mask *)
§ int (*set_rate_limit)(struct irq_desc *, time_us_t interval)
struct irq_desc (11 fields) source
§ uint8_t vector
§ enum irq_flags flags
§ const char *name
§ struct irq_chip *chip
§ void *chip_data
§ struct list_head actions
§ struct cpu_mask affinity
§ struct cpu_mask masked_cpus
§ bool present

Have we set handlers?

§ bool allocated

Has this been allocated?

§ bool enabled
struct irq_registers (21 fields) source
§ uint64_t rax
§ uint64_t rbx
§ uint64_t rcx
§ uint64_t rdx
§ uint64_t rbp
§ uint64_t rdi
§ uint64_t rsi
§ uint64_t r8
§ uint64_t r9
§ uint64_t r10
§ uint64_t r11
§ uint64_t r12
§ uint64_t r13
§ uint64_t r14
§ uint64_t r15
§ uint64_t error_code
§ uint64_t rip
§ uint64_t cs
§ uint64_t rflags
§ uint64_t rsp
§ uint64_t ss
struct irq_context (4 fields) source
§ irq_t vector
§ struct irq_registers *regs
§ uint8_t *irq_stack_scratch_buf

This scratch buffer is stack allocated, and is set upon IRQ entry, allowing the top half of the IRQ to modify it

For exception_sync_cb, it is passed into the callback as a parameter

§ enum irql irq_entered_irql

Remains valid in the top half, once the bottom half is reached, this becomes IRQL_NONE

What IRQL were we at before entering an ISR (if !in_interrupt, this should be IRQL_NONE

enum irq_result (2 variants) source
§ IRQ_NONE = 0
§ IRQ_HANDLED = 1
enum irq_flags (4 variants) source
§ IRQ_FLAG_SHARED = 1

IRQ is shared between things

§ IRQ_FLAG_LEVEL_TRIGGERED = 1 << 1
§ IRQ_FLAG_EDGE_TRIGGERED = 1 << 2
§ IRQ_FLAG_NONE = 0
typedef enum irq_result (*irq_handler_t)(
    struct irq_context * ictx,
    void * ctx
)
source
void irq_context_to_crash_regs(
    const struct irq_registers *ictx,
    struct crash_regs *out
)
source
void irq_register(
    char *name,
    uint8_t vector,
    irq_handler_t handler,
    void *ctx,
    enum irq_flags flags
)
source
void irq_register_full(struct irq_desc *d)
source
void irq_set_chip(uint8_t vector, struct irq_chip *chip, void *data)
source
uint32_t irq_mark_self_in_interrupt(bool new)
source

We DO NOT set _IRQ here because _NONE is used as this set of functions will set the flags _NONE checks

uint32_t irq_mark_self_in_nmi(bool new)
source
cc_pure bool irq_in_nmi(void)
source

These are called from the verification logic, they are simple reads. cc_pure so assume() accepts it: NMI nesting is balanced, so it is invariant from the interrupted code’s point of view

bool irq_in_interrupt(void)
source
bool irq_not_in_interrupt(void)
source
bool irq_vector_is_exception(uint8_t vector)
source
void irq_set_alloc(int32_t entry, bool used)
source
int32_t irq_alloc_entry(void)
source
void irq_free_entry(int32_t entry)
source
bool irq_is_installed(int32_t entry)
source
void irq_free_entry(int32_t entry)
source
void irq_vector_disable(irq_t irq)
source
void irq_vector_enable(irq_t irq)
source
#define IRQ_DIV_BY_Z 0x0
source
#define IRQ_DEBUG 0x1
source
#define IRQ_NMI 0x2
source
#define IRQ_BREAKPOINT 0x3
source
#define IRQ_DBF 0x8
source
#define IRQ_SSF 0xC
source
#define IRQ_GPF 0xD
source
#define IRQ_PAGE_FAULT 0xE
source
#define IRQ_TIMER 0x20
source
#define IRQ_TLB_SHOOTDOWN 0x22
source
#define IRQ_SCHEDULER 0x23
source
#define IRQ_NOP 0x24
source
#define IRQ_DPC 0x25
source
#define IRQ_EXCEPTION_COUNT 32
source