arch/arm64/kvm/hyp/exception.c

Source file repositories/reference/linux-study-clean/arch/arm64/kvm/hyp/exception.c

File Facts

System
Linux kernel
Corpus path
arch/arm64/kvm/hyp/exception.c
Extension
.c
Size
10839 bytes
Lines
378
Domain
Architecture Layer
Bucket
arch/arm64
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) {
		case unpack_vcpu_flag(EXCEPT_AA32_UND):
			enter_exception32(vcpu, PSR_AA32_MODE_UND, 4);
			break;
		case unpack_vcpu_flag(EXCEPT_AA32_IABT):
			enter_exception32(vcpu, PSR_AA32_MODE_ABT, 12);
			break;
		case unpack_vcpu_flag(EXCEPT_AA32_DABT):
			enter_exception32(vcpu, PSR_AA32_MODE_ABT, 16);
			break;
		default:
			/* Err... */
			break;
		}
	} else {
		switch (vcpu_get_flag(vcpu, EXCEPT_MASK)) {
		case unpack_vcpu_flag(EXCEPT_AA64_EL1_SYNC):
			enter_exception64(vcpu, PSR_MODE_EL1h, except_type_sync);
			break;

		case unpack_vcpu_flag(EXCEPT_AA64_EL1_SERR):
			enter_exception64(vcpu, PSR_MODE_EL1h, except_type_serror);
			break;

		case unpack_vcpu_flag(EXCEPT_AA64_EL2_SYNC):
			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_sync);
			break;

		case unpack_vcpu_flag(EXCEPT_AA64_EL2_IRQ):
			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_irq);
			break;

		case unpack_vcpu_flag(EXCEPT_AA64_EL2_SERR):
			enter_exception64(vcpu, PSR_MODE_EL2h, except_type_serror);
			break;

		default:
			/*
			 * Only EL1_{SYNC,SERR} and EL2_{SYNC,IRQ,SERR} makes
			 * sense so far. Everything else gets silently
			 * ignored.
			 */
			break;
		}
	}
}

/*
 * Adjust the guest PC (and potentially exception state) depending on
 * flags provided by the emulation code.
 */
void __kvm_adjust_pc(struct kvm_vcpu *vcpu)
{
	if (vcpu_get_flag(vcpu, PENDING_EXCEPTION)) {
		kvm_inject_exception(vcpu);
		vcpu_clear_flag(vcpu, PENDING_EXCEPTION);
		vcpu_clear_flag(vcpu, EXCEPT_MASK);
	} else if (vcpu_get_flag(vcpu, INCREMENT_PC)) {
		kvm_skip_instr(vcpu);
		vcpu_clear_flag(vcpu, INCREMENT_PC);
	}
}

Annotation

Implementation Notes