msix: clear pending bit of an unused vector
PCI spec states: if a masked vector has its Pending bit set, and the associated underlying interrupt events are somehow satisfied (usually by software though the exact manner is function-specific), the function must clear the Pending bit, to avoid sending a spurious interrupt message later when software unmasks the vector. In our case this happens if vector becomes unused. Clear pending bit in this case. Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
1f944c661a
commit
98304c846d
27
hw/msix.c
27
hw/msix.c
@ -105,14 +105,6 @@ static int msix_add_config(struct PCIDevice *pdev, unsigned short nentries,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void msix_free_irq_entries(PCIDevice *dev)
|
|
||||||
{
|
|
||||||
int vector;
|
|
||||||
|
|
||||||
for (vector = 0; vector < dev->msix_entries_nr; ++vector)
|
|
||||||
dev->msix_entry_used[vector] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Handle MSI-X capability config write. */
|
/* Handle MSI-X capability config write. */
|
||||||
void msix_write_config(PCIDevice *dev, uint32_t addr,
|
void msix_write_config(PCIDevice *dev, uint32_t addr,
|
||||||
uint32_t val, int len)
|
uint32_t val, int len)
|
||||||
@ -271,6 +263,16 @@ err_index:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void msix_free_irq_entries(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
int vector;
|
||||||
|
|
||||||
|
for (vector = 0; vector < dev->msix_entries_nr; ++vector) {
|
||||||
|
dev->msix_entry_used[vector] = 0;
|
||||||
|
msix_clr_pending(dev, vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Clean up resources for the device. */
|
/* Clean up resources for the device. */
|
||||||
int msix_uninit(PCIDevice *dev)
|
int msix_uninit(PCIDevice *dev)
|
||||||
{
|
{
|
||||||
@ -387,8 +389,13 @@ int msix_vector_use(PCIDevice *dev, unsigned vector)
|
|||||||
/* Mark vector as unused. */
|
/* Mark vector as unused. */
|
||||||
void msix_vector_unuse(PCIDevice *dev, unsigned vector)
|
void msix_vector_unuse(PCIDevice *dev, unsigned vector)
|
||||||
{
|
{
|
||||||
if (vector < dev->msix_entries_nr && dev->msix_entry_used[vector])
|
if (vector >= dev->msix_entries_nr || !dev->msix_entry_used[vector]) {
|
||||||
--dev->msix_entry_used[vector];
|
return;
|
||||||
|
}
|
||||||
|
if (--dev->msix_entry_used[vector]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msix_clr_pending(dev, vector);
|
||||||
}
|
}
|
||||||
|
|
||||||
void msix_unuse_all_vectors(PCIDevice *dev)
|
void msix_unuse_all_vectors(PCIDevice *dev)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user