[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[XEN PATCH v2 22/25] arm: new VGIC: its: Implement MMIO-based LPI invalidation


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Mykyta Poturai <Mykyta_Poturai@xxxxxxxx>
  • Date: Fri, 10 Nov 2023 12:56:23 +0000
  • Accept-language: en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=epam.com; dmarc=pass action=none header.from=epam.com; dkim=pass header.d=epam.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=HHz5hJhr12VTz+6oRnd6k1m3l8acsXE23yxPfe4m7RA=; b=Ti+7Icr3U8VAeoWzk2TCyOybdtiOUXA84naG+7EyrU5k+LH7wV/OP0VFcUM+PXdesS0ejBm8j3Fm1IDRO3KvmC607Qi+EaK5MXt3dYitU9Xg/pLiqzJbf5vRCCAF6bmTtXmMv7HLDYc9gSlPEjztMKUYEzQcto+w3OkfibQrjI7dD+yJ2D5cCBMlRIpY5fR+QBhWGAsvUFCUFzF3Dk5zoASNQDd+RbMwictCBdyAUuX6lysjoF5tnScRE2YTGd9y82zDxMjgw8yyzMiwtyoLaX5b1pE5/DogktooJhuPD94ULgX2wUhKwUVTErX1ABTN5xhjBt2I64y8WtvXxaG8fg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FZf0sfFhQI0rxfqw20un2bDEXSbRMWQxGazC955Fw3UBB1ZquLANkbuR/CqmyVmAoraR8rp0OV8MIque7NfSvq8TS1Ouh4cb82FfQghGpHk1NMI1ip41be6vIEFrsa4GQaYbd4RD7cYBFbaQqy6sAGeQPT9YSQKPkDTCpWDRa+XdlqlvRZ7SAcPoOutSetCnxFhNXSFNdbPGUSoWa9yg9mNKHwjGMJSUqsBio80020G2RhDdopnaYmnAeG9PbFKYJCXEI5xX0crKUWAAGPxR6LW4rALkMQv71Bwph/XNKpxcZEUtNo/BIQQD8/IUgTY6dnebLTbW0YIFMlz+ZvZnGQ==
  • Cc: Mykyta Poturai <Mykyta_Poturai@xxxxxxxx>, Stefano Stabellini <sstabellini@xxxxxxxxxx>, Julien Grall <julien@xxxxxxx>, Bertrand Marquis <bertrand.marquis@xxxxxxx>, Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>, Michal Orzel <michal.orzel@xxxxxxx>
  • Delivery-date: Fri, 10 Nov 2023 12:56:43 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHaE9VP1TCckR1kUUClKplCDKRdTQ==
  • Thread-topic: [XEN PATCH v2 22/25] arm: new VGIC: its: Implement MMIO-based LPI invalidation

Since GICv4.1, it has become legal for an implementation to advertise
GICR_{INVLPIR,INVALLR,SYNCR} while having an ITS, allowing for a more
efficient invalidation scheme (no guest command queue contention when
multiple CPUs are generating invalidations).

Provide the invalidation registers as a primitive to their ITS
counterpart. Note that we don't advertise them to the guest yet.

Based on Linux commit 4645d11f4a553 by Marc Zyngier

Signed-off-by: Mykyta Poturai <mykyta_poturai@xxxxxxxx>
---
 xen/arch/arm/include/asm/new_vgic.h |  1 +
 xen/arch/arm/vgic/vgic-mmio-v3.c    | 65 +++++++++++++++++++++++++++--
 xen/arch/arm/vgic/vgic-mmio.h       | 15 +++++++
 3 files changed, 78 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/include/asm/new_vgic.h 
b/xen/arch/arm/include/asm/new_vgic.h
index b038fb7861..dfc434ab41 100644
--- a/xen/arch/arm/include/asm/new_vgic.h
+++ b/xen/arch/arm/include/asm/new_vgic.h
@@ -239,6 +239,7 @@ struct vgic_cpu {
     struct vgic_io_device   rd_iodev;
     struct vgic_redist_region *rdreg;
     uint32_t rdreg_index;
+    atomic_t syncr_busy;
     struct vgic_io_device   sgi_iodev;
 
     /* Contains the attributes and gpa of the LPI pending tables. */
diff --git a/xen/arch/arm/vgic/vgic-mmio-v3.c b/xen/arch/arm/vgic/vgic-mmio-v3.c
index 4bf8c21203..0e3835d38a 100644
--- a/xen/arch/arm/vgic/vgic-mmio-v3.c
+++ b/xen/arch/arm/vgic/vgic-mmio-v3.c
@@ -583,6 +583,65 @@ static void vgic_mmio_write_pendbase(struct vcpu *vcpu, 
paddr_t addr,
               old_pendbaser );
 }
 
+static unsigned long vgic_mmio_read_sync(struct vcpu *vcpu, paddr_t addr,
+                                         unsigned int len)
+{
+    return !!atomic_read(&vcpu->arch.vgic.syncr_busy);
+}
+
+static void vgic_set_rdist_busy(struct vcpu *vcpu, bool busy)
+{
+    if ( busy )
+    {
+        atomic_inc(&vcpu->arch.vgic.syncr_busy);
+        smp_mb__after_atomic();
+    }
+    else
+    {
+        smp_mb__before_atomic();
+        atomic_dec(&vcpu->arch.vgic.syncr_busy);
+    }
+}
+
+static void vgic_mmio_write_invlpi(struct vcpu *vcpu, paddr_t addr,
+                                   unsigned int len, unsigned long val)
+{
+    struct vgic_irq *irq;
+
+    /*
+        * If the guest wrote only to the upper 32bit part of the
+        * register, drop the write on the floor, as it is only for
+        * vPEs (which we don't support for obvious reasons).
+        *
+        * Also discard the access if LPIs are not enabled.
+        */
+    if ( (addr & 4) || !vgic_lpis_enabled(vcpu) )
+        return;
+
+    vgic_set_rdist_busy(vcpu, true);
+
+    irq = vgic_get_irq(vcpu->domain, NULL, val & 0xffffffff);
+    if ( irq )
+    {
+        vgic_its_inv_lpi(vcpu->domain, irq);
+        vgic_put_irq(vcpu->domain, irq);
+    }
+
+    vgic_set_rdist_busy(vcpu, false);
+}
+
+static void vgic_mmio_write_invall(struct vcpu *vcpu, paddr_t addr,
+                                   unsigned int len, unsigned long val)
+{
+    /* See vgic_mmio_write_invlpi() for the early return rationale */
+    if ( (addr & 4) || !vgic_lpis_enabled(vcpu) )
+        return;
+
+    vgic_set_rdist_busy(vcpu, true);
+    vgic_its_invall(vcpu);
+    vgic_set_rdist_busy(vcpu, false);
+}
+
 static const struct vgic_register_region vgic_v3_dist_registers[] = {
     REGISTER_DESC_WITH_LENGTH(GICD_CTLR,
         vgic_mmio_read_v3_misc, vgic_mmio_write_v3_misc,
@@ -655,13 +714,13 @@ static const struct vgic_register_region 
vgic_v3_rd_registers[] = {
         vgic_mmio_read_pendbase, vgic_mmio_write_pendbase, 8,
         VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
     REGISTER_DESC_WITH_LENGTH(GICR_INVLPIR,
-        vgic_mmio_read_raz, vgic_mmio_write_wi, 8,
+        vgic_mmio_read_raz, vgic_mmio_write_invlpi, 8,
         VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
     REGISTER_DESC_WITH_LENGTH(GICR_INVALLR,
-        vgic_mmio_read_raz, vgic_mmio_write_wi, 8,
+        vgic_mmio_read_raz, vgic_mmio_write_invall, 8,
         VGIC_ACCESS_64bit | VGIC_ACCESS_32bit),
     REGISTER_DESC_WITH_LENGTH(GICR_SYNCR,
-        vgic_mmio_read_raz, vgic_mmio_write_wi, 4,
+        vgic_mmio_read_sync, vgic_mmio_write_wi, 4,
         VGIC_ACCESS_32bit),
     REGISTER_DESC_WITH_LENGTH(GICR_IDREGS,
         vgic_mmio_read_v3_idregs, vgic_mmio_write_wi, 48,
diff --git a/xen/arch/arm/vgic/vgic-mmio.h b/xen/arch/arm/vgic/vgic-mmio.h
index edf8665cda..12f4d690f6 100644
--- a/xen/arch/arm/vgic/vgic-mmio.h
+++ b/xen/arch/arm/vgic/vgic-mmio.h
@@ -153,4 +153,19 @@ unsigned long extract_bytes(uint64_t data, unsigned int 
offset,
 uint64_t update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
                     unsigned long val);
 
+#ifdef CONFIG_HAS_ITS
+int vgic_its_inv_lpi(struct domain *d, struct vgic_irq *irq);
+int vgic_its_invall(struct vcpu *vcpu);
+#else
+static inline int vgic_its_inv_lpi(struct domain *d, struct vgic_irq *irq)
+{
+    return 0;
+}
+
+static inline int vgic_its_invall(struct vcpu *vcpu)
+{
+    return 0;
+}
+#endif
+
 #endif
-- 
2.34.1



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.