lkml.org 
[lkml]   [2020]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 11/20] 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>
    ---
    drivers/irqchip/irq-gic-v4.c | 68 +++++++++++++++++++++++++++++-
    include/linux/irqchip/arm-gic-v4.h | 2 +
    2 files changed, 69 insertions(+), 1 deletion(-)

    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 cca4198fa1d5..9fbd0418f569 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;
    --
    2.20.1
    \
     
     \ /
      Last update: 2020-02-14 16:22    [W:4.080 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site