Add an external interface to trigger an SDEI event bound to an interrupt by providing GIC interrupt ID. Signed-off-by: Heyi Guo <guoheyi@xxxxxxxxxx> Cc: Peter Maydell <peter.maydell@xxxxxxxxxx> Cc: Dave Martin <Dave.Martin@xxxxxxx> Cc: Marc Zyngier <marc.zyngier@xxxxxxx> Cc: Mark Rutland <mark.rutland@xxxxxxx> Cc: James Morse <james.morse@xxxxxxx> --- target/arm/sdei.c | 38 ++++++++++++++++++++++++++++++++++++++ target/arm/sdei.h | 7 +++++++ 2 files changed, 45 insertions(+) diff --git a/target/arm/sdei.c b/target/arm/sdei.c index f9a1208..088ed76 100644 --- a/target/arm/sdei.c +++ b/target/arm/sdei.c @@ -453,6 +453,29 @@ static int64_t sdei_version(QemuSDEState *s, CPUState *cs, struct kvm_run *run) (0ULL << SDEI_VERSION_MINOR_SHIFT); } +static bool inject_event(QemuSDEState *s, CPUState *cs, + int32_t event, int irq) +{ + QemuSDE *sde; + + if (event < 0) { + return false; + } + sde = get_sde_no_check(s, event, cs); + if (sde->event_id == SDEI_INVALID_EVENT_ID) { + put_sde(sde, cs); + return false; + } + if (irq > 0 && sde->prop->interrupt != irq) { + /* Someone unbinds the interrupt! */ + put_sde(sde, cs); + return false; + } + sde->pending = true; + dispatch_single(s, sde, cs); + return true; +} + static int64_t unregister_single_sde(QemuSDEState *s, int32_t event, CPUState *cs, bool force) { @@ -1033,6 +1056,21 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run) } } +bool trigger_sdei_by_irq(int cpu, int irq) +{ + QemuSDEState *s = sde_state; + + if (!s || irq >= ARRAY_SIZE(s->irq_map)) { + return false; + } + + if (s->irq_map[irq] == SDEI_INVALID_EVENT_ID) { + return false; + } + + return inject_event(s, arm_get_cpu_by_id(cpu), s->irq_map[irq], irq); +} + static void qemu_shared_sde_init(QemuSDEState *s) { int i; diff --git a/target/arm/sdei.h b/target/arm/sdei.h index a69a0e4..a61e788 100644 --- a/target/arm/sdei.h +++ b/target/arm/sdei.h @@ -31,4 +31,11 @@ void sdei_handle_request(CPUState *cs, struct kvm_run *run); +/* + * Trigger an SDEI event bound to an interrupt. + * Return true if event has been triggered successfully. + * Return false if event has not been triggered for some reason. + */ +bool trigger_sdei_by_irq(int cpu, int irq); + #endif -- 1.8.3.1 _______________________________________________ kvmarm mailing list kvmarm@xxxxxxxxxxxxxxxxxxxxx https://lists.cs.columbia.edu/mailman/listinfo/kvmarm