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 <yanyan.shen@data61.csiro.au>
This commit is contained in:
parent
bddd405417
commit
c4fe536984
5 changed files with 35 additions and 0 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue