From patchwork Thu Mar 22 11:56:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 132265 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp741071ljb; Thu, 22 Mar 2018 04:59:07 -0700 (PDT) X-Google-Smtp-Source: AG47ELv9jraTcVdgXuZbEeAF9z8odN6soUai20zfv2Wvf9yul9dqB9BoVmbyOEMJ2KQ8etUHoXbg X-Received: by 2002:a24:9a45:: with SMTP id l66-v6mr8173828ite.19.1521719947836; Thu, 22 Mar 2018 04:59:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521719947; cv=none; d=google.com; s=arc-20160816; b=i0dI4P4d/sN7R+Qcr0PLI1cXPTwvy9E1msKOib++hV/xOH//tG1Ke/bsHs0QZYTTa5 FV5/4QgrcHVbA7Q6epMRDdAdk0WKURlv4KoMnhjOEubgxwv31lvNefSFIBCbBsX5Rsfj UEsHoEuQ56R+iFoLiEQ5bEb5SpQt8/gUtkHSHkD/rZlHmvPpvhPKdpvCjwGmn+NzOWfz U1zieDTNTOo3+GbnhRW6YQh6bbIRUCjEMa/CmRuD1AXw4vSW3FviX1YfTYI4jBnMwpCt oMOyjm3nivjxaUlbdgCZsSWyuFs73+NsFZ2E9d3upRDNQZHfqWY+C42qXSk/zTgBO7FO 3FZw== 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=UE8TxN61fXncXCG9FtFh30xTBOK9KvHgrmWHdQNDNxw=; b=B3lcqWsik6Te2YPuztEZNwiz+f5+2vZ0f1CSzFf04J8f5eEHITwoJWZbnDasmU5tiI FQIGb2dlABW8TQtIQOVP6E5nEwzmja6H0ZBDHCavrGQ4y1z8kcMjTKLQytFohe6i5kD/ N9VKqRjl4zvji0mHC4MMTe45cMuLoGIv7EawqDFQnkzPLZFVScKdPOlAikfphYWd/2R9 4Hdde6quq2UJG8d/3psPWa9RMHZLdo0nS1Vhewzytsy4rN0qjM8r8ZZI7uPYWwZGYcT1 g36p2QvthK36eXvvIFOrGSgVubLDVFJZiCmstIZQeUu04WpWp/69NhkmdP3irBP+JEAF e0FA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=kVK2MK3b; 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 17-v6si5166195itx.56.2018.03.22.04.59.07 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 22 Mar 2018 04:59: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=kVK2MK3b; 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 1eyyqB-0005xp-2E; Thu, 22 Mar 2018 11:57:07 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eyyq9-0005wG-43 for xen-devel@lists.xenproject.org; Thu, 22 Mar 2018 11:57:05 +0000 X-Inumbo-ID: 186e626d-2dc8-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 186e626d-2dc8-11e8-9728-bc764e045a96; Thu, 22 Mar 2018 12:56:47 +0100 (CET) Received: by mail-wm0-x242.google.com with SMTP id t6so15615108wmt.5 for ; Thu, 22 Mar 2018 04:57:02 -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=zvte5vF9ZK7tlvb0GGV7W0+MriShHCzgfmeVp2YBulk=; b=kVK2MK3bBcD9H5xD3XXuoRu6f+8h160x1aNWiaFt9DoMsbx0EaJK4UkpjxMndwywPN jQXUdGXMXrMPX7Qt8Atoe9n+n91UWExIZHF5CSkSj0Epn9v9H6+iWldiTsHcFEMXxNXR e9XBbSx54K2CZG2zZ7Hrg7+2//a6sUM5REZds= 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=zvte5vF9ZK7tlvb0GGV7W0+MriShHCzgfmeVp2YBulk=; b=cx5nyot7H57q/v9qvXgh3fO+XbYjCuum/Wkfp0cccPjx4cxoF7n2y9MGeRBK2SeSTF VIn8zpM71kkLD+PRXrQfmKg8ujH1QbqeNkmRW1HiIa5ozFdNyxGMFPTBBJ6z+wnqNn8L 1kadwVyPUAU1EN6UCeF08Z9qamENTQ/+I6+xVegnXgaja5WzqV+IG/rTkI8qOtIN96It 6xpHG4Hl8g/Mo5KcNPVYHs6q+A3BT7NwQnw6W5DNnqLwit04lXs3V0pPEYNMb07s8RxH maiEFVHbGVpjlyEOQufi9rjhZLA33UaCl0pTeKYNPOQ+ElsSExwV/WH2/L3XLYadPgok OAMw== X-Gm-Message-State: AElRT7HyDnm/l7eajhL43QFrMFEzeWCbLAt99vOJUKACHotNWNNcDNNI S4Ki0oOgRUU9513f3OvsKdyYNA== X-Received: by 10.28.9.68 with SMTP id 65mr5452942wmj.29.1521719821465; Thu, 22 Mar 2018 04:57:01 -0700 (PDT) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id e67sm12207356wmf.20.2018.03.22.04.57.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 22 Mar 2018 04:57:00 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Thu, 22 Mar 2018 11:56:47 +0000 Message-Id: <20180322115649.5283-2-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180322115649.5283-1-andre.przywara@linaro.org> References: <20180322115649.5283-1-andre.przywara@linaro.org> Subject: [Xen-devel] [PATCH v3a 03/39] ARM: GIC: Allow tweaking the active and pending state of an 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 MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" When playing around with hardware mapped, level triggered virtual IRQs, there is the need to explicitly set the active or pending state of an interrupt at some point. To prepare the GIC for that, we introduce a set_active_state() and a set_pending_state() function to let the VGIC manipulate the state of an associated hardware IRQ. This takes care of properly setting the _IRQ_INPROGRESS bit. Signed-off-by: Andre Przywara Reviewed-by: Julien Grall Acked-by: Stefano Stabellini --- Changelog v3 ... v3a: - always set/clear _IRQ_INPROGRESS bit (not only for guest IRQs) - add comments Changelog v2 ... v3: - extend comments to note preliminary nature of vgic_get_lpi() Changelog v1 ... v2: - reorder header file inclusion xen/arch/arm/gic-v2.c | 41 +++++++++++++++++++++++++++++++++++++++++ xen/arch/arm/gic-v3.c | 37 +++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/gic.h | 24 ++++++++++++++++++++++++ 3 files changed, 102 insertions(+) diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c index aa0fc6c1a1..7374686235 100644 --- a/xen/arch/arm/gic-v2.c +++ b/xen/arch/arm/gic-v2.c @@ -243,6 +243,45 @@ static void gicv2_poke_irq(struct irq_desc *irqd, uint32_t offset) writel_gicd(1U << (irqd->irq % 32), offset + (irqd->irq / 32) * 4); } +/* + * This is forcing the active state of an interrupt, somewhat circumventing + * the normal interrupt flow and the GIC state machine. So use with care + * and only if you know what you are doing. For this reason we also have to + * tinker with the _IRQ_INPROGRESS bit here, since the normal IRQ handler + * will not be involved. + */ +static void gicv2_set_active_state(struct irq_desc *irqd, bool active) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( active ) + { + set_bit(_IRQ_INPROGRESS, &irqd->status); + gicv2_poke_irq(irqd, GICD_ISACTIVER); + } + else + { + clear_bit(_IRQ_INPROGRESS, &irqd->status); + gicv2_poke_irq(irqd, GICD_ICACTIVER); + } +} + +static void gicv2_set_pending_state(struct irq_desc *irqd, bool pending) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( pending ) + { + /* The _IRQ_INPROGRESS bit will be set when the interrupt fires. */ + gicv2_poke_irq(irqd, GICD_ISPENDR); + } + else + { + /* The _IRQ_INPROGRESS remains unchanged. */ + gicv2_poke_irq(irqd, GICD_ICPENDR); + } +} + static void gicv2_set_irq_type(struct irq_desc *desc, unsigned int type) { uint32_t cfg, actual, edgebit; @@ -1278,6 +1317,8 @@ const static struct gic_hw_operations gicv2_ops = { .eoi_irq = gicv2_eoi_irq, .deactivate_irq = gicv2_dir_irq, .read_irq = gicv2_read_irq, + .set_active_state = gicv2_set_active_state, + .set_pending_state = gicv2_set_pending_state, .set_irq_type = gicv2_set_irq_type, .set_irq_priority = gicv2_set_irq_priority, .send_SGI = gicv2_send_SGI, diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c index cb41844af2..a5105ac9e7 100644 --- a/xen/arch/arm/gic-v3.c +++ b/xen/arch/arm/gic-v3.c @@ -477,6 +477,41 @@ static unsigned int gicv3_read_irq(void) return irq; } +/* + * This is forcing the active state of an interrupt, somewhat circumventing + * the normal interrupt flow and the GIC state machine. So use with care + * and only if you know what you are doing. For this reason we also have to + * tinker with the _IRQ_INPROGRESS bit here, since the normal IRQ handler + * will not be involved. + */ +static void gicv3_set_active_state(struct irq_desc *irqd, bool active) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( active ) + { + set_bit(_IRQ_INPROGRESS, &irqd->status); + gicv3_poke_irq(irqd, GICD_ISACTIVER, false); + } + else + { + clear_bit(_IRQ_INPROGRESS, &irqd->status); + gicv3_poke_irq(irqd, GICD_ICACTIVER, false); + } +} + +static void gicv3_set_pending_state(struct irq_desc *irqd, bool pending) +{ + ASSERT(spin_is_locked(&irqd->lock)); + + if ( pending ) + /* The _IRQ_INPROGRESS bit will be set when the interrupt fires. */ + gicv3_poke_irq(irqd, GICD_ISPENDR, false); + else + /* The _IRQ_INPROGRESS bit will remain unchanged. */ + gicv3_poke_irq(irqd, GICD_ICPENDR, false); +} + static inline uint64_t gicv3_mpidr_to_affinity(int cpu) { uint64_t mpidr = cpu_logical_map(cpu); @@ -1769,6 +1804,8 @@ static const struct gic_hw_operations gicv3_ops = { .eoi_irq = gicv3_eoi_irq, .deactivate_irq = gicv3_dir_irq, .read_irq = gicv3_read_irq, + .set_active_state = gicv3_set_active_state, + .set_pending_state = gicv3_set_pending_state, .set_irq_type = gicv3_set_irq_type, .set_irq_priority = gicv3_set_irq_priority, .send_SGI = gicv3_send_sgi, diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h index 3079387e06..2aca243ac3 100644 --- a/xen/include/asm-arm/gic.h +++ b/xen/include/asm-arm/gic.h @@ -345,6 +345,10 @@ struct gic_hw_operations { void (*deactivate_irq)(struct irq_desc *irqd); /* Read IRQ id and Ack */ unsigned int (*read_irq)(void); + /* Force the active state of an IRQ by accessing the distributor */ + void (*set_active_state)(struct irq_desc *irqd, bool state); + /* Force the pending state of an IRQ by accessing the distributor */ + void (*set_pending_state)(struct irq_desc *irqd, bool state); /* Set IRQ type */ void (*set_irq_type)(struct irq_desc *desc, unsigned int type); /* Set IRQ priority */ @@ -393,6 +397,26 @@ static inline unsigned int gic_get_nr_lrs(void) return gic_hw_ops->info->nr_lrs; } +/* + * Set the active state of an IRQ. This should be used with care, as this + * directly forces the active bit, without considering the GIC state machine. + * For private IRQs this only works for those of the current CPU. + */ +static inline void gic_set_active_state(struct irq_desc *irqd, bool state) +{ + gic_hw_ops->set_active_state(irqd, state); +} + +/* + * Set the pending state of an IRQ. This should be used with care, as this + * directly forces the pending bit, without considering the GIC state machine. + * For private IRQs this only works for those of the current CPU. + */ +static inline void gic_set_pending_state(struct irq_desc *irqd, bool state) +{ + gic_hw_ops->set_pending_state(irqd, state); +} + 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, From patchwork Thu Mar 22 11:56:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 132266 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp741132ljb; Thu, 22 Mar 2018 04:59:11 -0700 (PDT) X-Google-Smtp-Source: AG47ELvLRJppMLjG+wKP6NIgEqDRxK1Vc/ZNlZwdkJU+51fiuYj9lDDbUkErc4x5NL1KjHKchZuW X-Received: by 10.107.38.206 with SMTP id m197mr24923191iom.11.1521719950940; Thu, 22 Mar 2018 04:59:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521719950; cv=none; d=google.com; s=arc-20160816; b=vNCTsHPs1yLwN2zwfFxyDEjSEzmdl9pqqHce2iKJo2DOZNcsmjm6nxgukTV+aDaMsk Thf6viTwn8W/0gYchA5xiRMdL7B1wzPZfSKHdlPcbwNGC7oZC1PDkuaFKXLjj+3ziC/4 GMGMUm6+I3N6EO8ovI1iEu21Yxz2Y1nDwO9EKWep53FwM88zPrZubfBVTmook3UM7jGu DC3sL57fmcqe1ieRjnWOEq7iE0jnosUm5j+BR+Ul27u7bKZWbh7/+b4J9h7mbCDgGekt 0wDVbp5DSg/WmGsIy+rkMf6sTIcM7Z41V0c6vLZmhH3Yk+zUJvVvZ7zeKSfrXjcmXlli KqXg== 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=mtuL9QQjWerlWqEOUaPEFG+00CrDRC6UEMsUadhXUCM=; b=DZihNLq24b9j6DtH2c7g1zVvVvQYQxoHcxKBjE5FFLFVRYjrAiSMLE3wVJsWoWI6tE V1UMUHZnl0SEGLkmZ9+ScLXKSBYHZHxPiGnxXYrK5M0kxYPwZNYx60UWkpB2UvMeJvIt Mr8KDhlNdYl5oB0T970IIQepS9SZYJgpbgj+je91mKCtsdrnPF//OR38EC3yIDWZpide BYfV5NhFlXMMMD/xqOVFTffsGuz0lwMtx19G/Jb5rwoD7p2cpRmOhSvbc4lQCHtdigcF 5/355RsFWyIfAW+LY53+4lTTGAxjDI0oam863QB8lYN3AkfVF2ioV/00o+q4WfeLXFlj Pf5Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=gOLvgq13; 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 k66-v6si5044875itk.173.2018.03.22.04.59.10 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 22 Mar 2018 04:59:10 -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=gOLvgq13; 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 1eyyqB-0005yG-F2; Thu, 22 Mar 2018 11:57:07 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eyyqA-0005xA-EU for xen-devel@lists.xenproject.org; Thu, 22 Mar 2018 11:57:06 +0000 X-Inumbo-ID: 195d02a0-2dc8-11e8-9728-bc764e045a96 Received: from mail-wm0-x243.google.com (unknown [2a00:1450:400c:c09::243]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 195d02a0-2dc8-11e8-9728-bc764e045a96; Thu, 22 Mar 2018 12:56:48 +0100 (CET) Received: by mail-wm0-x243.google.com with SMTP id v21so4225409wmc.1 for ; Thu, 22 Mar 2018 04:57:04 -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=XVmouSEb4XctKIrzXJwNrfM8IQQKOLD2QEVedJwBJl0=; b=gOLvgq13wvej+IBFNUA3INA3ZXJfdcGSYRS1b5wfFCp1X2R3ua+ke3V+HbNDquQgz/ Po1Sb73NLAv/pbKRJ/+42SvUJ4F4fycjofu/6n47Ak58kJHt1cK93A7otxus/UHTsYFS 3Z5RhqLrtYgupJr3+NCjkBIDXaruFDNRKUAC0= 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=XVmouSEb4XctKIrzXJwNrfM8IQQKOLD2QEVedJwBJl0=; b=Wv15bAX43EqENMfrHcYS6rSb4EoZTaTebW+y0nI7hknG18Y1DqDqvENRluUKRc6rnQ feEHk3hpba00tGhNot8iWUdL2ffxPLUw8lwCvjPCYe6P+/XgaFLK5oEA2NORfP6J2AGB o8FWHAg3tZLbYNVG0ntvylC3FFIBYKjkSLvYs1DfjQddl9YmJh1u/GkFXNMovVZVx0RE Yc13cOWXX8XLY7+LXNHvP+VodewG/UW5osfgDc3g/YjoWC1vuTnryPN5bdqveZG5AdfV 4VvNpAH089v+qa/9l/0tuUf9KJG6pBFWvVSa6w1JkfkpXS8I3qA9IlFJyzkFjX6bVj4n CLjg== X-Gm-Message-State: AElRT7HPY2MHv3j0ZVdIoXVFt96ialvMghWly1iXAi/LYSgkTXMiPuBD 0eNukG/Wyda62UDze5FJQZN/fg== X-Received: by 10.28.27.194 with SMTP id b185mr5801395wmb.57.1521719822904; Thu, 22 Mar 2018 04:57:02 -0700 (PDT) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id e67sm12207356wmf.20.2018.03.22.04.57.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 22 Mar 2018 04:57:02 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Thu, 22 Mar 2018 11:56:48 +0000 Message-Id: <20180322115649.5283-3-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180322115649.5283-1-andre.przywara@linaro.org> References: <20180322115649.5283-1-andre.przywara@linaro.org> Subject: [Xen-devel] [PATCH v3a 14/39] ARM: new VGIC: Add GICv2 world switch backend 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 MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Processing maintenance interrupts and accessing the list registers are dependent on the host's GIC version. Introduce vgic-v2.c to contain GICv2 specific functions. Implement the GICv2 specific code for syncing the emulation state into the VGIC registers. This also adds the hook to let Xen setup the host GIC addresses. This is based on Linux commit 140b086dd197, written by Marc Zyngier. Signed-off-by: Andre Przywara Acked-by: Julien Grall . + */ + +#include +#include +#include +#include +#include + +#include "vgic.h" + +static struct { + bool enabled; + paddr_t dbase; /* Distributor interface address */ + paddr_t cbase; /* CPU interface address & size */ + paddr_t csize; + paddr_t vbase; /* Virtual CPU interface address */ + + /* Offset to add to get an 8kB contiguous region if GIC is aliased */ + uint32_t aliased_offset; +} gic_v2_hw_data; + +void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t csize, + paddr_t vbase, uint32_t aliased_offset) +{ + gic_v2_hw_data.enabled = true; + gic_v2_hw_data.dbase = dbase; + gic_v2_hw_data.cbase = cbase; + gic_v2_hw_data.csize = csize; + gic_v2_hw_data.vbase = vbase; + gic_v2_hw_data.aliased_offset = aliased_offset; + + printk("Using the new VGIC implementation.\n"); +} + +/* + * transfer the content of the LRs back into the corresponding ap_list: + * - active bit is transferred as is + * - pending bit is + * - transferred as is in case of edge sensitive IRQs + * - set to the line-level (resample time) for level sensitive IRQs + */ +void vgic_v2_fold_lr_state(struct vcpu *vcpu) +{ + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic; + unsigned int used_lrs = vcpu->arch.vgic.used_lrs; + unsigned long flags; + unsigned int lr; + + if ( !used_lrs ) /* No LRs used, so nothing to sync back here. */ + return; + + gic_hw_ops->update_hcr_status(GICH_HCR_UIE, false); + + for ( lr = 0; lr < used_lrs; lr++ ) + { + struct gic_lr lr_val; + uint32_t intid; + struct vgic_irq *irq; + struct irq_desc *desc = NULL; + bool have_desc_lock = false; + + gic_hw_ops->read_lr(lr, &lr_val); + + /* + * TODO: Possible optimization to avoid reading LRs: + * Read the ELRSR to find out which of our LRs have been cleared + * by the guest. We just need to know the IRQ number for those, which + * we could save in an array when populating the LRs. + * This trades one MMIO access (ELRSR) for possibly more than one (LRs), + * but requires some more code to save the IRQ number and to handle + * those finished IRQs according to the algorithm below. + * We need some numbers to justify this: chances are that we don't + * have many LRs in use most of the time, so we might not save much. + */ + gic_hw_ops->clear_lr(lr); + + intid = lr_val.virq; + irq = vgic_get_irq(vcpu->domain, vcpu, intid); + + local_irq_save(flags); + spin_lock(&irq->irq_lock); + + /* The locking order forces us to drop and re-take the locks here. */ + if ( irq->hw ) + { + spin_unlock(&irq->irq_lock); + + desc = irq_to_desc(irq->hwintid); + spin_lock(&desc->lock); + spin_lock(&irq->irq_lock); + + /* This h/w IRQ should still be assigned to the virtual IRQ. */ + ASSERT(irq->hw && desc->irq == irq->hwintid); + + have_desc_lock = true; + } + + /* + * If a hardware mapped IRQ has been handled for good, we need to + * clear the _IRQ_INPROGRESS bit to allow handling of new IRQs. + * + * TODO: This is probably racy, but is so already in the existing + * VGIC. A fix does not seem to be trivial. + */ + if ( irq->hw && !lr_val.active && !lr_val.pending ) + clear_bit(_IRQ_INPROGRESS, &desc->status); + + /* Always preserve the active bit */ + irq->active = lr_val.active; + + /* Edge is the only case where we preserve the pending bit */ + if ( irq->config == VGIC_CONFIG_EDGE && lr_val.pending ) + { + irq->pending_latch = true; + + if ( vgic_irq_is_sgi(intid) ) + irq->source |= (1U << lr_val.virt.source); + } + + /* Clear soft pending state when level irqs have been acked. */ + if ( irq->config == VGIC_CONFIG_LEVEL && !lr_val.pending ) + irq->pending_latch = false; + + /* + * Level-triggered mapped IRQs are special because we only + * observe rising edges as input to the VGIC. + * + * If the guest never acked the interrupt we have to sample + * the physical line and set the line level, because the + * device state could have changed or we simply need to + * process the still pending interrupt later. + * + * If this causes us to lower the level, we have to also clear + * the physical active state, since we will otherwise never be + * told when the interrupt becomes asserted again. + */ + if ( vgic_irq_is_mapped_level(irq) && lr_val.pending ) + { + ASSERT(irq->hwintid >= VGIC_NR_PRIVATE_IRQS); + + irq->line_level = gic_read_pending_state(desc); + + if ( !irq->line_level ) + gic_set_active_state(desc, false); + } + + spin_unlock(&irq->irq_lock); + if ( have_desc_lock ) + spin_unlock(&desc->lock); + local_irq_restore(flags); + + vgic_put_irq(vcpu->domain, irq); + } + + gic_hw_ops->update_hcr_status(GICH_HCR_EN, false); + vgic_cpu->used_lrs = 0; +} + +/** + * vgic_v2_populate_lr() - Populates an LR with the state of a given IRQ. + * @vcpu: The VCPU which the given @irq belongs to. + * @irq: The IRQ to convert into an LR. The irq_lock must be held already. + * @lr: The LR number to transfer the state into. + * + * This moves a virtual IRQ, represented by its vgic_irq, into a list register. + * Apart from translating the logical state into the LR bitfields, it also + * changes some state in the vgic_irq. + * For an edge sensitive IRQ the pending state is cleared in struct vgic_irq, + * for a level sensitive IRQ the pending state value is unchanged, as it is + * dictated directly by the input line level. + * + * If @irq describes an SGI with multiple sources, we choose the + * lowest-numbered source VCPU and clear that bit in the source bitmap. + * + * The irq_lock must be held by the caller. + */ +void vgic_v2_populate_lr(struct vcpu *vcpu, struct vgic_irq *irq, int lr) +{ + struct gic_lr lr_val = {0}; + + lr_val.virq = irq->intid; + + if ( irq_is_pending(irq) ) + { + lr_val.pending = true; + + if ( irq->config == VGIC_CONFIG_EDGE ) + irq->pending_latch = false; + + if ( vgic_irq_is_sgi(irq->intid) ) + { + uint32_t src = ffs(irq->source); + + BUG_ON(!src); + lr_val.virt.source = (src - 1); + irq->source &= ~(1 << (src - 1)); + if ( irq->source ) + irq->pending_latch = true; + } + } + + lr_val.active = irq->active; + + if ( irq->hw ) + { + lr_val.hw_status = true; + lr_val.hw.pirq = irq->hwintid; + /* + * Never set pending+active on a HW interrupt, as the + * pending state is kept at the physical distributor + * level. + */ + if ( irq->active && irq_is_pending(irq) ) + lr_val.pending = false; + } + else + { + if ( irq->config == VGIC_CONFIG_LEVEL ) + lr_val.virt.eoi = true; + } + + /* + * Level-triggered mapped IRQs are special because we only observe + * rising edges as input to the VGIC. We therefore lower the line + * level here, so that we can take new virtual IRQs. See + * vgic_v2_fold_lr_state for more info. + */ + if ( vgic_irq_is_mapped_level(irq) && lr_val.pending ) + irq->line_level = false; + + /* The GICv2 LR only holds five bits of priority. */ + lr_val.priority = irq->priority >> 3; + + gic_hw_ops->write_lr(lr, &lr_val); +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c index d91ed29d96..214176c14e 100644 --- a/xen/arch/arm/vgic/vgic.c +++ b/xen/arch/arm/vgic/vgic.c @@ -520,6 +520,7 @@ retry: static void vgic_fold_lr_state(struct vcpu *vcpu) { + vgic_v2_fold_lr_state(vcpu); } /* Requires the irq_lock to be held. */ @@ -527,6 +528,8 @@ static void vgic_populate_lr(struct vcpu *vcpu, struct vgic_irq *irq, int lr) { ASSERT(spin_is_locked(&irq->irq_lock)); + + vgic_v2_populate_lr(vcpu, irq, lr); } static void vgic_set_underflow(struct vcpu *vcpu) @@ -640,7 +643,10 @@ void vgic_sync_to_lrs(void) spin_lock(¤t->arch.vgic.ap_list_lock); vgic_flush_lr_state(current); spin_unlock(¤t->arch.vgic.ap_list_lock); + + gic_hw_ops->update_hcr_status(GICH_HCR_EN, 1); } + /* * Local variables: * mode: C diff --git a/xen/arch/arm/vgic/vgic.h b/xen/arch/arm/vgic/vgic.h index 1547478518..e2b6d51e47 100644 --- a/xen/arch/arm/vgic/vgic.h +++ b/xen/arch/arm/vgic/vgic.h @@ -27,6 +27,11 @@ static inline bool irq_is_pending(struct vgic_irq *irq) return irq->pending_latch || irq->line_level; } +static inline bool vgic_irq_is_mapped_level(struct vgic_irq *irq) +{ + return irq->config == VGIC_CONFIG_LEVEL && irq->hw; +} + struct vgic_irq *vgic_get_irq(struct domain *d, struct vcpu *vcpu, uint32_t intid); void vgic_put_irq(struct domain *d, struct vgic_irq *irq); @@ -41,6 +46,10 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq) atomic_inc(&irq->refcount); } +void vgic_v2_fold_lr_state(struct vcpu *vcpu); +void vgic_v2_populate_lr(struct vcpu *vcpu, struct vgic_irq *irq, int lr); +void vgic_v2_set_underflow(struct vcpu *vcpu); + #endif /* From patchwork Thu Mar 22 11:56:49 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andre Przywara X-Patchwork-Id: 132264 Delivered-To: patch@linaro.org Received: by 10.46.84.29 with SMTP id i29csp741056ljb; Thu, 22 Mar 2018 04:59:07 -0700 (PDT) X-Google-Smtp-Source: AG47ELvPJw58k0vq+7FdfuV4Fm2u8FTTLElaCeRyFYScAc7RDvcjlHPlrfgiVVElwa3xw915+aL5 X-Received: by 2002:a24:5491:: with SMTP id t139-v6mr8042584ita.89.1521719947056; Thu, 22 Mar 2018 04:59:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1521719947; cv=none; d=google.com; s=arc-20160816; b=u9AxLbHfZRqolWsOUBSFXQdigZbbH7akzi+sg8rH7c43ufbDoqX7pHuP2LNmSH2WJ6 qcxOnI8XAmTZZUSJY3wj4+F7J9YzteADI9dNL1KZCojWGquZLeDnEhfr4ZWSlygbmlSP Gnv2ET/rdR+85DoPREpmWduNWEHqgGEYi/CBn0McoVygHFp5dCsGikry6DuQUtVoiPeD qoY9HIOgQaqzqyci5gerDYUs9PszOEEnaLWidd8LIg0K53dQgy1YoSERtourJoJ/JaCf w+o8+f66hWW1UCODDxlGNCxyqeLNjqj6zvk8KwxAU6ttAR/ipl/WcT8ntvirsg2zgcbW 5Ucw== 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=EhnU9HIGEM+gB7BBIb5upiaOFgWXLHqXwoNEWlmbR3E=; b=qCwX1QOi0HGaAqVroauflG5XHCYW5tqNlaTSbh4Sgzg/GKVEnJEoP4wJ8GtMTWBl21 pftxlBGQ8OM4PipzTGG/AGrr7QBECrMkpDWhR7HhulzIKAJMUHZCr9gWw83gdMiZzqnz ceias6D3cRHTcD3Gg0Fj/UWaM04KvCIUPYVvdRJZih2q7QIvVRZ1oSQxv6lwVAqvkVsd ZIOBzFhIA/pdrIEHq/tDt8eJw+bIwU1vgEG/n9W23HpPndU5G5/1i6NuHH2FktUbCzbC EMKIt7WIeH/decaPvGQdXnRIQs529B7h1LbfshoGUpWkGJ4dhddCBi57WH7DOudgic4t KNOQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=RCqxOeAL; 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 t5-v6si349980itf.158.2018.03.22.04.59.06 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 22 Mar 2018 04:59: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=RCqxOeAL; 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 1eyyqB-0005yp-SU; Thu, 22 Mar 2018 11:57:07 +0000 Received: from us1-rack-dfw2.inumbo.com ([104.130.134.6]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1eyyqA-0005xQ-PJ for xen-devel@lists.xenproject.org; Thu, 22 Mar 2018 11:57:06 +0000 X-Inumbo-ID: 19de7547-2dc8-11e8-9728-bc764e045a96 Received: from mail-wm0-x241.google.com (unknown [2a00:1450:400c:c09::241]) by us1-rack-dfw2.inumbo.com (Halon) with ESMTPS id 19de7547-2dc8-11e8-9728-bc764e045a96; Thu, 22 Mar 2018 12:56:49 +0100 (CET) Received: by mail-wm0-x241.google.com with SMTP id v21so4225479wmc.1 for ; Thu, 22 Mar 2018 04:57:05 -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=pMku6kU8Pd/TESz90YxBY+YuDKILn5Q0S2X0Rh0vW8A=; b=RCqxOeAL0O9diDflAW7mL57mV5PYuqOGB4r3bPke9C9TI6H+E7h6PEuT/56l06xoBD Gnet1z+/g6kf3D0JvHqjyDl4YLpw+eryuHAHdo9Qa7qkRuP3Nd+MrBd15EM5P8C4hnbc PB97jlFhz71ukyb2MipB6Oofn2Zrc302MTZLY= 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=pMku6kU8Pd/TESz90YxBY+YuDKILn5Q0S2X0Rh0vW8A=; b=HJZ+TX8rWsiMOBg1Q5KDF5bquAwaPp2BH9gDyxCcg7XXhjp6JwbxP2Swt4gr05zBtW vwLZavQBoVgGr8pr/HP/+PS9yPyggZnfG1781SVfikQny/nVgGzOTDIj1deHkO2Xx619 gFnfiQy+TbW5gOfqSuTI9zc+y+4E9d3P4a0Qiexp0G0nRmj9MtVIfh4EB6iV/3h1J88b A8wjawrNSZW212vMI1G4h2Uy/AYi8PIwOHpxwTM/2g3CTzLkg7L2u25TN5Ypockp7VW/ jVnk/xRpZAc2wwULw37rqhUzBQfJrzGbe9txeSNlUbiKFnkzyoeEJiOCEeX+i9S1uLme 587w== X-Gm-Message-State: AElRT7ETS2rRvrejwSFoVr7xTLOA3hUvzoT6fpEBFqnPsClsMbQgrnvs Jb1HYETPjGy73cJxUo451HwSxwkS9XE= X-Received: by 10.28.127.204 with SMTP id a195mr5671854wmd.58.1521719823989; Thu, 22 Mar 2018 04:57:03 -0700 (PDT) Received: from e104803-lin.lan (mail.andrep.de. [217.160.17.100]) by smtp.gmail.com with ESMTPSA id e67sm12207356wmf.20.2018.03.22.04.57.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 22 Mar 2018 04:57:03 -0700 (PDT) From: Andre Przywara To: Julien Grall , Stefano Stabellini Date: Thu, 22 Mar 2018 11:56:49 +0000 Message-Id: <20180322115649.5283-4-andre.przywara@linaro.org> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180322115649.5283-1-andre.przywara@linaro.org> References: <20180322115649.5283-1-andre.przywara@linaro.org> Subject: [Xen-devel] [PATCH v3a 39/39] ARM: VGIC: wire new VGIC(-v2) files into Xen build system 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 MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Now that we have both the old VGIC prepared to cope with a sibling and the code for the new VGIC in place, lets add a Kconfig option to enable the new code and wire it into the Xen build system. This will add a compile time option to use either the "old" or the "new" VGIC. In the moment this is restricted to a vGIC-v2. To make the build system happy, we provide a temporary dummy implementation of vgic_v3_setup_hw() to allow building for now. Signed-off-by: Andre Przywara Acked-by: Julien Grall Acked-by: Stefano Stabellini --- Changelog v3 ... v3a: - print panic when trying to run on GICv3 hardware Changelog v2 ... v3: - fix indentation of Kconfig entry - select NEEDS_LIST_SORT - drop unconditional list_sort.o inclusion Changelog v1 ... v2: - add Kconfig help text - use separate Makefile in vgic/ directory - protect compilation without GICV3 support - always include list_sort() in build xen/arch/arm/Kconfig | 18 +++++++++++++++++- xen/arch/arm/Makefile | 5 ++++- xen/arch/arm/vgic/Makefile | 5 +++++ xen/arch/arm/vgic/vgic.c | 11 +++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 xen/arch/arm/vgic/Makefile diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index 2782ee6589..8174c0c635 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -48,7 +48,23 @@ config HAS_GICV3 config HAS_ITS bool prompt "GICv3 ITS MSI controller support" if EXPERT = "y" - depends on HAS_GICV3 + depends on HAS_GICV3 && !NEW_VGIC + +config NEW_VGIC + bool + prompt "Use new VGIC implementation" + select NEEDS_LIST_SORT + ---help--- + + This is an alternative implementation of the ARM GIC interrupt + controller emulation, based on the Linux/KVM VGIC. It has a better + design and fixes many shortcomings of the existing GIC emulation in + Xen. It will eventually replace the existing/old VGIC. + However at the moment it lacks support for Dom0 using the ITS for + using MSIs. + Say Y if you want to help testing this new code or if you experience + problems with the standard emulation. + At the moment this implementation is not security supported. config SBSA_VUART_CONSOLE bool "Emulated SBSA UART console support" diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index 41d7366527..a9533b107e 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -16,7 +16,6 @@ obj-y += domain_build.o obj-y += domctl.o obj-$(EARLY_PRINTK) += early_printk.o obj-y += gic.o -obj-y += gic-vgic.o obj-y += gic-v2.o obj-$(CONFIG_HAS_GICV3) += gic-v3.o obj-$(CONFIG_HAS_ITS) += gic-v3-its.o @@ -47,10 +46,14 @@ obj-y += sysctl.o obj-y += time.o obj-y += traps.o obj-y += vcpreg.o +subdir-$(CONFIG_NEW_VGIC) += vgic +ifneq ($(CONFIG_NEW_VGIC),y) +obj-y += gic-vgic.o obj-y += vgic.o obj-y += vgic-v2.o obj-$(CONFIG_HAS_GICV3) += vgic-v3.o obj-$(CONFIG_HAS_ITS) += vgic-v3-its.o +endif obj-y += vm_event.o obj-y += vtimer.o obj-$(CONFIG_SBSA_VUART_CONSOLE) += vpl011.o diff --git a/xen/arch/arm/vgic/Makefile b/xen/arch/arm/vgic/Makefile new file mode 100644 index 0000000000..806826948e --- /dev/null +++ b/xen/arch/arm/vgic/Makefile @@ -0,0 +1,5 @@ +obj-y += vgic.o +obj-y += vgic-v2.o +obj-y += vgic-mmio.o +obj-y += vgic-mmio-v2.o +obj-y += vgic-init.o diff --git a/xen/arch/arm/vgic/vgic.c b/xen/arch/arm/vgic/vgic.c index f9a5088285..ac18cab6f3 100644 --- a/xen/arch/arm/vgic/vgic.c +++ b/xen/arch/arm/vgic/vgic.c @@ -981,6 +981,17 @@ unsigned int vgic_max_vcpus(const struct domain *d) return min_t(unsigned int, MAX_VIRT_CPUS, vgic_vcpu_limit); } +#ifdef CONFIG_HAS_GICV3 +/* Dummy implementation to allow building without actual vGICv3 support. */ +void vgic_v3_setup_hw(paddr_t dbase, + unsigned int nr_rdist_regions, + const struct rdist_region *regions, + unsigned int intid_bits) +{ + panic("New VGIC implementation does not yet support GICv3."); +} +#endif + /* * Local variables: * mode: C