irqchip/gic-v3-its: Setup VLPI properties at map time
authorMarc Zyngier <marc.zyngier@arm.com>
Thu, 26 Oct 2017 09:44:07 +0000 (10:44 +0100)
committerMarc Zyngier <marc.zyngier@arm.com>
Thu, 2 Nov 2017 15:55:44 +0000 (15:55 +0000)
So far, we require the hypervisor to update the VLPI properties
once the the VLPI mapping has been established. While this
makes it easy for the ITS driver, it creates a window where
an incoming interrupt can be delivered with an unknown set
of properties. Not very nice.

Instead, let's add a "properties" field to the mapping structure,
and use that to configure the VLPI before it actually gets mapped.

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
drivers/irqchip/irq-gic-v3-its.c
include/linux/irqchip/arm-gic-v4.h

index 6a74f0497f822525b0a305ab66183e4203c995de..29b2ff5c684180b17885fbd8057e8629e196148b 100644 (file)
@@ -1008,9 +1008,15 @@ static void lpi_write_config(struct irq_data *d, u8 clr, u8 set)
        if (irqd_is_forwarded_to_vcpu(d)) {
                struct its_device *its_dev = irq_data_get_irq_chip_data(d);
                u32 event = its_get_event_id(d);
+               struct its_vlpi_map *map;
 
                prop_page = its_dev->event_map.vm->vprop_page;
-               hwirq = its_dev->event_map.vlpi_maps[event].vintid;
+               map = &its_dev->event_map.vlpi_maps[event];
+               hwirq = map->vintid;
+
+               /* Remember the updated property */
+               map->properties &= ~clr;
+               map->properties |= set | LPI_PROP_GROUP1;
        } else {
                prop_page = gic_rdists->prop_page;
                hwirq = d->hwirq;
@@ -1249,12 +1255,20 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
                /* Ensure all the VPEs are mapped on this ITS */
                its_map_vm(its_dev->its, info->map->vm);
 
+               /*
+                * Flag the interrupt as forwarded so that we can
+                * start poking the virtual property table.
+                */
+               irqd_set_forwarded_to_vcpu(d);
+
+               /* Write out the property to the prop table */
+               lpi_write_config(d, 0xff, info->map->properties);
+
                /* Drop the physical mapping */
                its_send_discard(its_dev, event);
 
                /* and install the virtual one */
                its_send_vmapti(its_dev, event);
-               irqd_set_forwarded_to_vcpu(d);
 
                /* Increment the number of VLPIs */
                its_dev->event_map.nr_vlpis++;
index 43cde15f221bb92c2a4e751a4c9237d69191b48d..447da8ca2156221749876d53c84430c62e729980 100644 (file)
@@ -71,12 +71,14 @@ struct its_vpe {
  * @vm:                Pointer to the GICv4 notion of a VM
  * @vpe:       Pointer to the GICv4 notion of a virtual CPU (VPE)
  * @vintid:    Virtual LPI number
+ * @properties:        Priority and enable bits (as written in the prop table)
  * @db_enabled:        Is the VPE doorbell to be generated?
  */
 struct its_vlpi_map {
        struct its_vm           *vm;
        struct its_vpe          *vpe;
        u32                     vintid;
+       u8                      properties;
        bool                    db_enabled;
 };