summaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2017-10-26 11:44:07 +0200
committerMarc Zyngier <marc.zyngier@arm.com>2017-11-02 16:55:44 +0100
commitd4d7b4ad2f05c03fb25252aea66f9f3cd7cfbe06 (patch)
tree65b1f84da956429e65ddd0eb1da2b9930834bcb2 /drivers/irqchip
parentMerge tag 'v4.14-rc3' into irq/irqchip-4.15 (diff)
downloadlinux-d4d7b4ad2f05c03fb25252aea66f9f3cd7cfbe06.tar.xz
linux-d4d7b4ad2f05c03fb25252aea66f9f3cd7cfbe06.zip
irqchip/gic-v3-its: Setup VLPI properties at map time
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>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-gic-v3-its.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
index 6a74f0497f82..29b2ff5c6841 100644
--- a/drivers/irqchip/irq-gic-v3-its.c
+++ b/drivers/irqchip/irq-gic-v3-its.c
@@ -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++;