From patchwork Mon Mar 5 16:03:41 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 130654 Delivered-To: patch@linaro.org Received: by 10.46.66.2 with SMTP id p2csp2853522lja; Mon, 5 Mar 2018 08:06:57 -0800 (PST) X-Google-Smtp-Source: AG47ELvwpHdCXxfR368VgLzqYbyzghrdDUE+NBqdcN2apLTNP83ap9RBFp9OHOVWKqtYOP/hRVF0 X-Received: by 10.107.88.10 with SMTP id m10mr16221956iob.144.1520266017768; Mon, 05 Mar 2018 08:06:57 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1520266017; cv=none; d=google.com; s=arc-20160816; b=M/IqqFPGqcJptR9BM3WW5eyfaR6zdC+ulXdzMSzVkuED2mZdo00iTmFtZLf9cXpTPC fw7SlJbVaPppcuA3qrraCe+rcs3d9JQVeHEnE27gbkOXsiwWP0tIvx+tYhfXGW8JWWdh IElgcYcVW+WLWkYYcYfk+L7lWAFEnzgCXgzpolPOu6Z6wc/f+xNi6UVJ9rnUei01NW4G LDUolwI1LErr2BtIvRO7OsVUtqI7tKRZ5mPnWaixgCmMsbln6Bw891/To8sU8uqnkUrm +wf+8zgdDcZYcLm7na7GiZs6yd3RYbF6RzwSfamCkQjeMhWHeeWl7bOI5HGgRnGRKBjY krJQ== 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 :list-subscribe:list-help:list-post:list-unsubscribe:list-id :precedence:subject:cc:references:in-reply-to:message-id:date:to :from:dkim-signature:arc-authentication-results; bh=VIblBgVJh+eYTLU1CbX4FbZ1HzAFMh+pTdUn43RounQ=; b=obl3drXz7I9jdxE3GZV66DiVXE5CVC4La+KKIUARUOE1xibD7gJiT/maGnOZAa90Bj cCDo+Yl949lU0yjE0vUAmxNH+YfePWoknoULgP+usyR4OEfWfFv6KTX7Eo7q9hwGPkWb c9Ic8QlHWqlhZqDbG3Ncq6hee8Ot7kmuj0P8ui/I8AG/s0Ott2ObvSfPnnpqb5Pl6nr5 9klPtXr2VpH3QTqoBuMLY4rBhLcLH8kHZG2oyQJij8rcWLz+xowiz1KuzilhB5mBfh4W +5M4o3/CEEpYa+JYYhd8yj0/miQFnqixmknRX0+gyvBLbLODWC39yZ7Vv15TLxS4JKV6 DXdA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=EuChOzKi; 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 k71si6126401itd.48.2018.03.05.08.06.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 05 Mar 2018 08:06:57 -0800 (PST) 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=EuChOzKi; 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.84_2) (envelope-from ) id 1essbY-0007e1-9X; Mon, 05 Mar 2018 16:04:48 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1essbX-0007c9-I6 for xen-devel@lists.xenproject.org; Mon, 05 Mar 2018 16:04:47 +0000 X-Inumbo-ID: c5699857-208e-11e8-ba59-bc764e045a96 Received: from mail-wr0-x242.google.com (unknown [2a00:1450:400c:c0c::242]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id c5699857-208e-11e8-ba59-bc764e045a96; Mon, 05 Mar 2018 17:03:41 +0100 (CET) Received: by mail-wr0-x242.google.com with SMTP id p104so17811616wrc.12 for ; Mon, 05 Mar 2018 08:04:46 -0800 (PST) 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=ECIJ2cf4PDmJG8l6bVRDddqv1cMhpaHWKLgjf+MOx7g=; b=EuChOzKixmEgWSRFtVfNFKjDw65DVzNHb/KyiiFj0ddIVVxDQW+FQoKCmChXC/4fwg fzzNeiHaxTDZ5xlh37cTQ+1b/OHC+CnrsnU+lzv2EJHw9drkF57XmkaFTW+BQgK5y3To iocInbdcBPdojNVHWQm5WD4WL/ZbRWxZx5LLg= 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=ECIJ2cf4PDmJG8l6bVRDddqv1cMhpaHWKLgjf+MOx7g=; b=puxQ3osJyp9LyQ2vuiG3z46kRYPFgiXXRG5NfwXKsX9pxgw5Kwf7hcfX///IfswmPj r4Hp2nhMOX1wpEBx3MmHSrxFoxK3lOQRuq43YRjy3toSG2JYdr3JqFJSSlrH/6yfqvB7 ZtMZNYQwTK4jyDG8EPNKdHr8mn0L5EniI/7Bvi9O13AvWpcpqux7xDVxDa2+iQ/2nOym eCfJt3uNNdBqLp5kWN8Iv4V1QFvCe0x4cbme/Ci2BvouHLLpBp6NRSQHQ8kvad4MPuip gCUeNenmQ4C1Wuzy10hnz4doClWGBCIr9h1ELhUzs7eldViSwYxH4AVvRbmgZtlw7sLQ es3w== X-Gm-Message-State: APf1xPDgPFLTqMkxKuQ6Knl6M0m3nTmHdJaT6FmjZchkxWbcfTY4wR7i CnxbEZywxxxdyceuoTs6glxb2Q== X-Received: by 10.223.134.12 with SMTP id 12mr12676554wrv.193.1520265885608; Mon, 05 Mar 2018 08:04:45 -0800 (PST) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id y6sm6574381wmy.14.2018.03.05.08.04.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 05 Mar 2018 08:04:45 -0800 (PST) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Mon, 5 Mar 2018 16:03:41 +0000 Message-Id: <20180305160415.16760-24-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180305160415.16760-1-andre.przywara@linaro.org> References: <20180305160415.16760-1-andre.przywara@linaro.org> Cc: xen-devel@lists.xenproject.org Subject: [Xen-devel] [PATCH 23/57] ARM: GIC: allow reading pending state of a hardware IRQ X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , 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 --- Changelog RFC ... v1: - add gicv2/3_peek_irq() helpers - use struct irq_desc* in the interface (instead of just the IRQ number) xen/arch/arm/gic-v2.c | 15 +++++++++++++++ xen/arch/arm/gic-v3.c | 19 +++++++++++++++++++ xen/arch/arm/gic.c | 5 +++++ xen/include/asm-arm/gic.h | 5 +++++ 4 files changed, 44 insertions(+) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index 74169b5633..48352f6499 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -241,6 +241,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)); @@ -549,6 +558,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; @@ -1294,6 +1308,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 c96469f09d..3e75d06c3b 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); @@ -1094,6 +1107,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; @@ -1762,6 +1780,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/arch/arm/gic.c b/xen/arch/arm/gic.c index f1329a630a..67c3b4d86d 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -116,6 +116,11 @@ static void gic_set_irq_priority(struct irq_desc *desc, unsigned int priority) gic_hw_ops->set_irq_priority(desc, priority); } +bool gic_read_pending_state(struct irq_desc *irqd) +{ + return gic_hw_ops->read_pending_state(irqd); +} + /* Program the GIC to route an interrupt to the host (i.e. Xen) * - needs to be called with desc.lock held */ diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 46dcb0fe7c..03667f00cf 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -248,6 +248,9 @@ void gic_set_pending_state(struct irq_desc *irqd, bool state); /* Program the IRQ type into the GIC */ void gic_set_irq_type(struct irq_desc *desc, unsigned int type); +/* Read the pending state of an interrupt from the distributor. */ +bool gic_read_pending_state(struct irq_desc *irqd); + /* Program the GIC to route an interrupt */ extern void gic_route_irq_to_xen(struct irq_desc *desc, unsigned int priority); extern int gic_route_irq_to_guest(struct domain *, unsigned int virq, @@ -382,6 +385,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 */