diff --git a/hypervisor/arch/x86/guest/assign.c b/hypervisor/arch/x86/guest/assign.c index 1d619a014..9c7bfc576 100644 --- a/hypervisor/arch/x86/guest/assign.c +++ b/hypervisor/arch/x86/guest/assign.c @@ -14,6 +14,7 @@ #include #include #include +#include /* * Check if the IRQ is single-destination and return the destination vCPU if so. @@ -534,6 +535,8 @@ void ptirq_softirq(uint16_t pcpu_id) vmsi->addr.full, vmsi->data.full); } } + + handle_x86_tee_int(entry, pcpu_id); } } diff --git a/hypervisor/arch/x86/guest/optee.c b/hypervisor/arch/x86/guest/optee.c index 3fb312d3a..b0d48030d 100644 --- a/hypervisor/arch/x86/guest/optee.c +++ b/hypervisor/arch/x86/guest/optee.c @@ -145,3 +145,41 @@ int32_t hcall_switch_ee(struct acrn_vcpu *vcpu, __unused struct acrn_vm *target_ return ret; } + +void handle_x86_tee_int(struct ptirq_remapping_info *entry, uint16_t pcpu_id) +{ + struct acrn_vcpu *tee_vcpu; + struct acrn_vcpu *curr_vcpu = get_running_vcpu(pcpu_id); + + if (((get_vm_config(entry->vm->vm_id)->guest_flags & GUEST_FLAG_REE) != 0U) && + ((get_vm_config(curr_vcpu->vm->vm_id)->guest_flags & GUEST_FLAG_TEE) != 0U)) { + /* + * Non-Secure interrupt (interrupt belongs to REE) comes + * when REE vcpu is running, the interrupt will be injected + * to REE directly. But when TEE vcpu is running at that time, + * we need to inject a predefined vector to TEE for notification + * and continue to switch back to TEE for running. + */ + tee_vcpu = vcpu_from_pid(get_companion_vm(entry->vm), pcpu_id); + vlapic_set_intr(tee_vcpu, TEE_NOTIFICATION_VECTOR, LAPIC_TRIG_EDGE); + } else if (((get_vm_config(entry->vm->vm_id)->guest_flags & GUEST_FLAG_TEE) != 0U) && + ((get_vm_config(curr_vcpu->vm->vm_id)->guest_flags & GUEST_FLAG_REE) != 0U)) { + /* + * Secure interrupt (interrupt belongs to TEE) comes + * when TEE vcpu is running, the interrupt will be + * injected to TEE directly. But when REE vcpu is running + * at that time, we need to switch to TEE for handling, + * and copy 0xB20000FF to RDI to notify OPTEE about this. + */ + tee_vcpu = vcpu_from_pid(entry->vm, pcpu_id); + /* + * Copy 0xB20000FF to RDI to indicate the switch is from secure interrupt + * This is the contract with OPTEE. + */ + vcpu_set_gpreg(tee_vcpu, CPU_REG_RDI, OPTEE_FIQ_ENTRY); + + wake_thread(&tee_vcpu->thread_obj); + } else { + /* Nothing need to do for this moment */ + } +} diff --git a/hypervisor/include/arch/x86/asm/guest/optee.h b/hypervisor/include/arch/x86/asm/guest/optee.h index 3af740e79..91b244e14 100644 --- a/hypervisor/include/arch/x86/asm/guest/optee.h +++ b/hypervisor/include/arch/x86/asm/guest/optee.h @@ -9,10 +9,17 @@ #include #include +#include + +#define TEE_NOTIFICATION_VECTOR 0x29U /* If the RDI equals to this value, then this is a RETURN after FIQ DONE */ #define OPTEE_RETURN_FIQ_DONE 0xBE000006UL +/* This value tells OPTEE that this switch to TEE is due to secure interrupt */ +#define OPTEE_FIQ_ENTRY 0xB20000FFUL + void prepare_tee_vm_memmap(struct acrn_vm *vm, const struct acrn_vm_config *vm_config); +void handle_x86_tee_int(struct ptirq_remapping_info *entry, uint16_t pcpu_id); #endif /* TEE_H_ */