Skip to content

Commit 3047198

Browse files
Alex Williamsonawilliam
authored andcommitted
vfio/cdx: Consolidate MSI configured state onto cdx_irqs
struct vfio_cdx_device carries three fields that track whether MSI has been configured: vdev->cdx_irqs (the allocated vector array), vdev-> msi_count (the array length), and vdev->config_msi (a boolean flag). The three are set together when vfio_cdx_msi_enable() succeeds and cleared together by vfio_cdx_msi_disable(). However, the error paths in vfio_cdx_msi_enable() free the cdx_irqs allocation on failure without resetting the pointer, leaving it stale and skewed from the other two fields until the next enable call overwrites it. Clear vdev->cdx_irqs to NULL alongside the kfree() in both error paths so the pointer consistently reflects the configured state. With that invariant restored and access to the MSI state serialized by cdx_irqs_lock, vdev->config_msi is fully redundant with (vdev->cdx_irqs != NULL). Drop the config_msi field and switch all readers to test cdx_irqs directly. Assisted-by: Claude:claude-opus-4-7 Signed-off-by: Alex Williamson <[email protected]> Acked-by: Nikhil Agarwal <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alex Williamson <[email protected]>
1 parent 670e886 commit 3047198

2 files changed

Lines changed: 14 additions & 16 deletions

File tree

drivers/vfio/cdx/intr.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -32,26 +32,27 @@ static int vfio_cdx_msi_enable(struct vfio_cdx_device *vdev, int nvec)
3232
return -ENOMEM;
3333

3434
ret = cdx_enable_msi(cdx_dev);
35-
if (ret) {
36-
kfree(vdev->cdx_irqs);
37-
return ret;
38-
}
35+
if (ret)
36+
goto err_free;
3937

4038
/* Allocate cdx MSIs */
4139
ret = msi_domain_alloc_irqs(dev, MSI_DEFAULT_DOMAIN, nvec);
42-
if (ret) {
43-
cdx_disable_msi(cdx_dev);
44-
kfree(vdev->cdx_irqs);
45-
return ret;
46-
}
40+
if (ret)
41+
goto err_disable;
4742

4843
for (msi_idx = 0; msi_idx < nvec; msi_idx++)
4944
vdev->cdx_irqs[msi_idx].irq_no = msi_get_virq(dev, msi_idx);
5045

5146
vdev->msi_count = nvec;
52-
vdev->config_msi = 1;
5347

5448
return 0;
49+
50+
err_disable:
51+
cdx_disable_msi(cdx_dev);
52+
err_free:
53+
kfree(vdev->cdx_irqs);
54+
vdev->cdx_irqs = NULL;
55+
return ret;
5556
}
5657

5758
static int vfio_cdx_msi_set_vector_signal(struct vfio_cdx_device *vdev,
@@ -129,7 +130,7 @@ static void vfio_cdx_msi_disable(struct vfio_cdx_device *vdev)
129130

130131
vfio_cdx_msi_set_block(vdev, 0, vdev->msi_count, NULL);
131132

132-
if (!vdev->config_msi)
133+
if (!vdev->cdx_irqs)
133134
return;
134135

135136
msi_domain_free_irqs_all(dev, MSI_DEFAULT_DOMAIN);
@@ -138,7 +139,6 @@ static void vfio_cdx_msi_disable(struct vfio_cdx_device *vdev)
138139

139140
vdev->cdx_irqs = NULL;
140141
vdev->msi_count = 0;
141-
vdev->config_msi = 0;
142142
}
143143

144144
static int vfio_cdx_set_msi_trigger(struct vfio_cdx_device *vdev,
@@ -163,7 +163,7 @@ static int vfio_cdx_set_msi_trigger(struct vfio_cdx_device *vdev,
163163
s32 *fds = data;
164164
int ret;
165165

166-
if (vdev->config_msi)
166+
if (vdev->cdx_irqs)
167167
return vfio_cdx_msi_set_block(vdev, start, count,
168168
fds);
169169
ret = vfio_cdx_msi_enable(vdev, cdx_dev->num_msi);
@@ -177,8 +177,7 @@ static int vfio_cdx_set_msi_trigger(struct vfio_cdx_device *vdev,
177177
return ret;
178178
}
179179

180-
/* Ensure MSI is configured before accessing cdx_irqs */
181-
if (!vdev->config_msi)
180+
if (!vdev->cdx_irqs)
182181
return -EINVAL;
183182

184183
for (i = start; i < start + count; i++) {

drivers/vfio/cdx/private.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ struct vfio_cdx_device {
3838
u32 flags;
3939
#define BME_SUPPORT BIT(0)
4040
u32 msi_count;
41-
u8 config_msi;
4241
};
4342

4443
#ifdef CONFIG_GENERIC_MSI_IRQ

0 commit comments

Comments
 (0)