|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] xen/arm: vpl011: record the virq only once it is reserved
domain_vpl011_init() sets vpl011->virq before vgic_reserve_virq() claims
it, and both a refused reservation and a failed
alloc_unbound_xen_event_channel() take the out1 error path into
domain_vpl011_deinit(), which frees vpl011->virq. That clears the
allocation bit of an interrupt the vPL011 never reserved, so an
interrupt held by another user can be handed out a second time.
Record the virq only after the reservation succeeds.
Fixes: 08bbc1c02d38 ("xen/arm: vpl011: Fix domain_vpl011_init error path")
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxx>
---
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>,
CC: Julien Grall <julien@xxxxxxx>,
CC: Bertrand Marquis <bertrand.marquis@xxxxxxx>,
CC: Michal Orzel <michal.orzel@xxxxxxx>,
CC: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
xen/arch/arm/vpl011.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/xen/arch/arm/vpl011.c b/xen/arch/arm/vpl011.c
index d0d17c76b7..a37e88a8b4 100644
--- a/xen/arch/arm/vpl011.c
+++ b/xen/arch/arm/vpl011.c
@@ -640,6 +640,7 @@ static void vpl011_notification(struct vcpu *v, unsigned
int port)
int domain_vpl011_init(struct domain *d, struct vpl011_init_info *info)
{
int rc;
+ unsigned int virq;
struct vpl011 *vpl011 = &d->arch.vpl011;
if ( vpl011->backend.dom.ring_buf )
@@ -659,7 +660,7 @@ int domain_vpl011_init(struct domain *d, struct
vpl011_init_info *info)
if ( (uart != NULL) && (vpl011_irq > 0) )
{
vpl011->base_addr = uart->base_addr;
- vpl011->virq = vpl011_irq;
+ virq = vpl011_irq;
}
else
{
@@ -685,7 +686,7 @@ int domain_vpl011_init(struct domain *d, struct
vpl011_init_info *info)
else
{
vpl011->base_addr = GUEST_PL011_BASE;
- vpl011->virq = GUEST_VPL011_SPI;
+ virq = GUEST_VPL011_SPI;
}
/*
@@ -724,12 +725,12 @@ int domain_vpl011_init(struct domain *d, struct
vpl011_init_info *info)
}
}
- rc = vgic_reserve_virq(d, vpl011->virq);
- if ( !rc )
+ if ( !vgic_reserve_virq(d, virq) )
{
rc = -EINVAL;
goto out1;
}
+ vpl011->virq = virq;
vpl011->uartfr = TXFE | RXFE;
--
2.47.3
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |