Commit c1d4d5cd authored by Marc Zyngier's avatar Marc Zyngier

irqchip/gic-v3-its: Add its_vlpi_map helpers

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: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarZenghui 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
parent 576a8342
...@@ -207,6 +207,15 @@ static struct its_collection *dev_event_to_col(struct its_device *its_dev, ...@@ -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]; 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) static struct its_collection *irq_to_col(struct irq_data *d)
{ {
struct its_device *its_dev = irq_data_get_irq_chip_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) ...@@ -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) 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; struct its_cmd_desc desc;
desc.its_vmapti_cmd.vpe = map->vpe; desc.its_vmapti_cmd.vpe = map->vpe;
...@@ -985,7 +994,7 @@ static void its_send_vmapti(struct its_device *dev, u32 id) ...@@ -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) 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; struct its_cmd_desc desc;
desc.its_vmovi_cmd.vpe = map->vpe; desc.its_vmovi_cmd.vpe = map->vpe;
...@@ -1063,20 +1072,26 @@ static void its_send_vinvall(struct its_node *its, struct its_vpe *vpe) ...@@ -1063,20 +1072,26 @@ static void its_send_vinvall(struct its_node *its, struct its_vpe *vpe)
/* /*
* irqchip functions - assumes MSI, mostly. * 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) 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; irq_hw_number_t hwirq;
void *va; void *va;
u8 *cfg; u8 *cfg;
if (irqd_is_forwarded_to_vcpu(d)) { if (map) {
struct its_device *its_dev = irq_data_get_irq_chip_data(d); va = page_address(map->vm->vprop_page);
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];
hwirq = map->vintid; hwirq = map->vintid;
/* Remember the updated property */ /* Remember the updated property */
...@@ -1136,11 +1151,14 @@ static void its_vlpi_set_doorbell(struct irq_data *d, bool enable) ...@@ -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); struct its_device *its_dev = irq_data_get_irq_chip_data(d);
u32 event = its_get_event_id(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; return;
its_dev->event_map.vlpi_maps[event].db_enabled = enable; map->db_enabled = enable;
/* /*
* More fun with the architecture: * More fun with the architecture:
...@@ -1369,19 +1387,18 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info) ...@@ -1369,19 +1387,18 @@ static int its_vlpi_map(struct irq_data *d, struct its_cmd_info *info)
static int its_vlpi_get(struct irq_data *d, struct its_cmd_info *info) 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); 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; int ret = 0;
mutex_lock(&its_dev->event_map.vlpi_lock); mutex_lock(&its_dev->event_map.vlpi_lock);
if (!its_dev->event_map.vm || if (!its_dev->event_map.vm || !map->vm) {
!its_dev->event_map.vlpi_maps[event].vm) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
/* Copy our mapping information to the incoming request */ /* Copy our mapping information to the incoming request */
*info->map = its_dev->event_map.vlpi_maps[event]; *info->map = *map;
out: out:
mutex_unlock(&its_dev->event_map.vlpi_lock); mutex_unlock(&its_dev->event_map.vlpi_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment