# KVM virtualization: EL2, VMX/SVM과 RISC-V H-extension

v6.18.37 / arch/arm64/kvm/arm.c

가상 CPU가 대기 중일 때 계속 실제 CPU를 차지하게 할 필요는 없습니다. 그러나 가상 인터럽트가 도착하면 다시 실행할 수 있어야 합니다. arm64는 EL2·HCR·vGIC, x86은 VMX/SVM 및 가상 APIC, RISC-V는 H 확장 및 가상 인터럽트 상태를 사용합니다. 대표로 arm64의 runnable 판단 함수를 읽습니다.

## kvm_arch_vcpu_runnable

```c

int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)
{
	bool irq_lines = *vcpu_hcr(v) & (HCR_VI | HCR_VF | HCR_VSE);

	irq_lines |= (!irqchip_in_kernel(v->kvm) &&
		      (kvm_timer_should_notify_user(v) ||
		       kvm_pmu_should_notify_user(v)));

	return ((irq_lines || kvm_vgic_vcpu_pending_irq(v))
		&& !kvm_arm_vcpu_stopped(v) && !v->arch.pause);
}

```

### 756행

```c

int kvm_arch_vcpu_runnable(struct kvm_vcpu *v)

```

vCPU가 대기 상태에서 실행할 사유가 있는지 판단할 정수 결과를 반환합니다. 게스트 진입 명령 자체는 여기 없습니다.

### 758행

```c

	bool irq_lines = *vcpu_hcr(v) & (HCR_VI | HCR_VF | HCR_VSE);

```

vCPU HCR 상태의 가상 IRQ·FIQ·SError 주입 비트를 읽습니다. 물리 GIC pending 전체를 직접 읽는 식이 아닙니다.

### 760행

```c

	irq_lines |= (!irqchip_in_kernel(v->kvm) &&

```

irqchip을 커널 안에서 관리하지 않는 경우의 깨움 사유도 기존 irq_lines에 합칩니다.

### 761행

```c

		      (kvm_timer_should_notify_user(v) ||

```

가상 timer 사건을 사용자 공간에 알려야 한다면 실행을 다시 진행할 이유로 삼습니다.

### 762행

```c

		       kvm_pmu_should_notify_user(v)));

```

가상 PMU의 통지 필요도 같은 조건에 포함하고 괄호를 닫습니다.

### 764행

```c

	return ((irq_lines || kvm_vgic_vcpu_pending_irq(v))

```

위에서 계산한 주입 상태 또는 vGIC의 pending IRQ가 있는지 확인합니다.

### 765행

```c

		&& !kvm_arm_vcpu_stopped(v) && !v->arch.pause);

```

그렇더라도 vCPU가 stopped이거나 pause이면 실행 가능으로 보지 않습니다. 논리 AND 때문에 깨움 사유와 관리 상태를 함께 만족해야 합니다.

