운영체제나 RTOS 커널의 세부 동작을 파악하려면 익셉션이 유발되면 처리되는 익셉션 벡터 핸들러를 잘 알아야 합니다. 익셉션 벡터 핸들러의 코드를 보면 Armv8 아키텍처에서 정의된 스팩에 따라 익셉션 벡터 핸들러가 구현됐다는 사실을 알 수 있습니다. XEN 하이퍼바이저의 익셉션 벡터 핸들러 코드도 예외는 아닙니다. 게스트 OS와 하이퍼바이저와 통신하는 주요 인터페이스가 XEN 하이퍼바이저의 익셉션 벡터 핸들러이니 잘 익혀둘 필요가 있습니다.
익셉션 핸들러 코드 소개
포스트에서 분석할 XEN 하이퍼바이저의 익셉션 벡터 핸들러 전체 어셈블리 코드를 소개합니다.
1 000000000026a800 <hyp_traps_vector>:
2 26a800: 17fffc00 b 269800 <hyp_sync_invalid>
3 26a804: d503201f nop
4 26a808: d503201f nop
...
5 26a880: 17fffbfb b 26986c <hyp_irq_invalid>
6 26a884: d503201f nop
7 26a888: d503201f nop
...
8 26a900: 17fffbf6 b 2698d8 <hyp_fiq_invalid>
9 26a904: d503201f nop
10 26a908: d503201f nop
...
11 26a980: 17fffbf1 b 269944 <hyp_error_invalid>
12 26a984: d503201f nop
13 26a988: d503201f nop
...
14 26aa00: 17fffc07 b 269a1c <hyp_sync>
15 26aa04: d503201f nop
16 26aa08: d503201f nop
...
17 26aa80: 17fffc05 b 269a94 <hyp_irq>
18 26aa84: d503201f nop
19 26aa88: d503201f nop
...
20 26ab00: 17fffb76 b 2698d8 <hyp_fiq_invalid>
21 26ab04: d503201f nop
22 26ab08: d503201f nop
...
23 26ab80: 17fffb8c b 2699b0 <hyp_error>
24 26ab84: d503201f nop
25 26ab88: d503201f nop
...
26 26ac00: 17fffbc5 b 269b14 <guest_sync>
27 26ac04: d503201f nop
28 26ac08: d503201f nop
...
29 26ac80: 17fffbfe b 269c78 <guest_irq>
30 26ac84: d503201f nop
31 26ac88: d503201f nop
...
32 26ad00: 17fffc13 b 269d4c <guest_fiq_invalid>
33 26ad04: d503201f nop
34 26ad08: d503201f nop
...
35 26ad80: 17fffc18 b 269de0 <guest_error>
36 26ad84: d503201f nop
37 26ad88: d503201f nop
...
38 26ae00: 17fffc2d b 269eb4 <guest_sync_compat>
39 26ae04: d503201f nop
40 26ae08: d503201f nop
...
41 26ae80: 17fffc44 b 269f90 <guest_irq_compat>
42 26ae84: d503201f nop
43 26ae88: d503201f nop
...
44 26af00: 17fffc5b b 26a06c <guest_fiq_invalid_compat>
45 26af04: d503201f nop
46 26af08: d503201f nop
...
47 26af80: 17fffc61 b 26a104 <guest_error_compat>
익셉션 벡터 핸들러의 코드 분석을 시작하기 직전에 "'익셉션 벡터 베이스 주소 + 오프셋 주소' 규칙으로 프로그램 카운터가 브랜치된다"라는 사실을 염두에 둡시다.
익셉션 벡터 핸들러 코드를 정확히 분석하려면 다음과 같은 정보를 염두에 둬야 합니다.
* 익셉션 벡터 베이스 주소: 0x26a800
* 익셉션 별 오프셋 주소의 간격: +0x80
익셉션이 유발되면 익셉션의 종류 별로 지정된 오프셋 주소에 따라 '익셉션 벡터 베이스 주소 + 오프셋 주소' 규칙으로 프로그램 카운터가 브랜치되는 것입니다.
이해를 돕기 위해 다음 예제 코드를 보면서 설명하겠습니다.
1 000000000026a800 <hyp_traps_vector>:
2 26a800: 17fffc00 b 269800 <hyp_sync_invalid>
3 26a804: d503201f nop
4 26a808: d503201f nop
...
5 26a880: 17fffbfb b 26986c <hyp_irq_invalid>
6 26a884: d503201f nop
7 26a888: d503201f nop
'EL2 with SP_EL0'와 같이 스택 포인터를 익셉션 레벨과 상관없이 설정하는 조건에서 발생하는 익셉션의 오프셋 정보는 다음과 같습니다.
* Synchronous 익셉션: 0x0
* IRQ 익셉션: 0x80
만약 'EL2 with SP_EL0' 조건에서 Synchronous 익셉션이 유발되면 다음과 같은 공식에 따라 프로그램 카운터가 0x26a800 주소로 브랜치됩니다.
* 0x26a800 = 0x26a800(익셉션 벡터 베이스 주소) + 0x0(오프셋)
그런데 'EL2 with SP_EL0' 조건에서 'IRQ Interrupt' 익셉션이 유발되면 프로그램 카운터가 0x26a880 주소로 브랜치됩니다. 프로그래 카운터가 바뀌는 공식은 다음과 같습니다.
* 0x26a880 = 0x26a800(익셉션 벡터 베이스 주소) + 0x80(오프셋)
이번에는 하이퍼바이저가 실행되는 EL2에서 익셉션이 유발되면 어떻게 프로그램 카운터가 브랜치되는지 알아보겠습니다.
14 26aa00: 17fffc07 b 269a1c <hyp_sync>
15 26aa04: d503201f nop
16 26aa08: d503201f nop
...
17 26aa80: 17fffc05 b 269a94 <hyp_irq>
18 26aa84: d503201f nop
19 26aa88: d503201f nop
EL2이 실행될 때 발생하는 익셉션의 오프셋 정보는 다음과 같습니다.
* IRQ 익셉션: 0x280
만약 EL2에서 Synchronous 익셉션이 유발되면 다음과 같은 공식에 따라 프로그램 카운터가 0x26a800 주소로 브랜치됩니다.
* 0x26aa00 = 0x26a800(익셉션 벡터 베이스 주소) + 0x200(오프셋)
이와 마찬가지로 EL2에서 'IRQ Interrupt' 익셉션이 유발되면 프로그램 카운터가 0x26aa80 주소로 브랜치됩니다. 규칙은 다음과 같습니다.
* 0x26aa80 = 0x26a800(익셉션 벡터 베이스 주소) + 0x280(오프셋)
이처럼 XEN 하이퍼바이저의 익셉션 벡터 테이블은 Armv8 아키텍처에서 명시된 익셉션 벡터 테이블의 스팩 기준에 따라 구현됐다는 점을 알 수 있습니다.
다음은 위에서 든 익셉션 벡터 핸들러 코드에서 익셉션의 종류 별로 브랜치되는 프로그램 카운터의 정보를 정리한 표입니다.

표 12.3 XEN 하이버파이저의 익셉션 벡터 주소
익셉션 벡터 핸들러의 코드를 제대로 이해하려면 Arm 아키텍처에서 정의된 익셉션 벡터 테이블을 먼저 숙지하고 있어야 합니다.
최근 덧글