From patchwork Thu Apr 27 13:56:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 756041 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3wDJRn0jPhz9sNN for ; Thu, 27 Apr 2017 23:57:41 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3wDJRm72cnzDqBH for ; Thu, 27 Apr 2017 23:57:40 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3wDJRb0hgKzDq72 for ; Thu, 27 Apr 2017 23:57:30 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id v3RDugiI003774; Thu, 27 Apr 2017 08:56:43 -0500 From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Thu, 27 Apr 2017 15:56:39 +0200 Message-Id: <20170427135639.31629-1-benh@kernel.crashing.org> X-Mailer: git-send-email 2.9.3 Subject: [Skiboot] [PATCH] xive+phb4: Fix exposing trigger page to Linux X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" We currently don't expose the trigger page of MSIs to Linux which breaks re-sending of a queued one. To fix that properly we need to understand out a subtle API complication: - The "internal" XIVE_SRC_TRIGGER_PAGE indicates that a trigger page is supported, whether it's the same page as the EOI page or not. - The "external" OPAL_XIVE_IRQ_TRIGGER_PAGE indicates that a *separate* trigger page exists. To know if triggers are supported the caller should simply check if a valid (non-0) value is returned in "out_trig_page" of opal_xive_get_irq_info(). So PHB4 must set XIVE_SRC_TRIGGER_PAGE for MSIs and the xive code needs to do the "right" thing for setting whether OPAL_XIVE_IRQ_TRIGGER_PAGE should be set or not. Signed-off-by: Benjamin Herrenschmidt --- hw/phb4.c | 3 ++- hw/xive.c | 15 ++++++++++++--- include/xive.h | 14 +++++++++----- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/hw/phb4.c b/hw/phb4.c index 12e17bd..e1f0bcb 100644 --- a/hw/phb4.c +++ b/hw/phb4.c @@ -3383,7 +3383,8 @@ static void phb4_create(struct dt_node *np) /* Register all interrupt sources with XIVE */ xive_register_hw_source(p->base_msi, p->num_irqs - 8, 16, - p->int_mmio, XIVE_SRC_SHIFT_BUG, + p->int_mmio, + XIVE_SRC_SHIFT_BUG | XIVE_SRC_TRIGGER_PAGE, NULL, NULL); xive_register_hw_source(p->base_lsi, 8, 16, diff --git a/hw/xive.c b/hw/xive.c index ed1dc90..1952ce6 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -3372,8 +3372,14 @@ static uint64_t xive_convert_irq_flags(uint64_t iflags) if (iflags & XIVE_SRC_STORE_EOI) oflags |= OPAL_XIVE_IRQ_STORE_EOI; - if (iflags & XIVE_SRC_TRIGGER_PAGE) + + /* OPAL_XIVE_IRQ_TRIGGER_PAGE is only meant to be set if + * the interrupt has a *separate* trigger page. + */ + if ((iflags & XIVE_SRC_EOI_PAGE1) && + (iflags & XIVE_SRC_TRIGGER_PAGE)) oflags |= OPAL_XIVE_IRQ_TRIGGER_PAGE; + if (iflags & XIVE_SRC_LSI) oflags |= OPAL_XIVE_IRQ_LSI; if (iflags & XIVE_SRC_SHIFT_BUG) @@ -3422,14 +3428,17 @@ static int64_t opal_xive_get_irq_info(uint32_t girq, mm_base = (uint64_t)s->esb_mmio + (1ull << s->esb_shift) * idx; + /* The EOI page can either be the first or second page */ if (s->flags & XIVE_SRC_EOI_PAGE1) { uint64_t p1off = 1ull << (s->esb_shift - 1); eoi_page = mm_base + p1off; - if (s->flags & XIVE_SRC_TRIGGER_PAGE) - trig_page = mm_base; } else eoi_page = mm_base; + /* The trigger page, if it exists, is always the first page */ + if (s->flags & XIVE_SRC_TRIGGER_PAGE) + trig_page = mm_base; + if (out_eoi_page) *out_eoi_page = eoi_page; if (out_trig_page) diff --git a/include/xive.h b/include/xive.h index 06aad8b..d2ef1d9 100644 --- a/include/xive.h +++ b/include/xive.h @@ -447,11 +447,15 @@ uint64_t xive_get_notify_port(uint32_t chip_id, uint32_t ent); uint32_t xive_get_notify_base(uint32_t girq); /* Internal IRQ flags */ -#define XIVE_SRC_TRIGGER_PAGE 0x01 -#define XIVE_SRC_EOI_PAGE1 0x02 -#define XIVE_SRC_STORE_EOI 0x04 -#define XIVE_SRC_LSI 0x08 -#define XIVE_SRC_SHIFT_BUG 0x10 +#define XIVE_SRC_TRIGGER_PAGE 0x01 /* Trigger page exist (either separate + * or not, so different from the OPAL + * flag which is only set when the + * trigger page is separate). + */ +#define XIVE_SRC_EOI_PAGE1 0x02 /* EOI on the second page */ +#define XIVE_SRC_STORE_EOI 0x04 /* EOI using stores supported */ +#define XIVE_SRC_LSI 0x08 /* Interrupt is an LSI */ +#define XIVE_SRC_SHIFT_BUG 0x10 /* ESB update offset << 4 */ struct irq_source_ops; void xive_register_hw_source(uint32_t base, uint32_t count, uint32_t shift,