mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2026-01-06 16:15:00 +00:00
hv: tee: Handling x86_tee secure interrupts corner cases
Previous upstreamed patches handles the secure/non-secure interrupts in
handle_x86_tee_int. However there is a corner case in which there might
be unhandled secure interrupts (in a very short time window) when TEE
yields vCPU. For this case we always make sure that no secure interrupts
are pending in TEE's vlapic before scheduling REE.
Also in previous patches, if non-secure interrupt comes when TEE is
handling its secure interrupts, hypervisor injects a predefined vector
into TEE's vlapic. TEE does not consume this vector in secure interrupt
handling routine so it stays in vIRR, but it should be cleared because the
actual interrupt will be consumed in REE after VM Entry.
v3:
Fix comments on interrupt priority
v2:
Add comments explaining the priority of secure/non-secure interrupts
Tracked-On: #6571
Signed-off-by: Yifan Liu <yifan1.liu@intel.com>
Reviewed-by: Wang, Yu1 <yu1.wang@intel.com>
Acked-by: Anthony Xu <anthony.xu@intel.com>
This commit is contained in:
@@ -10,6 +10,9 @@
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/guest/optee.h>
|
||||
#include <asm/trampoline.h>
|
||||
#include <asm/guest/vlapic.h>
|
||||
#include <asm/guest/virq.h>
|
||||
#include <asm/lapic.h>
|
||||
#include <reloc.h>
|
||||
#include <hypercall.h>
|
||||
#include <logmsg.h>
|
||||
@@ -56,6 +59,7 @@ static int32_t tee_switch_to_ree(struct acrn_vcpu *vcpu)
|
||||
uint64_t rdi, rsi, rdx, rbx;
|
||||
struct acrn_vm *ree_vm;
|
||||
struct acrn_vcpu *ree_vcpu;
|
||||
uint32_t pending_intr;
|
||||
int32_t ret = -EINVAL;
|
||||
|
||||
rdi = vcpu_get_gpreg(vcpu, CPU_REG_RDI);
|
||||
@@ -78,6 +82,28 @@ static int32_t tee_switch_to_ree(struct acrn_vcpu *vcpu)
|
||||
vcpu_set_gpreg(ree_vcpu, CPU_REG_RBX, rbx);
|
||||
}
|
||||
|
||||
pending_intr = vlapic_get_next_pending_intr(vcpu);
|
||||
if (prio(pending_intr) > prio(TEE_FIXED_NONSECURE_VECTOR)) {
|
||||
/* For TEE, all non-secure interrupts are represented as
|
||||
* TEE_FIXED_NONSECURE_VECTOR that has lower priority than all
|
||||
* secure interrupts.
|
||||
*
|
||||
* If there are secure interrupts pending, we inject TEE's PI
|
||||
* ANV and schedules REE. This way REE gets trapped immediately
|
||||
* after VM Entry and will go through the secure interrupt handling
|
||||
* flow in handle_x86_tee_int.
|
||||
*/
|
||||
send_single_ipi(pcpuid_from_vcpu(ree_vcpu),
|
||||
(uint32_t)(vcpu->arch.pid.control.bits.nv));
|
||||
} else if (prio(pending_intr) == prio(TEE_FIXED_NONSECURE_VECTOR)) {
|
||||
/* The TEE_FIXED_NONSECURE_VECTOR needs to be cleared as the
|
||||
* pending non-secure interrupts will be handled immediately
|
||||
* after resuming to REE. On ARM this is automatically done
|
||||
* by hardware and ACRN emulates this behavior.
|
||||
*/
|
||||
vlapic_clear_pending_intr(vcpu, TEE_FIXED_NONSECURE_VECTOR);
|
||||
}
|
||||
|
||||
sleep_thread(&vcpu->thread_obj);
|
||||
ret = 0;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user