From c4fe5369845fdaa29744bda9b0bebcb9cd9a943c Mon Sep 17 00:00:00 2001 From: Anna Lyons Date: Tue, 28 Jan 2020 17:54:30 +1100 Subject: [PATCH] arm: remote IPI call support for VIRQS Added support for injecting remote IPI calls towards given VCPU's on SMP configured systems. This introudcing a new type of IpiRemoteCall and handlers for updating the vgic state on incoming/outgoing IPI's. Co-authored-by: Yanyan Shen --- include/arch/arm/arch/object/vcpu.h | 3 +++ include/arch/arm/arch/smp/ipi.h | 3 +++ include/smp/ipi.h | 5 +++++ src/arch/arm/object/vcpu.c | 15 +++++++++++++++ src/arch/arm/smp/ipi.c | 9 +++++++++ 5 files changed, 35 insertions(+) diff --git a/include/arch/arm/arch/object/vcpu.h b/include/arch/arm/arch/object/vcpu.h index c142b6b0e..e7e15c266 100644 --- a/include/arch/arm/arch/object/vcpu.h +++ b/include/arch/arm/arch/object/vcpu.h @@ -116,6 +116,9 @@ exception_t decodeARMVCPUInvocation( void vcpu_restore(vcpu_t *cpu); void vcpu_switch(vcpu_t *cpu); +#ifdef ENABLE_SMP_SUPPORT +void handleVCPUInjectInterruptIPI(vcpu_t *vcpu, unsigned long index, virq_t virq); +#endif /* ENABLE_SMP_SUPPORT */ exception_t decodeVCPUWriteReg(cap_t cap, unsigned int length, word_t *buffer); exception_t decodeVCPUReadReg(cap_t cap, unsigned int length, bool_t call, word_t *buffer); diff --git a/include/arch/arm/arch/smp/ipi.h b/include/arch/arm/arch/smp/ipi.h index 3a59af771..3aaac89c5 100644 --- a/include/arch/arm/arch/smp/ipi.h +++ b/include/arch/arm/arch/smp/ipi.h @@ -23,6 +23,9 @@ typedef enum { IpiRemoteCall_InvalidateTranslationAll, IpiRemoteCall_switchFpuOwner, IpiRemoteCall_MaskPrivateInterrupt, +#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT + IpiRemoteCall_VCPUInjectInterrupt, +#endif /* Add relevant calls here upon required */ IpiNumArchRemoteCall } IpiRemoteCall_t; diff --git a/include/smp/ipi.h b/include/smp/ipi.h index f08f3a648..1946242f5 100644 --- a/include/smp/ipi.h +++ b/include/smp/ipi.h @@ -150,6 +150,11 @@ static void inline doRemoteOp2Arg(IpiRemoteCall_t func, word_t data1, word_t dat doRemoteOp(func, data1, data2, 0, cpu); } +static void inline doRemoteOp3Arg(IpiRemoteCall_t func, word_t data1, word_t data2, word_t data3, word_t cpu) +{ + doRemoteOp(func, data1, data2, data3, cpu); +} + /* This is asynchronous call and could be called outside the lock. * Returns immediately. * diff --git a/src/arch/arm/object/vcpu.c b/src/arch/arm/object/vcpu.c index 0b268176c..6c1b0589f 100644 --- a/src/arch/arm/object/vcpu.c +++ b/src/arch/arm/object/vcpu.c @@ -369,6 +369,10 @@ exception_t invokeVCPUInjectIRQ(vcpu_t *vcpu, unsigned long index, virq_t virq) { if (likely(ARCH_NODE_STATE(armHSCurVCPU) == vcpu)) { set_gic_vcpu_ctrl_lr(index, virq); +#ifdef ENABLE_SMP_SUPPORT + } else if (vcpu->vcpuTCB->tcbAffinity != getCurrentCPUIndex()) { + doRemoteOp3Arg(IpiRemoteCall_VCPUInjectInterrupt, (word_t)vcpu, index, virq.words[0], vcpu->vcpuTCB->tcbAffinity); +#endif /* CONFIG_ENABLE_SMP */ } else { vcpu->vgic.lr[index] = virq; } @@ -564,4 +568,15 @@ void handleVCPUFault(word_t hsr) activateThread(); } +#ifdef ENABLE_SMP_SUPPORT +void handleVCPUInjectInterruptIPI(vcpu_t *vcpu, unsigned long index, virq_t virq) +{ + if (likely(ARCH_NODE_STATE(armHSCurVCPU) == vcpu)) { + set_gic_vcpu_ctrl_lr(index, virq); + } else { + vcpu->vgic.lr[index] = virq; + } +} +#endif /* ENABLE_SMP_SUPPORT */ + #endif diff --git a/src/arch/arm/smp/ipi.c b/src/arch/arm/smp/ipi.c index 1f17b8776..9fa4330ba 100644 --- a/src/arch/arm/smp/ipi.c +++ b/src/arch/arm/smp/ipi.c @@ -65,6 +65,15 @@ static void handleRemoteCall(IpiModeRemoteCall_t call, word_t arg0, maskInterrupt(arg0, IDX_TO_IRQT(arg1)); break; +#if defined CONFIG_ARM_HYPERVISOR_SUPPORT && defined ENABLE_SMP_SUPPORT + case IpiRemoteCall_VCPUInjectInterrupt: { + virq_t virq; + virq.words[0] = arg2; + handleVCPUInjectInterruptIPI((vcpu_t *) arg0, arg1, virq); + break; + } +#endif + default: fail("Invalid remote call"); break;