이 코드는 어떤 문제를 푸나요?
CPU가 IRQ를 처리했다는 사실을 GIC에도 반영해야 다음 알림을 정상적으로 처리할 수 있습니다. 아래는 물리 GICv3의 EOI 함수를 읽는 예입니다. vGIC의 가상 pending과 List Register는 별도 상태이므로 물리 EOI를 곧바로 게스트 EOI와 같은 동작으로 설명하지 않습니다.
읽을 범위: v6.18.37 · drivers/irqchip/irq-gic-v3.c · gic_eoi_irq 719–733행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.
먼저 알아둘 개념
물리와 가상 인터럽트
호스트가 실제 GIC에서 받은 요청과 게스트에 보여 주는 요청은 다른 상태 기계입니다.
EOImode
우선순위 종료와 비활성화가 한 동작인지 분리되는지를 좌우합니다.
List Register
GIC 가상화 인터페이스가 게스트에게 보여 줄 인터럽트 상태를 담는 자원이며 무한한 큐는 아닙니다.
처음 읽을 때
장치→호스트 GIC→KVM→게스트의 알림 경로를 나누어 설명하십시오.
더 깊이 살펴볼 때
물리 IRQ를 vCPU에 전달할 때 deactivate 책임이 어떻게 달라지는지 EOImode1 경로와 비교하십시오.
그림으로 보는 변화

1. INTID 확보
irq_data에서 물리 하드웨어 번호를 찾습니다.
화살표는 irqdomain 번호 변환의 결과를 사용한다는 의미입니다.
2. 물리 EOI
ICC_EOIR1_EL1을 쓰고 동기화합니다.
이 화살표를 가상 List Register의 직접 갱신으로 읽지 않습니다.
3. 구현별 마무리
필요한 erratum 경로에서 추가 deactivate를 수행합니다.
조건부 작업이며 모든 GIC 경로가 동일하지 않습니다.
gic_eoi_irq를 한 줄씩 읽기
줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.
static void gic_eoi_irq(struct irq_data *d)
{
write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);
isb();
if (gic_arm64_erratum_2941627_needed(d)) {
/*
* Make sure the GIC stream deactivate packet
* issued by ICC_EOIR1_EL1 has completed before
* deactivating through GICD_IACTIVER.
*/
dsb(sy);
gic_poke_irq(d, GICD_ICACTIVER);
}
}static void gic_eoi_irq(struct irq_data *d)일반 GIC EOI 경로의 IRQ chip 콜백입니다. 다른 EOImode용 콜백도 있으므로 모든 GIC 종료를 이 한 함수로 일반화하지 않습니다.
write_gicreg(irqd_to_hwirq(d), ICC_EOIR1_EL1);irq_data에서 하드웨어 INTID를 얻어 ICC_EOIR1_EL1에 씁니다. Linux IRQ 번호를 그대로 쓰는 것이 아니라 GIC가 이해하는 번호를 사용합니다.
isb();ISB로 CPU 인터페이스 시스템 레지스터 접근 뒤의 명령 실행을 동기화합니다.
if (gic_arm64_erratum_2941627_needed(d)) {해당 인터럽트 처리에 Arm erratum 2941627 보완이 필요한지 검사합니다. 참인 시스템에서만 추가 경로를 실행합니다.
dsb(sy);EOIR로 발생한 GIC stream deactivate가 필요한 완료 조건을 만족하도록 DSB SY를 수행합니다. 앞의 ISB와 다른 역할입니다.
gic_poke_irq(d, GICD_ICACTIVER);해당 인터럽트의 active 상태를 GICD_ICACTIVER에 쓰는 방식으로 지웁니다. active는 현재 처리 중임을 나타내는 상태이며 IRQ의 enable 비트를 내려 앞으로의 수신을 차단하는 동작과 다릅니다. 앞의 완료 처리만으로 충분하지 않은 하드웨어 erratum 조건에서 추가로 수행합니다.
함께 생각해 볼 질문
게스트 EOI가 항상 같은 함수에 도착합니까?
아닙니다. 가상화 인터페이스와 KVM의 경로를 구분해야 합니다.
LPI도 항상 DIR을 써서 끝냅니까?
아닙니다. LPI와 전달된 인터럽트에는 다른 완료 규칙이 있습니다.
GIC 번호와 Linux IRQ를 혼용하면 무엇이 문제입니까?
잘못된 인터럽트의 상태를 변경하거나 잘못된 handler를 연결할 수 있습니다.
출처와 읽은 범위
Linux stable v6.18.37 · drivers/irqchip/irq-gic-v3.c
해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고
