mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 01:03:55 -06:00
vfio-user: handle device interrupts
Forward remote device's interrupts to the guest Signed-off-by: Elena Ufimtseva <elena.ufimtseva@oracle.com> Signed-off-by: John G Johnson <john.g.johnson@oracle.com> Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Message-id: 9523479eaafe050677f4de2af5dd0df18c27cfd9.1655151679.git.jag.raman@oracle.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
3123f93d6b
commit
08cf3dc611
13 changed files with 298 additions and 12 deletions
49
hw/pci/msi.c
49
hw/pci/msi.c
|
@ -134,7 +134,7 @@ void msi_set_message(PCIDevice *dev, MSIMessage msg)
|
|||
pci_set_word(dev->config + msi_data_off(dev, msi64bit), msg.data);
|
||||
}
|
||||
|
||||
MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector)
|
||||
static MSIMessage msi_prepare_message(PCIDevice *dev, unsigned int vector)
|
||||
{
|
||||
uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
|
||||
bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
|
||||
|
@ -159,6 +159,11 @@ MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector)
|
|||
return msg;
|
||||
}
|
||||
|
||||
MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector)
|
||||
{
|
||||
return dev->msi_prepare_message(dev, vector);
|
||||
}
|
||||
|
||||
bool msi_enabled(const PCIDevice *dev)
|
||||
{
|
||||
return msi_present(dev) &&
|
||||
|
@ -241,6 +246,8 @@ int msi_init(struct PCIDevice *dev, uint8_t offset,
|
|||
0xffffffff >> (PCI_MSI_VECTORS_MAX - nr_vectors));
|
||||
}
|
||||
|
||||
dev->msi_prepare_message = msi_prepare_message;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -256,6 +263,7 @@ void msi_uninit(struct PCIDevice *dev)
|
|||
cap_size = msi_cap_sizeof(flags);
|
||||
pci_del_capability(dev, PCI_CAP_ID_MSI, cap_size);
|
||||
dev->cap_present &= ~QEMU_PCI_CAP_MSI;
|
||||
dev->msi_prepare_message = NULL;
|
||||
|
||||
MSI_DEV_PRINTF(dev, "uninit\n");
|
||||
}
|
||||
|
@ -307,6 +315,39 @@ bool msi_is_masked(const PCIDevice *dev, unsigned int vector)
|
|||
return mask & (1U << vector);
|
||||
}
|
||||
|
||||
void msi_set_mask(PCIDevice *dev, int vector, bool mask, Error **errp)
|
||||
{
|
||||
ERRP_GUARD();
|
||||
uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
|
||||
bool msi64bit = flags & PCI_MSI_FLAGS_64BIT;
|
||||
uint32_t irq_state, vector_mask, pending;
|
||||
|
||||
if (vector > PCI_MSI_VECTORS_MAX) {
|
||||
error_setg(errp, "msi: vector %d not allocated. max vector is %d",
|
||||
vector, PCI_MSI_VECTORS_MAX);
|
||||
return;
|
||||
}
|
||||
|
||||
vector_mask = (1U << vector);
|
||||
|
||||
irq_state = pci_get_long(dev->config + msi_mask_off(dev, msi64bit));
|
||||
|
||||
if (mask) {
|
||||
irq_state |= vector_mask;
|
||||
} else {
|
||||
irq_state &= ~vector_mask;
|
||||
}
|
||||
|
||||
pci_set_long(dev->config + msi_mask_off(dev, msi64bit), irq_state);
|
||||
|
||||
pending = pci_get_long(dev->config + msi_pending_off(dev, msi64bit));
|
||||
if (!mask && (pending & vector_mask)) {
|
||||
pending &= ~vector_mask;
|
||||
pci_set_long(dev->config + msi_pending_off(dev, msi64bit), pending);
|
||||
msi_notify(dev, vector);
|
||||
}
|
||||
}
|
||||
|
||||
void msi_notify(PCIDevice *dev, unsigned int vector)
|
||||
{
|
||||
uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev));
|
||||
|
@ -334,11 +375,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector)
|
|||
|
||||
void msi_send_message(PCIDevice *dev, MSIMessage msg)
|
||||
{
|
||||
MemTxAttrs attrs = {};
|
||||
|
||||
attrs.requester_id = pci_requester_id(dev);
|
||||
address_space_stl_le(&dev->bus_master_as, msg.address, msg.data,
|
||||
attrs, NULL);
|
||||
dev->msi_trigger(dev, msg);
|
||||
}
|
||||
|
||||
/* Normally called by pci_default_write_config(). */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue