aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sysemu/kvm.h4
-rw-r--r--kvm-all.c7
-rw-r--r--target-arm/kvm.c6
-rw-r--r--target-i386/kvm.c6
-rw-r--r--target-mips/kvm.c6
-rw-r--r--target-ppc/kvm.c6
-rw-r--r--target-s390x/kvm.c26
7 files changed, 61 insertions, 0 deletions
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index 104cf3535e..30cb84d2b8 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -158,6 +158,7 @@ extern bool kvm_readonly_mem_allowed;
struct kvm_run;
struct kvm_lapic_state;
+struct kvm_irq_routing_entry;
typedef struct KVMCapabilityInfo {
const char *name;
@@ -270,6 +271,9 @@ int kvm_arch_on_sigbus(int code, void *addr);
void kvm_arch_init_irq_routing(KVMState *s);
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data);
+
int kvm_set_irq(KVMState *s, int irq, int level);
int kvm_irqchip_send_msi(KVMState *s, MSIMessage msg);
diff --git a/kvm-all.c b/kvm-all.c
index 18cc6b4d3d..2f21a4e6fe 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -1225,6 +1225,10 @@ int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg)
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);
+ if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) {
+ kvm_irqchip_release_virq(s, virq);
+ return -EINVAL;
+ }
kvm_add_routing_entry(s, &kroute);
kvm_irqchip_commit_routes(s);
@@ -1250,6 +1254,9 @@ int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg)
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);
+ if (kvm_arch_fixup_msi_route(&kroute, msg.address, msg.data)) {
+ return -EINVAL;
+ }
return kvm_update_routing_entry(s, &kroute);
}
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index 4d81f3d765..23cefe98b4 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -548,3 +548,9 @@ int kvm_arch_irqchip_create(KVMState *s)
return 0;
}
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+ return 0;
+}
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index f92edfe14a..54ccb890b5 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -2733,3 +2733,9 @@ int kvm_device_msix_deassign(KVMState *s, uint32_t dev_id)
return kvm_deassign_irq_internal(s, dev_id, KVM_DEV_IRQ_GUEST_MSIX |
KVM_DEV_IRQ_HOST_MSIX);
}
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+ return 0;
+}
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index a761ea5b32..b68191c88e 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -688,3 +688,9 @@ int kvm_arch_get_registers(CPUState *cs)
return ret;
}
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+ return 0;
+}
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index 911f91212a..1edf2b5aeb 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -2402,3 +2402,9 @@ out_close:
error_out:
return;
}
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+ return 0;
+}
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 09c2483618..dcd75055c1 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -41,6 +41,7 @@
#include "trace.h"
#include "qapi-event.h"
#include "hw/s390x/s390-pci-inst.h"
+#include "hw/s390x/s390-pci-bus.h"
/* #define DEBUG_KVM */
@@ -1544,3 +1545,28 @@ int kvm_s390_set_cpu_state(S390CPU *cpu, uint8_t cpu_state)
return ret;
}
+
+int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
+ uint64_t address, uint32_t data)
+{
+ S390PCIBusDevice *pbdev;
+ uint32_t fid = data >> ZPCI_MSI_VEC_BITS;
+ uint32_t vec = data & ZPCI_MSI_VEC_MASK;
+
+ pbdev = s390_pci_find_dev_by_fid(fid);
+ if (!pbdev) {
+ DPRINTF("add_msi_route no dev\n");
+ return -ENODEV;
+ }
+
+ pbdev->routes.adapter.ind_offset = vec;
+
+ route->type = KVM_IRQ_ROUTING_S390_ADAPTER;
+ route->flags = 0;
+ route->u.adapter.summary_addr = pbdev->routes.adapter.summary_addr;
+ route->u.adapter.ind_addr = pbdev->routes.adapter.ind_addr;
+ route->u.adapter.summary_offset = pbdev->routes.adapter.summary_offset;
+ route->u.adapter.ind_offset = pbdev->routes.adapter.ind_offset;
+ route->u.adapter.adapter_id = pbdev->routes.adapter.adapter_id;
+ return 0;
+}