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

[Xen-devel] [PATCH 14/28] ARM: vGICv3: Handle disabled LPIs



If a guest disables an LPI, we do not forward this to the associated
host LPI to avoid queueing commands to the host ITS command queue.
So it may happen that an LPI fires nevertheless on the host. In this
case we can bail out early, but have to save the pending state on the
virtual side.

Signed-off-by: Andre Przywara <andre.przywara@xxxxxxx>
---
 xen/arch/arm/gic-v3-lpi.c  |  8 ++++++++
 xen/arch/arm/vgic-v3.c     | 12 ++++++++++++
 xen/include/asm-arm/vgic.h |  6 ++++++
 3 files changed, 26 insertions(+)

diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c
index d270053..ade8b69 100644
--- a/xen/arch/arm/gic-v3-lpi.c
+++ b/xen/arch/arm/gic-v3-lpi.c
@@ -124,6 +124,14 @@ void do_LPI(unsigned int lpi)
 
     put_domain(d);
 
+    /*
+     * We keep all host LPIs enabled, so check if it's disabled on the guest
+     * side and just record this LPI in the virtual pending table in this case.
+     * The guest picks it up once it gets enabled again.
+     */
+    if ( !vgic_can_inject_lpi(vcpu, hlpi.virt_lpi) )
+        return;
+
     vgic_vcpu_inject_irq(vcpu, hlpi.virt_lpi);
 }
 
diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c
index c6db2d7..de625bf 100644
--- a/xen/arch/arm/vgic-v3.c
+++ b/xen/arch/arm/vgic-v3.c
@@ -498,6 +498,18 @@ bool vgic_lpi_is_enabled(struct domain *d, uint32_t vlpi)
     return d->arch.vgic.proptable[vlpi - LPI_OFFSET] & LPI_PROP_ENABLED;
 }
 
+bool vgic_can_inject_lpi(struct vcpu *vcpu, uint32_t vlpi)
+{
+    if ( vlpi >= vcpu->domain->arch.vgic.nr_lpis )
+        return false;
+
+    if ( vgic_lpi_is_enabled(vcpu->domain, vlpi) )
+        return true;
+
+    set_bit(vlpi - LPI_OFFSET, vcpu->arch.vgic.pendtable);
+    return false;
+}
+
 static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info,
                                           uint32_t gicr_reg,
                                           register_t r)
diff --git a/xen/include/asm-arm/vgic.h b/xen/include/asm-arm/vgic.h
index a882fe8..e71b18b 100644
--- a/xen/include/asm-arm/vgic.h
+++ b/xen/include/asm-arm/vgic.h
@@ -323,6 +323,7 @@ int vgic_v3_init(struct domain *d, int *mmio_count);
 #ifdef CONFIG_HAS_GICV3
 extern int vgic_lpi_get_priority(struct domain *d, uint32_t vlpi);
 extern bool vgic_lpi_is_enabled(struct domain *d, uint32_t vlpi);
+extern bool vgic_can_inject_lpi(struct vcpu *v, uint32_t vlpi);
 #else
 static inline int vgic_lpi_get_priority(struct domain *d, uint32_t vlpi)
 {
@@ -333,6 +334,11 @@ static inline bool vgic_lpi_is_enabled(struct domain *d, 
uint32_t vlpi)
 {
     return false;
 }
+
+static inline bool vgic_can_inject_lpi(struct vcpu *v, uint32_t vlpi)
+{
+    return false;
+}
 #endif
 
 extern int domain_vgic_register(struct domain *d, int *mmio_count);
-- 
2.9.0


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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