[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 4/6] kvm: Implement passing device ID to MSI rou
From: |
Pavel Fedin |
Subject: |
[Qemu-devel] [RFC PATCH 4/6] kvm: Implement passing device ID to MSI routing functions |
Date: |
Mon, 28 Sep 2015 16:42:58 +0300 |
Routing add/update functions now take additional PCIDevice pointer. Also,
in order to provide backwards compatibility with older kernels, a new
kvm_msi_flags global variable is provided, and machines, wishing to use
new MSI features, must set appropriates flags in it.
Signed-off-by: Pavel Fedin <address@hidden>
---
hw/i386/kvm/pci-assign.c | 9 +++++----
hw/vfio/pci.c | 11 ++++++-----
hw/virtio/virtio-pci.c | 5 +++--
include/sysemu/kvm.h | 6 ++++--
kvm-all.c | 17 +++++++++++++----
kvm-stub.c | 5 +++--
6 files changed, 34 insertions(+), 19 deletions(-)
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index b1beaa6..132f249 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -980,7 +980,7 @@ static void assigned_dev_update_msi(PCIDevice *pci_dev)
MSIMessage msg = msi_get_message(pci_dev, 0);
int virq;
- virq = kvm_irqchip_add_msi_route(kvm_state, msg);
+ virq = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev);
if (virq < 0) {
perror("assigned_dev_update_msi: kvm_irqchip_add_msi_route");
return;
@@ -1018,7 +1018,7 @@ static void assigned_dev_update_msi_msg(PCIDevice
*pci_dev)
}
kvm_irqchip_update_msi_route(kvm_state, assigned_dev->msi_virq[0],
- msi_get_message(pci_dev, 0));
+ msi_get_message(pci_dev, 0), pci_dev);
}
static bool assigned_dev_msix_masked(MSIXTableEntry *entry)
@@ -1084,7 +1084,7 @@ static int assigned_dev_update_msix_mmio(PCIDevice
*pci_dev)
msg.address = entry->addr_lo | ((uint64_t)entry->addr_hi << 32);
msg.data = entry->data;
- r = kvm_irqchip_add_msi_route(kvm_state, msg);
+ r = kvm_irqchip_add_msi_route(kvm_state, msg, pci_dev);
if (r < 0) {
return r;
}
@@ -1603,7 +1603,8 @@ static void assigned_dev_msix_mmio_write(void *opaque,
hwaddr addr,
msg.data = entry->data;
ret = kvm_irqchip_update_msi_route(kvm_state,
- adev->msi_virq[i], msg);
+ adev->msi_virq[i], msg,
+ pci_dev);
if (ret) {
error_report("Error updating irq routing entry (%d)", ret);
}
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index dcabb6d..8fadbcf 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -424,7 +424,7 @@ static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev,
VFIOMSIVector *vector,
return;
}
- virq = kvm_irqchip_add_msi_route(kvm_state, *msg);
+ virq = kvm_irqchip_add_msi_route(kvm_state, *msg, &vdev->pdev);
if (virq < 0) {
event_notifier_cleanup(&vector->kvm_interrupt);
return;
@@ -449,9 +449,10 @@ static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector)
event_notifier_cleanup(&vector->kvm_interrupt);
}
-static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg)
+static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg,
+ PCIDevice *pdev)
{
- kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg);
+ kvm_irqchip_update_msi_route(kvm_state, vector->virq, msg, pdev);
}
static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
@@ -486,7 +487,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev,
unsigned int nr,
if (!msg) {
vfio_remove_kvm_msi_virq(vector);
} else {
- vfio_update_kvm_msi_virq(vector, *msg);
+ vfio_update_kvm_msi_virq(vector, *msg, pdev);
}
} else {
vfio_add_kvm_msi_virq(vdev, vector, msg, true);
@@ -760,7 +761,7 @@ static void vfio_update_msi(VFIOPCIDevice *vdev)
}
msg = msi_get_message(&vdev->pdev, i);
- vfio_update_kvm_msi_virq(vector, msg);
+ vfio_update_kvm_msi_virq(vector, msg, &vdev->pdev);
}
}
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index eda8205..8f0a063 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -590,7 +590,7 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy
*proxy,
int ret;
if (irqfd->users == 0) {
- ret = kvm_irqchip_add_msi_route(kvm_state, msg);
+ ret = kvm_irqchip_add_msi_route(kvm_state, msg, &proxy->pci_dev);
if (ret < 0) {
return ret;
}
@@ -726,7 +726,8 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy
*proxy,
if (proxy->vector_irqfd) {
irqfd = &proxy->vector_irqfd[vector];
if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
- ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
+ ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg,
+ &proxy->pci_dev);
if (ret < 0) {
return ret;
}
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index d42c464..731f164 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -53,6 +53,7 @@ extern bool kvm_gsi_routing_allowed;
extern bool kvm_gsi_direct_mapping;
extern bool kvm_readonly_mem_allowed;
extern bool kvm_direct_msi_allowed;
+extern uint32_t kvm_msi_flags;
#if defined CONFIG_KVM || !defined NEED_CPU_H
#define kvm_enabled() (kvm_allowed)
@@ -447,8 +448,9 @@ static inline void cpu_clean_state(CPUState *cpu)
}
}
-int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg);
-int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg);
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev);
+int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
+ PCIDevice *dev);
void kvm_irqchip_release_virq(KVMState *s, int virq);
int kvm_irqchip_add_adapter_route(KVMState *s, AdapterInfo *adapter);
diff --git a/kvm-all.c b/kvm-all.c
index 4931b27..b2c2564 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -111,6 +111,7 @@ bool kvm_allowed;
bool kvm_readonly_mem_allowed;
bool kvm_vm_attributes_allowed;
bool kvm_direct_msi_allowed;
+uint32_t kvm_msi_flags;
static const KVMCapabilityInfo kvm_required_capabilites[] = {
KVM_CAP_INFO(USER_MEMORY),
@@ -1189,7 +1190,7 @@ int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg)
return kvm_set_irq(s, route->kroute.gsi, 1);
}
-int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev)
{
struct kvm_irq_routing_entry kroute = {};
int virq;
@@ -1209,10 +1210,14 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage
msg)
kroute.gsi = virq;
kroute.type = KVM_IRQ_ROUTING_MSI;
- kroute.flags = 0;
kroute.u.msi.address_lo = (uint32_t)msg.address;
kroute.u.msi.address_hi = msg.address >> 32;
kroute.u.msi.data = le32_to_cpu(msg.data);
+ kroute.flags = kvm_msi_flags;
+ if (kroute.flags & KVM_MSI_VALID_DEVID) {
+ kroute.u.msi.devid = (pci_bus_num(dev->bus) << 8) | dev->devfn;
+ }
+
if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) {
kvm_irqchip_release_virq(s, virq);
return -EINVAL;
@@ -1224,7 +1229,8 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
return virq;
}
-int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
+int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
+ PCIDevice *dev)
{
struct kvm_irq_routing_entry kroute = {};
@@ -1238,10 +1244,13 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq,
MSIMessage msg)
kroute.gsi = virq;
kroute.type = KVM_IRQ_ROUTING_MSI;
- kroute.flags = 0;
kroute.u.msi.address_lo = (uint32_t)msg.address;
kroute.u.msi.address_hi = msg.address >> 32;
kroute.u.msi.data = le32_to_cpu(msg.data);
+ kroute.flags = kvm_msi_flags;
+ if (kroute.flags & KVM_MSI_VALID_DEVID) {
+ kroute.u.msi.devid = (pci_bus_num(dev->bus) << 8) | dev->devfn;
+ }
if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) {
return -EINVAL;
}
diff --git a/kvm-stub.c b/kvm-stub.c
index d9ad624..08bcc32 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -115,7 +115,7 @@ int kvm_on_sigbus(int code, void *addr)
}
#ifndef CONFIG_USER_ONLY
-int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
+int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg, PCIDevice *dev)
{
return -ENOSYS;
}
@@ -128,7 +128,8 @@ void kvm_irqchip_release_virq(KVMState *s, int virq)
{
}
-int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
+int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg,
+ PCIDevice *dev)
{
return -ENOSYS;
}
--
2.4.4
- [Qemu-devel] [RFC PATCH 0/6] vITS support, Pavel Fedin, 2015/09/29
- [Qemu-devel] [RFC PATCH 4/6] kvm: Implement passing device ID to MSI routing functions,
Pavel Fedin <=
- [Qemu-devel] [RFC PATCH 1/6] kvm: Make KVM_CAP_SIGNAL_MSI globally available, Pavel Fedin, 2015/09/29
- [Qemu-devel] [RFC PATCH 3/6] Add vGICv3 ITS definitions, Pavel Fedin, 2015/09/29
- [Qemu-devel] [RFC PATCH 5/6] kvm_arm: Implement support for ITS emulation by KVM, Pavel Fedin, 2015/09/29
- [Qemu-devel] [RFC PATCH 2/6] hw/intc: Implement ITS base class, Pavel Fedin, 2015/09/29
- [Qemu-devel] [RFC PATCH 6/6] arm/virt: Add ITS to the virt board, Pavel Fedin, 2015/09/29