Skip to content

Commit 6d31b6f

Browse files
author
Marc Zyngier
committed
irqchip/gic-v4.1: Add VSGI allocation/teardown
Allocate per-VPE SGIs when initializing the GIC-specific part of the VPE data structure. Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Zenghui Yu <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent ae699ad commit 6d31b6f

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

drivers/irqchip/irq-gic-v4.c

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,47 @@ static bool has_v4_1(void)
9292
return !!sgi_domain_ops;
9393
}
9494

95+
static int its_alloc_vcpu_sgis(struct its_vpe *vpe, int idx)
96+
{
97+
char *name;
98+
int sgi_base;
99+
100+
if (!has_v4_1())
101+
return 0;
102+
103+
name = kasprintf(GFP_KERNEL, "GICv4-sgi-%d", task_pid_nr(current));
104+
if (!name)
105+
goto err;
106+
107+
vpe->fwnode = irq_domain_alloc_named_id_fwnode(name, idx);
108+
if (!vpe->fwnode)
109+
goto err;
110+
111+
kfree(name);
112+
name = NULL;
113+
114+
vpe->sgi_domain = irq_domain_create_linear(vpe->fwnode, 16,
115+
sgi_domain_ops, vpe);
116+
if (!vpe->sgi_domain)
117+
goto err;
118+
119+
sgi_base = __irq_domain_alloc_irqs(vpe->sgi_domain, -1, 16,
120+
NUMA_NO_NODE, vpe,
121+
false, NULL);
122+
if (sgi_base <= 0)
123+
goto err;
124+
125+
return 0;
126+
127+
err:
128+
if (vpe->sgi_domain)
129+
irq_domain_remove(vpe->sgi_domain);
130+
if (vpe->fwnode)
131+
irq_domain_free_fwnode(vpe->fwnode);
132+
kfree(name);
133+
return -ENOMEM;
134+
}
135+
95136
int its_alloc_vcpu_irqs(struct its_vm *vm)
96137
{
97138
int vpe_base_irq, i;
@@ -118,8 +159,13 @@ int its_alloc_vcpu_irqs(struct its_vm *vm)
118159
if (vpe_base_irq <= 0)
119160
goto err;
120161

121-
for (i = 0; i < vm->nr_vpes; i++)
162+
for (i = 0; i < vm->nr_vpes; i++) {
163+
int ret;
122164
vm->vpes[i]->irq = vpe_base_irq + i;
165+
ret = its_alloc_vcpu_sgis(vm->vpes[i], i);
166+
if (ret)
167+
goto err;
168+
}
123169

124170
return 0;
125171

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

181+
static void its_free_sgi_irqs(struct its_vm *vm)
182+
{
183+
int i;
184+
185+
if (!has_v4_1())
186+
return;
187+
188+
for (i = 0; i < vm->nr_vpes; i++) {
189+
unsigned int irq = irq_find_mapping(vm->vpes[i]->sgi_domain, 0);
190+
191+
if (WARN_ON(!irq))
192+
continue;
193+
194+
irq_domain_free_irqs(irq, 16);
195+
irq_domain_remove(vm->vpes[i]->sgi_domain);
196+
irq_domain_free_fwnode(vm->vpes[i]->fwnode);
197+
}
198+
}
199+
135200
void its_free_vcpu_irqs(struct its_vm *vm)
136201
{
202+
its_free_sgi_irqs(vm);
137203
irq_domain_free_irqs(vm->vpes[0]->irq, vm->nr_vpes);
138204
irq_domain_remove(vm->domain);
139205
irq_domain_free_fwnode(vm->fwnode);

include/linux/irqchip/arm-gic-v4.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ struct its_vpe {
4949
};
5050
/* GICv4.1 implementations */
5151
struct {
52+
struct fwnode_handle *fwnode;
53+
struct irq_domain *sgi_domain;
5254
struct {
5355
u8 priority;
5456
bool enabled;

0 commit comments

Comments
 (0)