Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

3240
557
422294


[Arm프로세서] XEN 하이퍼바이저: 익셉션 핸들러 코드 소개 Arm: Virtualization

운영체제나 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이 실행될 때 발생하는 익셉션의 오프셋 정보는 다음과 같습니다.

    * Synchronous 익셉션: 0x200
    * IRQ 익셉션: 0x280

만약 EL2에서 Synchronous 익셉션이 유발되면 다음과 같은 공식에 따라 프로그램 카운터가 0x26a800 주소로 브랜치됩니다.

    * 0x26aa00 = 0x26a800(익셉션 벡터 베이스 주소) + 0x200(오프셋)

이와 마찬가지로 EL2에서 'IRQ Interrupt' 익셉션이 유발되면 프로그램 카운터가 0x26aa80 주소로 브랜치됩니다. 규칙은 다음과 같습니다.

    * 0x26aa80 = 0x26a800(익셉션 벡터 베이스 주소) + 0x280(오프셋)

이처럼 XEN 하이퍼바이저의 익셉션 벡터 테이블은 Armv8 아키텍처에서 명시된 익셉션 벡터 테이블의 스팩 기준에 따라 구현됐다는 점을 알 수 있습니다. 
다음은 위에서 든 익셉션 벡터 핸들러 코드에서 익셉션의 종류 별로 브랜치되는 프로그램 카운터의 정보를 정리한 표입니다.


표 12.3 XEN 하이버파이저의 익셉션 벡터 주소

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


덧글

댓글 입력 영역