From e97b171ca238671ebc21d30e62710c7832074a0b Mon Sep 17 00:00:00 2001 From: Jie Deng Date: Fri, 12 Nov 2021 16:13:45 +0800 Subject: [PATCH] hv: tee: x86_tee interrupt support 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. 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. To sum up, when secure interrupt comes, switch to TEE immediately regardless of whether REE is running or not; when non-Secure interrupt comes and TEE is running, just notify the TEE and keep it running, TEE will switch to REE on its own initiative after completing its work. Tracked-On: projectacrn#6571 Signed-off-by: Jie Deng Reviewed-by: Wang, Yu1 Acked-by: Eddie Dong --- hypervisor/arch/x86/guest/assign.c | 3 ++ hypervisor/arch/x86/guest/optee.c | 38 +++++++++++++++++++ hypervisor/include/arch/x86/asm/guest/optee.h | 7 ++++ 3 files changed, 48 insertions(+) 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_ */