하이퍼바이저 콘트롤 레지스터는 하이퍼바이저의 세부 동작을 설정하는 가장 중요한 레지스터 중입니다. HCR_EL2은 EL1에서 일어나는 세부 동작에 따라 EL2으로 진입(트랩)하는 방식을 설정할 수 있는 비트맵으로 구성돼 있습니다.


다음 그림은 HCR_EL2 레지스터의 비트 맵 정보입니다.



그림 12.3 HCR_EL2 레지스터의 비트 맵 <출처: DDI0487G_b_armv8_arm.pdf> 

다른 레지스터와 같이 레지스터를 구성하는 비트를 1로 설정하면, 해당 비트 맵과 관련된 동작이 수행됩니다. HCR_EL2 레지스터를 구성하는 비트 맵 중에 중요한 내용을 소개하겠습니다.

IMO, bit [4]

이 비트가 1로 설정되면 EL2이나 EL1에서 설정된 인터럽트를 EL2에서 받아 처리합니다. 만약 SCR_EL3.IRQ 비트가 1로 설정되면 EL3가 인터럽트를 받아 처리합니다. 만약 0으로 설정되면 EL2보다 낮은 익셉션 레벨에서 설정된 인터럽트를 EL2가 받지 않습니다.

AMO, bit [5]

이 비트는 EL1에서 발생한 Asynchronous 익셉션을 EL2에서 처리하기 위한 용도로 사용됩니다.
AMO 비트가 1로 설정됐으면 EL2이나 EL2보다 낮은 익셉션 레벨에서 Asynchronous 혹은 SError 인터럽트가 발생하면 EL2로 트랩됩니다. 

TWI, bit [13]

이 비트를 1로 설정하고 EL0 혹은 EL1에서 wfi 명령어를 실행하면 트랩이 발생하면서 EL2로 익셉션 레벨이 바뀝니다. 만약 0으로 설정된 경우 wfi 명령어를 실행하면 arm 코어가 저전력 모드로 진입하게 동작합니다. 

TWE, bit [14]

이 비트를 1로 설정하고 EL0 혹은 EL1에서 wfe 명령어를 실행하면 트랩이 일어나며, 이 과정에서 EL2로 진입합니다. 만약 0으로 설정된 경우에 wfe 명령어를 실행하면 arm 코어가 저전력 모드로 실행됩니다.

TSC, bit [19]

TSC 비트가 1로 설정된 경우, EL1에서 smc 명령어를 실행하면 EL2로 트랩됩니다. 일반적으로 EL1에서 smc 명령어를 실행하면 EL3에 존재하는 모니터 모드로 진입합니다.

그런데 여러 게스트 OS에서 smc 명령어를 동시다발적으로 실행하면 예기치 못한 문제가 발생할 수 있어, smc 명령어를 하이퍼바이저가 받아서 제어해야 할 상황이 있습니다. 이를 smc 명령어 후킹이라고 합니다.

TVM, bit [26]

가상 메모리를 제어하기 위한 트랩을 설정하는 비트입니다. TVM 비트가 1로 설정되면, EL1에서 다음와 같은 메모리를 제어하는 레지스터에 어떤 값을 쓰면 EL2로 트랩됩니다. 

   * SCTLR_EL1, TTBR0_EL1, TTBR1_EL1, TCR_EL1, ESR_EL1, FAR_EL1, AFSR0_EL1, AFSR1_EL1, MAIR_EL1, AMAIR_EL1, CONTEXTIDR_EL1.

EL2로 트랩될 때 Arm 코어는 하드웨어적으로 익셉션 신드롬 레지스터에 0x18값을 써줍니다.

TGE, bit [27]

TGE 비트가 1로 설정되면 EL1에서 발생한 익셉션이 EL2로 라우팅됩니다. EL1에서 익셉션이 발생하면 EL1에 존재하는 익셉션 벡터 주소(VBAR_EL1 기준)로 프로그램 카운터가 브랜치되는 것이 아니라, EL2로 익셉션 레벨이 바뀌면서 EL2이 위치한 익셉션 벡터 주소(VBAR_EL2 기준)로 프로그램 카운터가 바뀝니다.

운영체제의 커널에서 실행되는 시스템 정보를 EL2에서 실행되는 하이퍼바이저가 후킹할 때도 사용됩니다.

HCD, bit [29]

HCD 비트는 하이퍼바이저 콜을 설정하는 기능입니다. HCD 비트가 1로 설정되면 hvc 명령어가 활성화되고, HCD 비트가 0으로 설정되면 hvc 명령어가 비활성화(Undefined)됩니다.

 

< '시스템 소프트웨어 개발을 위한 Arm 아키텍처의 구조와 원리' 저자>

 

 

 

+ Recent posts