irqchip/gic-v3-its: Add its_vlpi_map helpers
authorMarc Zyngier <maz@kernel.org>
Fri, 8 Nov 2019 16:58:01 +0000 (16:58 +0000)
committerMarc Zyngier <maz@kernel.org>
Sun, 10 Nov 2019 18:47:52 +0000 (18:47 +0000)
Obtaining the mapping information for a VLPI is something quite common,
and the GICv4.1 code is going to make even more use of it. Expose it as
a separate set of helpers.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
Link: https://lore.kernel.org/r/20191027144234.8395-8-maz@kernel.org
Link: https://lore.kernel.org/r/20191108165805.3071-8-maz@kernel.org
drivers/irqchip/irq-gic-v3-its.c

index e8aeb07..e8d088c 100644 (file)
@@ -207,6 +207,15 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev,
        return its->collections + its_dev->event_map.col_map[event];
 }
 
+static struct its_vlpi_map *dev_event_to_vlpi_map(struct its_device *its_dev,
+                                              u32 event)
+{
+       if (WARN_ON_ONCE(event >= its_dev->event_map.nr_lpis))
+               return NULL;
+
+       return &its_dev->event_map.vlpi_maps[event];
+}
+
 static struct its_collection *irq_to_col(struct irq_data *d)
 {
        struct its_device *its_dev = irq_data_get_irq_chip_data(d);
@@ -971,7 +980,7 @@ static void its_send_invall(struct its_node *its, struct its_collection *col)
 
 static void its_send_vmapti(struct its_device *dev, u32 id)
 {
-       struct its_vlpi_map *map = &dev->event_map.vlpi_maps[id];
+       struct its_vlpi_map *map = dev_event_to_vlpi_map(dev, id);
        struct its_cmd_desc desc;
 
        desc.its_vmapti_cmd.vpe = map->vpe;
@@ -985,7 +994,7 @@ static void its_send_vmapti(struct its_device *dev, u32 id)
 
 static void its_send_vmovi(struct its_device *dev, u32 id)
 {
-       struct its_vlpi_map *map = &dev->event_map.vlpi_maps[id];
+       struct its_vlpi_map *map = dev_event_to_vlpi_map(dev, id);
        struct its_cmd_desc desc;
 
        desc.its_vmovi_cmd.vpe = map->vpe;
@@ -1063,20 +1072,26 @@ static void its_send_vinvall(struct its_node *its, struct its_vpe *vpe)
 /*
  * irqchip functions - assumes MSI, mostly.
  */
+static struct its_vlpi_map *get_vlpi_map(struct irq_data *d)
+{
+       struct its_device *its_dev = irq_data_get_irq_chip_data(d);
+       u32 event = its_get_event_id(d);
+
+       if (!irqd_is_forwarded_to_vcpu(d))
+               return NULL;
+
+       return dev_event_to_vlpi_map(its_dev, event);
+}
 
 static void lpi_write_config(struct irq_data *d, u8 clr, u8 set)
 {
+       struct its_vlpi_map *map = get_vlpi_map(d);
        irq_hw_number_t hwirq;
        void *va;
        u8 *cfg;
 
-       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;
-
-               va = page_address(its_dev->event_map.vm->vprop_page);
-               map = &its_dev->event_map.vlpi_maps[event];
+       if (map) {
+               va = page_address(map->vm->vprop_page);
                hwirq = map->vintid;
 
                /* Remember the updated property */
@@ -1136,11 +1151,14 @@ static void its_vlpi_set_doorbell(struct irq_data *d, bool enable)
 {
        struct its_device *its_dev = irq_data_get_irq_chip_data(d);
        u32 event = its_get_event_id(d);
+       struct its_vlpi_map *map;
 
-       if (its_dev->event_map.vlpi_maps[event].db_enabled == enable)
+       map = dev_event_to_vlpi_map(its_dev, event);
+
+       if (map->db_enabled == enable)
                return;
 
-       its_dev->event_map.vlpi_maps[event].db_enabled = enable;
+       map->db_enabled = enable;
 
        /*
         * More fun with the architecture:
@@ -1369,19 +1387,18 @@ out:
 static int its_vlpi_get(struct irq_data *d, struct its_cmd_info *info)
 {
        struct its_device *its_dev = irq_data_get_irq_chip_data(d);
-       u32 event = its_get_event_id(d);
+       struct its_vlpi_map *map = get_vlpi_map(d);
        int ret = 0;
 
        mutex_lock(&its_dev->event_map.vlpi_lock);
 
-       if (!its_dev->event_map.vm ||
-           !its_dev->event_map.vlpi_maps[event].vm) {
+       if (!its_dev->event_map.vm || !map->vm) {
                ret = -EINVAL;
                goto out;
        }
 
        /* Copy our mapping information to the incoming request */
-       *info->map = its_dev->event_map.vlpi_maps[event];
+       *info->map = *map;
 
 out:
        mutex_unlock(&its_dev->event_map.vlpi_lock);