From patchwork Wed Mar 21 16:32:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 132226 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp2356211ljb; Wed, 21 Mar 2018 09:35:07 -0700 (PDT) X-Google-Smtp-Source: AG47ELvz8EX8EBpf2TIDyHqJQ7qMTrZ7aj8DHuzYPvfYF/CkqQvNNomzA05XqZqqxAYwmA1qv4uZ X-Received: by 2002:a24:2b50:: with SMTP id h77-v6mr4887255ita.103.1521650107389; Wed, 21 Mar 2018 09:35:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521650107; cv=none; d=google.com; s=arc-20160816; b=L365USwAHaciNYTY1rSD2/gLryk+I5Z3idXgFLqa0iIwZmEXuAo4kLIrzhOpQdcDWa NdnArM85E2bK2wF8XCOgXN+8ZtGYaVzxU5iiwqNsRy7POgrseywgXuC+LnHP4LRgAwGg LgOUVRqRuAKpk/ChI0xW6YJkk8P8d5WKFKLlDiic3wdFnL85exIULnl1e9luwt++IKtE Sp3D1rvSsvNW8O+L56qDNlutvAfBXoZgr5eBdrocG7n/zFC6qZKPTZB8yKWZJCVVCTrb jXacLZirBHUpWUL0LJ/4OGr/Qvkx/ej8Pd9xXUr/85IXVNYj068KgFhD8ZNXB/kNulxu 7iTw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:references:in-reply-to:message-id:date:to:from :dkim-signature:arc-authentication-results; bh=sHuy/BLU83cKCDKuwlPJsjOpGYjEJMGu/rEqfHEIt1g=; b=ksZeHpdXnu+rtlk+WxMKHMlRheXF3y0VWroP8/L5eD9K0hoGLDBn97KOJnWsoevIAU Zube5wn3c7+oVH/B1/UJwv1XuYqPEoprXm/GJtv7w3w5YR+71JapibqXSLJIgWYVnSf0 wIFKw2sv0qYXNN222TCC75GE39ndKHhuk2bmZJZb9LZRf0znVFHlKXEFEfZxA/TyL+Uy oBc18cHEBT/w8lbscGg/EnL16ONztMpiUk8A/4He2xyYW8qMICt7b/S5WDNhkMXIZHZm O6Ns0mLXMWJle949k6ZuaffRAJpNz367hqjQz/Kd8XY3Kt63qiHQU/w3XBlC/ePS03XR eeQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=G9HdBZa7; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.xenproject.org (lists.xenproject.org. [192.237.175.120]) by mx.google.com with ESMTPS id e64si3552266ioi.229.2018.03.21.09.35.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 21 Mar 2018 09:35:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=G9HdBZa7; spf=pass (google.com: best guess record for domain of xen-devel-bounces@lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eygfY-00021j-0L; Wed, 21 Mar 2018 16:32:56 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eygfW-000207-AA for xen-devel@lists.xenproject.org; Wed, 21 Mar 2018 16:32:54 +0000 X-Inumbo-ID: 77b4af1d-2d25-11e8-9728-bc764e045a96 Received: from mail-wm0-x242.google.com (unknown [2a00:1450:400c:c09::242]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 77b4af1d-2d25-11e8-9728-bc764e045a96; Wed, 21 Mar 2018 17:32:38 +0100 (CET) Received: by mail-wm0-x242.google.com with SMTP id f125so10926854wme.4 for ; Wed, 21 Mar 2018 09:32:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=N03luX7VE3TsVx5fGwPm387XpIyL7+2RYeo0313kDss=; b=G9HdBZa7G2vR57eN+pM4LowGmBTWcpwuZYrir1Dzs1PNLt0vQ5IR/kYefpFMSc7VD5 w+Pd5lZB8RMaea1xaHw3evcRlzR6Qm3KoAS7j76WKZlMC1qejZrag29e/9LkWBf2skrr Fk18vAfYxDeUk+gvmIRXKoIsEYPIJaDQZ8V2k= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=N03luX7VE3TsVx5fGwPm387XpIyL7+2RYeo0313kDss=; b=HU5fTOmV2LI0cOyazXFt8Ywd2XtGPM9Ah4R2cfZRrHDWp7SbhDJEd0uoj9mOyfSQpD /BhfFoBzIrmtECMIlNHfpAJdbvCCp4eEB+doMRaEbT89I1HmLX65vp9iwEkSGE0I1SAu LjVKGPsscZFMMmo1k9Bi9kkyA8C3JaUi69GDPkIzOvIC9BTU0XRI1u+vqoqLrQVUazIS 8yMDrJVH9eMgmWNaONNiGdlVsp1BIgAauQio0fJEJ9mrHD0qf2AFyPL5B9hZp9apQN1j O/9U/3mtCNZiiKlQgAAZGVoZYo1Lv9eGsBEdP9rP4OeTC6AuQ2flWFd/q/miUckxoedj aTeg== X-Gm-Message-State: AElRT7Gfv4+UJ6kAd8DSy8kDJMfweQQywXtVjZ3xFp7iDgqgBbzr2ZoQ h/QSxnP8erGnkwFxx53CZiloDl2wCqQ= X-Received: by 10.28.206.65 with SMTP id e62mr3207146wmg.26.1521649972202; Wed, 21 Mar 2018 09:32:52 -0700 (PDT) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id n64sm4423724wmd.11.2018.03.21.09.32.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 21 Mar 2018 09:32:51 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Wed, 21 Mar 2018 16:32:00 +0000 Message-Id: <20180321163235.12529-5-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180321163235.12529-1-andre.przywara@linaro.org> References: <20180321163235.12529-1-andre.przywara@linaro.org> Subject: [Xen-devel] [PATCH v3 04/39] ARM: GIC: Allow reading pending state of a hardware IRQ X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: xen-devel@lists.xenproject.org, Andre Przywara MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" To synchronize level triggered interrupts which are mapped into a guest, we need to update the virtual line level at certain points in time. For a hardware mapped interrupt the GIC is the only place where we can easily access this information. Implement a gic_hw_operations member to return the pending state of a particular interrupt. Due to hardware limitations this only works for private interrupts of the current CPU, so there is no CPU field in the prototype. This adds gicv2/3_peek_irq() helper functions, to read a bit in a bitmap spread over several MMIO registers. Signed-off-by: Andre Przywara Reviewed-by: Julien Grall Acked-by: Stefano Stabellini --- Changelog v2 ... v3: - introduce gicv[23]_peek_irq() (moved from patch before) xen/arch/arm/gic-v2.c | 15 +++++++++++++++ xen/arch/arm/gic-v3.c | 19 +++++++++++++++++++ xen/include/asm-arm/gic.h | 11 +++++++++++ 3 files changed, 45 insertions(+) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index d1f1578c05..b440a45e8e 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -243,6 +243,15 @@ static void gicv2_poke_irq(struct irq_desc *irqd, uint32_t offset) writel_gicd(1U << (irqd->irq % 32), offset + (irqd->irq / 32) * 4); } +static bool gicv2_peek_irq(struct irq_desc *irqd, uint32_t offset) +{ + uint32_t reg; + + reg = readl_gicd(offset + (irqd->irq / 32) * 4) & (1U << (irqd->irq % 32)); + + return reg; +} + static void gicv2_set_active_state(struct irq_desc *irqd, bool active) { ASSERT(spin_is_locked(&irqd->lock)); @@ -580,6 +589,11 @@ static unsigned int gicv2_read_apr(int apr_reg) return readl_gich(GICH_APR); } +static bool gicv2_read_pending_state(struct irq_desc *irqd) +{ + return gicv2_peek_irq(irqd, GICD_ISPENDR); +} + static void gicv2_irq_enable(struct irq_desc *desc) { unsigned long flags; @@ -1325,6 +1339,7 @@ const static struct gic_hw_operations gicv2_ops = { .write_lr = gicv2_write_lr, .read_vmcr_priority = gicv2_read_vmcr_priority, .read_apr = gicv2_read_apr, + .read_pending_state = gicv2_read_pending_state, .make_hwdom_dt_node = gicv2_make_hwdom_dt_node, .make_hwdom_madt = gicv2_make_hwdom_madt, .get_hwdom_extra_madt_size = gicv2_get_hwdom_extra_madt_size, diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index f244d51661..5c9a783968 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -444,6 +444,19 @@ static void gicv3_poke_irq(struct irq_desc *irqd, u32 offset, bool wait_for_rwp) gicv3_wait_for_rwp(irqd->irq); } +static bool gicv3_peek_irq(struct irq_desc *irqd, u32 offset) +{ + void __iomem *base; + unsigned int irq = irqd->irq; + + if ( irq >= NR_GIC_LOCAL_IRQS) + base = GICD + (irq / 32) * 4; + else + base = GICD_RDIST_SGI_BASE; + + return !!(readl(base + offset) & (1U << (irq % 32))); +} + static void gicv3_unmask_irq(struct irq_desc *irqd) { gicv3_poke_irq(irqd, GICD_ISENABLER, false); @@ -1144,6 +1157,11 @@ static unsigned int gicv3_read_apr(int apr_reg) } } +static bool gicv3_read_pending_state(struct irq_desc *irqd) +{ + return gicv3_peek_irq(irqd, GICD_ISPENDR); +} + static void gicv3_irq_enable(struct irq_desc *desc) { unsigned long flags; @@ -1812,6 +1830,7 @@ static const struct gic_hw_operations gicv3_ops = { .write_lr = gicv3_write_lr, .read_vmcr_priority = gicv3_read_vmcr_priority, .read_apr = gicv3_read_apr, + .read_pending_state = gicv3_read_pending_state, .secondary_init = gicv3_secondary_cpu_init, .make_hwdom_dt_node = gicv3_make_hwdom_dt_node, .make_hwdom_madt = gicv3_make_hwdom_madt, diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 2aca243ac3..58b910fe6a 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -373,6 +373,8 @@ struct gic_hw_operations { unsigned int (*read_vmcr_priority)(void); /* Read APRn register */ unsigned int (*read_apr)(int apr_reg); + /* Query the pending state of an interrupt at the distributor level. */ + bool (*read_pending_state)(struct irq_desc *irqd); /* Secondary CPU init */ int (*secondary_init)(void); /* Create GIC node for the hardware domain */ @@ -417,6 +419,15 @@ static inline void gic_set_pending_state(struct irq_desc *irqd, bool state) gic_hw_ops->set_pending_state(irqd, state); } +/* + * Read the pending state of an interrupt from the distributor. + * For private IRQs this only works for those of the current CPU. + */ +static inline bool gic_read_pending_state(struct irq_desc *irqd) +{ + return gic_hw_ops->read_pending_state(irqd); +} + void register_gic_ops(const struct gic_hw_operations *ops); int gic_make_hwdom_dt_node(const struct domain *d, const struct dt_device_node *gic,