본문 바로가기

시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리/15장: 가상화(Virtualization)

[가상화-virtualization] 가상화 관점의 익셉션 벡터 테이블 분석

이전 절에서 익셉션 벡터 테이블의 스펙을 간단히 리뷰했습니다. 이어서 EL2 관점에서 익셉션 벡터 테이블을 자세히 분석하겠습니다.

EL2 관점에서 분석한 익셉션 벡터 테이블

다음은 하이퍼바이저가 실행되는 EL2 기준에서 본 익셉션 벡터 테이블을 나타낸 표입니다.

 

 

 

 

 

 

 

 

 



먼저 'EL2 with SP_EL0' 행의 내용을 분석합시다. 'EL2 with SP_EL0'는 익셉션 레벨에 상관없이 스택을 설정하는 조건에서 실행되는 익셉션 종류별 오프셋을 나타냅니다. 그런데 대부분의 하이퍼바이저는 이와 같은 익셉션은 지원하지 않습니다.    

EL2에서 발생한 익셉션 분석

이어서 'EL2에서 발생'로 표시된 부분을 봅시다. 0x200, 0x280, 0x300, 0x380은 하이퍼바이저가 구동되는 EL2에서 익셉션이 발생했을 때 익셉션의 종류별로 분기되는 오프셋 주소를 나타냅니다. 

이 내용에 대해 조금 더 자세히 알아볼까요? 만약 EL2에서 실행되는 하이퍼바이저에서 Synchronous 익셉션이 유발되면 다음과 같이 익셉션 벡터 베이스 주소(VBAR_EL2)에 +0x200 오프셋을 더한 주소로 프로그램 카운터가 분기됩니다. 

 Synchronous 익셉션 벡터 주소: VBAR_EL2 + 0x200

만약 EL2에서 'IRQ 인터럽트' 익셉션이 유발되면 익셉션 벡터 베이스 주소인 VBAR_EL2에 +0x280 오프셋을 더한 주소로 프로그램 카운터가 다음과 같이 분기됩니다. 

 IRQ 인터럽트 익셉션 벡터 주소: VBAR_EL2 + 0x280

또한 EL2에서 FIQ와 SError 익셉션이 유발되면 같은 방식으로 다음과 같은 주소로 프로그램 카운터가 분기됩니다.

 FIQ 익셉션 벡터 주소: VBAR_EL2 + 0x300
 SError 익셉션 벡터 주소: VBAR_EL2 + 0x380

 

---
[정보] 하이퍼바이저와 FIQ의 관계

대부분의 하이퍼바이저에서는 FIQ 익셉션을 지원하지 않습니다. FIQ는 시큐어 월드에서 실행되는 트러스트 커널에서 받아 처리하도록 시스템을 구성합니다.
---

게스트 OS가 실행되는 EL1에서 발생한 익셉션 분석

이어서 'EL1에서 발생(Aarch64)'로 표시된 부분은 게스트 OS가 구동되는 EL1에서 익셉션이 유발되면 분기되는 오프셋 주소를 나타냅니다. 

EL1에서 실행되는 게스트 OS에서 HVC, WFE, WFI 명령어를 실행하면 Synchronous 익셉션이 유발됩니다. 이때 다음과 같이 익셉션 벡터 베이스 주소(VBAR_EL2)에 +0x400 오프셋을 더한 주소로 프로그램 카운터가 분기됩니다. 

 Synchronous 익셉션 벡터 주소: VBAR_EL2 + 0x400

이 같은 동작을 “게스트 Exit 혹은 하이퍼바이저로 트랩된다”라고 설명할 수 있습니다. 

또한 게스트 OS가 실행되는 EL1에서 'IRQ 인터럽트' 익셉션이 유발되면 익셉션 벡터 베이스 주소(VBAR_EL2)에 +0x480 오프셋을 더한 주소로 프로그램 카운터가 분기됩니다.

 IRQ 인터럽트 익셉션 벡터 주소: VBAR_EL2 + 0x480

일반적으로 EL1에서 설정한 IRQ 인터럽트는 EL1에 존재하는 익셉션 핸들러에서 처리합니다. 하지만 HCR_EL2.IMO를 1로 설정하면 해당 인터럽트를 EL1에 있는 익셉션 핸들러가 아닌 EL2에 존재하는 익셉션 핸들러에서 받아 처리할 수 있습니다. 물리적인 인터럽트를 EL2가 먼저 받아 이를 EL1에서 실행되는 게스트 OS에 알려야 한다면 가상 인터럽트를 생성해 게스트 OS에 통지할 수 있습니다.  

다음으로 게스트 OS가 실행되는 EL1에서 'FIQ 인터럽트' 익셉션이 유발되면 분기되는 주소를 알아봅시다. 익셉션 벡터 베이스 주소(VBAR_EL2)에 +0x500 오프셋을 더한 주소로 다음과 같이 프로그램 카운터가 분기됩니다. 

 FIQ 인터럽트 익셉션 벡터 주소: VBAR_EL2 + 0x500

이전에 설명했지만 대부분의 하이퍼바이저는 FIQ를 지원하지 않습니다. +0x500 오프셋을 적용한 주소에는 크래시를 유발하는 *_invalid와 같은 레이블이 실행되며, 서브루틴에서 크래시를 유발하는 코드가 실행됩니다.

마지막으로 게스트 OS가 실행되는 EL1에서 'SError 인터럽트' 익셉션이 유발되면 익셉션 벡터 베이스 주소인 VBAR_EL2를 기준으로 +0x580 오프셋을 더한 주소로 프로그램 카운터가 분기됩니다. 규칙은 다음과 같습니다.

 SError 익셉션 벡터 주소: VBAR_EL2 + 0x580

일반적으로 EL1에서 설정한 'SError 인터럽트'는 EL1에서 처리되나 HCR_EL2 레지스터를 설정하면 해당 'SError 인터럽트' 익셉션을 EL2에서 받아 처리할 수 있습니다.

'EL1에서 발생(Aarch32)' 행은 EL1에서 실행되는 게스트 OS가 32비트 환경에서 실행될 때 처리되는 익셉션입니다. 최근 대부분의 게스트 OS(예: 리눅스 커널)는 64비트 모드로 실행되므로 'EL1에서 발생(Aarch32)' 행에서 정의된 익셉션은 "하위 호환성을 위해 정의됐다"라는 정도로 알아둡시다.

 

< 관련 강의 >