이 코드는 어떤 문제를 푸나요?
장치가 인터럽트를 발생시키면 CPU는 GIC에서 어떤 인터럽트인지 확인하고 Linux IRQ 체계에 전달합니다. 하드웨어 번호와 Linux가 관리하는 번호는 같은 숫자라고 가정할 수 없습니다. 아래 함수는 이미 읽은 번호를 받아 특수 번호를 거르고 irq domain으로 처리기를 찾는 구간입니다.
읽을 범위: v6.18.37 · drivers/irqchip/irq-gic-v3.c · __gic_handle_irq 867–878행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.
먼저 알아둘 개념
INTID와 Linux IRQ
INTID는 GIC가 다루는 하드웨어 인터럽트 식별자입니다. irq domain은 이를 Linux의 IRQ 관리 자료와 연결하므로 두 번호를 구분해야 합니다.
acknowledge와 완료
인터럽트를 수락하고 우선순위·active 상태를 다루는 과정은 장치 원인을 제거하는 것과 다릅니다. GIC 상태와 장치 상태를 모두 맞춰야 같은 요청이 반복되는 것을 이해할 수 있습니다.
특수 인터럽트 번호
GIC에는 실제 장치 처리기로 보낼 일반 번호 외에 특수 상태를 나타내는 번호가 있습니다. 그런 값에 일반 domain 처리를 무조건 적용하면 안 됩니다.
처음 읽을 때
장치 → GIC INTID → irq domain → Linux 처리기라는 연결을 그려 보세요. 화살표는 신호·번호 해석의 단계이며 장치 데이터가 이 길로 복사된다는 뜻은 아닙니다.
더 깊이 살펴볼 때
gic_complete_ack와 gic_deactivate_unhandled를 실제 EOI 모드별 구현에 연결해 보세요. 우선순위 drop, interrupt deactivation, 장치 원인 제거의 시점은 같은 한 단계로 줄일 수 없습니다.
그림으로 보는 변화

1. 번호 유효성 구분
특수 INTID이면 일반 처리를 생략
화살표는 이미 읽은 irqnr의 처리 흐름입니다. IAR 읽기는 이 함수 밖에서 이루어집니다.
2. 수락 상태 정리
gic_complete_ack(irqnr)
GIC의 상태 전이를 진행합니다. 장치의 인터럽트 원인 레지스터를 여기서 직접 지운다는 뜻은 아닙니다.
3. Linux 처리기 호출
irq domain 변환 후 처리; 실패하면 비활성화
화살표는 처리 위임입니다. 실패 경로의 deactivate는 정상 장치 처리기 호출과 구분됩니다.
__gic_handle_irq를 한 줄씩 읽기
줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.
static void __gic_handle_irq(u32 irqnr, struct pt_regs *regs)
{
if (gic_irqnr_is_special(irqnr))
return;
gic_complete_ack(irqnr);
if (generic_handle_domain_irq(gic_data.domain, irqnr)) {
WARN_ONCE(true, "Unexpected interrupt (irqnr %u)\n", irqnr);
gic_deactivate_unhandled(irqnr);
}
}static void __gic_handle_irq(u32 irqnr, struct pt_regs *regs)이미 읽은 GIC 인터럽트 번호와 저장된 예외 문맥을 받아 일반 IRQ 처리를 진행합니다. 이 함수 자체가 IAR을 읽는 것은 아닙니다.
if (gic_irqnr_is_special(irqnr))irqnr가 GIC의 특수 번호 범주인지 확인합니다. 모든 숫자가 실제 장치 IRQ를 뜻하지는 않습니다.
return;특수 번호라면 일반 장치 처리기를 찾지 않고 끝냅니다.
gic_complete_ack(irqnr);인터럽트 수락 뒤 필요한 GIC 상태 처리를 수행합니다. EOI 모드 등의 세부 동작은 보조 함수 구현에 있습니다.
if (generic_handle_domain_irq(gic_data.domain, irqnr)) {GIC irq domain에서 하드웨어 번호를 해석하여 등록된 IRQ 처리 경로를 호출합니다. 0이 아닌 반환이면 처리에 문제가 있음을 의미합니다.
WARN_ONCE(true, "Unexpected interrupt (irqnr %u)\n", irqnr);예상하지 못한 인터럽트 번호를 한 번 경고하여 원인을 추적할 수 있게 합니다.
gic_deactivate_unhandled(irqnr);처리되지 않은 인터럽트를 GIC 쪽에서 비활성화하는 정리를 수행합니다. 정상 장치 드라이버의 원인 해소와는 다른 오류 경로입니다.
함께 생각해 볼 질문
irqnr를 Linux IRQ 번호로 그대로 쓰면 되나요?
항상 그렇지 않습니다. 여기서는 GIC domain을 통해 하드웨어 식별자를 Linux IRQ 처리에 연결합니다.
인터럽트를 acknowledge하면 장치 원인도 사라지나요?
아닙니다. 장치의 원인을 해소하는 작업과 GIC의 수락·우선순위·active 상태 처리는 구분됩니다.
처리할 수 없는 번호를 경고만 하고 두면 되나요?
이 경로는 경고 뒤 gic_deactivate_unhandled로 GIC 상태도 정리합니다. 처리되지 않은 active 상태를 그대로 남기지 않기 위한 조치입니다.
출처와 읽은 범위
Linux stable v6.18.37 · drivers/irqchip/irq-gic-v3.c
해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고
