@@ -861,11 +861,10 @@ static int assign_device(AssignedDevice *dev)
static int assign_intx(AssignedDevice *dev)
{
- struct kvm_assigned_irq assigned_irq_data;
AssignedIRQType new_type;
PCIINTxRoute intx_route;
bool intx_host_msi;
- int r = 0;
+ int r;
/* Interrupt PIN 0 means don't use INTx */
if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0) {
@@ -881,7 +880,7 @@ static int assign_intx(AssignedDevice *dev)
if (dev->intx_route.mode == intx_route.mode &&
dev->intx_route.irq == intx_route.irq) {
- return r;
+ return 0;
}
switch (dev->assigned_irq_type) {
@@ -911,20 +910,17 @@ static int assign_intx(AssignedDevice *dev)
}
retry:
- memset(&assigned_irq_data, 0, sizeof(assigned_irq_data));
- assigned_irq_data.assigned_dev_id = dev->dev_id;
- assigned_irq_data.guest_irq = intx_route.irq;
- assigned_irq_data.flags = KVM_DEV_IRQ_GUEST_INTX;
if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK &&
dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) {
- assigned_irq_data.flags |= KVM_DEV_IRQ_HOST_MSI;
+ intx_host_msi = true;
new_type = ASSIGNED_IRQ_INTX_HOST_MSI;
} else {
- assigned_irq_data.flags |= KVM_DEV_IRQ_HOST_INTX;
+ intx_host_msi = false;
new_type = ASSIGNED_IRQ_INTX_HOST_INTX;
}
- r = kvm_assign_irq(kvm_state, &assigned_irq_data);
+ r = kvm_device_intx_assign(kvm_state, dev->dev_id, intx_host_msi,
+ intx_route.irq);
if (r < 0) {
if (r == -EIO && !(dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK) &&
dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) {
@@ -2091,6 +2091,31 @@ int kvm_device_pci_deassign(KVMState *s, uint32_t dev_id)
return kvm_vm_ioctl(s, KVM_DEASSIGN_PCI_DEVICE, &dev_data);
}
+static int kvm_assign_irq_internal(KVMState *s, uint32_t dev_id,
+ uint32_t irq_type, uint32_t guest_irq)
+{
+ struct kvm_assigned_irq assigned_irq = {
+ .assigned_dev_id = dev_id,
+ .guest_irq = guest_irq,
+ .flags = irq_type,
+ };
+
+ if (kvm_check_extension(s, KVM_CAP_ASSIGN_DEV_IRQ)) {
+ return kvm_vm_ioctl(s, KVM_ASSIGN_DEV_IRQ, &assigned_irq);
+ } else {
+ return kvm_vm_ioctl(s, KVM_ASSIGN_IRQ, &assigned_irq);
+ }
+}
+
+int kvm_device_intx_assign(KVMState *s, uint32_t dev_id, bool use_host_msi,
+ uint32_t guest_irq)
+{
+ uint32_t irq_type = KVM_DEV_IRQ_GUEST_INTX |
+ (use_host_msi ? KVM_DEV_IRQ_HOST_MSI : KVM_DEV_IRQ_HOST_INTX);
+
+ return kvm_assign_irq_internal(s, dev_id, irq_type, guest_irq);
+}
+
static int kvm_deassign_irq_internal(KVMState *s, uint32_t dev_id,
uint32_t type)
{
@@ -19,6 +19,8 @@ int kvm_device_pci_assign(KVMState *s, PCIHostDeviceAddress *dev_addr,
uint32_t flags, uint32_t *dev_id);
int kvm_device_pci_deassign(KVMState *s, uint32_t dev_id);
+int kvm_device_intx_assign(KVMState *s, uint32_t dev_id,
+ bool use_host_msi, uint32_t guest_irq);
int kvm_device_intx_deassign(KVMState *s, uint32_t dev_id, bool use_host_msi);
int kvm_device_msi_deassign(KVMState *s, uint32_t dev_id);
Avoid passing kvm_assigned_irq on INTx assignment and separate this function from (to-be-refactored) MSI/MSI-X assignment. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> --- hw/device-assignment.c | 16 ++++++---------- target-i386/kvm.c | 25 +++++++++++++++++++++++++ target-i386/kvm_i386.h | 2 ++ 3 files changed, 33 insertions(+), 10 deletions(-)