lkml.org 
[lkml]   [2020]   [Mar]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v6 14/23] irqchip/gic-v4.1: Add VSGI allocation/teardown
    Date
    Allocate per-VPE SGIs when initializing the GIC-specific part of the
    VPE data structure.

    Signed-off-by: Marc Zyngier <maz@kernel.org>
    Reviewed-by: Zenghui Yu <yuzenghui@huawei.com>
    Link: https://lore.kernel.org/r/20200304203330.4967-15-maz@kernel.org
    ---
    drivers/irqchip/irq-gic-v3-its.c | 2 +-
    drivers/irqchip/irq-gic-v4.c | 68 +++++++++++++++++++++++++++++-
    include/linux/irqchip/arm-gic-v4.h | 4 +-
    3 files changed, 71 insertions(+), 3 deletions(-)

    diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c
    index 15250faa9ef7..7ad46ff5f0b9 100644
    --- a/drivers/irqchip/irq-gic-v3-its.c
    +++ b/drivers/irqchip/irq-gic-v3-its.c
    @@ -4053,7 +4053,7 @@ static int its_sgi_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
    struct its_cmd_info *info = vcpu_info;

    switch (info->cmd_type) {
    - case PROP_UPDATE_SGI:
    + case PROP_UPDATE_VSGI:
    vpe->sgi_config[d->hwirq].priority = info->priority;
    vpe->sgi_config[d->hwirq].group = info->group;
    its_configure_sgi(d, false);
    diff --git a/drivers/irqchip/irq-gic-v4.c b/drivers/irqchip/irq-gic-v4.c
    index 117ba6db023d..99b33f60ac63 100644
    --- a/drivers/irqchip/irq-gic-v4.c
    +++ b/drivers/irqchip/irq-gic-v4.c
    @@ -92,6 +92,47 @@ static bool has_v4_1(void)
    return !!sgi_domain_ops;
    }

    +static int its_alloc_vcpu_sgis(struct its_vpe *vpe, int idx)
    +{
    + char *name;
    + int sgi_base;
    +
    + if (!has_v4_1())
    + return 0;
    +
    + name = kasprintf(GFP_KERNEL, "GICv4-sgi-%d", task_pid_nr(current));
    + if (!name)
    + goto err;
    +
    + vpe->fwnode = irq_domain_alloc_named_id_fwnode(name, idx);
    + if (!vpe->fwnode)
    + goto err;
    +
    + kfree(name);
    + name = NULL;
    +
    + vpe->sgi_domain = irq_domain_create_linear(vpe->fwnode, 16,
    + sgi_domain_ops, vpe);
    + if (!vpe->sgi_domain)
    + goto err;
    +
    + sgi_base = __irq_domain_alloc_irqs(vpe->sgi_domain, -1, 16,
    + NUMA_NO_NODE, vpe,
    + false, NULL);
    + if (sgi_base <= 0)
    + goto err;
    +
    + return 0;
    +
    +err:
    + if (vpe->sgi_domain)
    + irq_domain_remove(vpe->sgi_domain);
    + if (vpe->fwnode)
    + irq_domain_free_fwnode(vpe->fwnode);
    + kfree(name);
    + return -ENOMEM;
    +}
    +
    int its_alloc_vcpu_irqs(struct its_vm *vm)
    {
    int vpe_base_irq, i;
    @@ -118,8 +159,13 @@ int its_alloc_vcpu_irqs(struct its_vm *vm)
    if (vpe_base_irq <= 0)
    goto err;

    - for (i = 0; i < vm->nr_vpes; i++)
    + for (i = 0; i < vm->nr_vpes; i++) {
    + int ret;
    vm->vpes[i]->irq = vpe_base_irq + i;
    + ret = its_alloc_vcpu_sgis(vm->vpes[i], i);
    + if (ret)
    + goto err;
    + }

    return 0;

    @@ -132,8 +178,28 @@ int its_alloc_vcpu_irqs(struct its_vm *vm)
    return -ENOMEM;
    }

    +static void its_free_sgi_irqs(struct its_vm *vm)
    +{
    + int i;
    +
    + if (!has_v4_1())
    + return;
    +
    + for (i = 0; i < vm->nr_vpes; i++) {
    + unsigned int irq = irq_find_mapping(vm->vpes[i]->sgi_domain, 0);
    +
    + if (WARN_ON(!irq))
    + continue;
    +
    + irq_domain_free_irqs(irq, 16);
    + irq_domain_remove(vm->vpes[i]->sgi_domain);
    + irq_domain_free_fwnode(vm->vpes[i]->fwnode);
    + }
    +}
    +
    void its_free_vcpu_irqs(struct its_vm *vm)
    {
    + its_free_sgi_irqs(vm);
    irq_domain_free_irqs(vm->vpes[0]->irq, vm->nr_vpes);
    irq_domain_remove(vm->domain);
    irq_domain_free_fwnode(vm->fwnode);
    diff --git a/include/linux/irqchip/arm-gic-v4.h b/include/linux/irqchip/arm-gic-v4.h
    index 8b42d9d9b17e..b120a01952fe 100644
    --- a/include/linux/irqchip/arm-gic-v4.h
    +++ b/include/linux/irqchip/arm-gic-v4.h
    @@ -49,6 +49,8 @@ struct its_vpe {
    };
    /* GICv4.1 implementations */
    struct {
    + struct fwnode_handle *fwnode;
    + struct irq_domain *sgi_domain;
    struct {
    u8 priority;
    bool enabled;
    @@ -103,7 +105,7 @@ enum its_vcpu_info_cmd_type {
    SCHEDULE_VPE,
    DESCHEDULE_VPE,
    INVALL_VPE,
    - PROP_UPDATE_SGI,
    + PROP_UPDATE_VSGI,
    };

    struct its_cmd_info {
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-03-20 19:52    [W:5.223 / U:0.004 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site