Commit b05c81d2 authored by Eric Auger's avatar Eric Auger Committed by Peter Maydell
Browse files

target/arm/kvm: Translate the MSI doorbell in kvm_arch_fixup_msi_route



In case the MSI is translated by an IOMMU we need to fixup the
MSI route with the translated address.

Signed-off-by: default avatarEric Auger <eric.auger@redhat.com>
Signed-off-by: default avatarBharat Bhushan <Bharat.Bhushan@nxp.com>
Message-id: 1524665762-31355-12-git-send-email-eric.auger@redhat.com
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parent 0d1ac82e
Loading
Loading
Loading
Loading
+37 −1
Original line number Diff line number Diff line
@@ -20,8 +20,10 @@
#include "sysemu/kvm.h"
#include "kvm_arm.h"
#include "cpu.h"
#include "trace.h"
#include "internals.h"
#include "hw/arm/arm.h"
#include "hw/pci/pci.h"
#include "exec/memattrs.h"
#include "exec/address-spaces.h"
#include "hw/boards.h"
@@ -649,9 +651,43 @@ int kvm_arm_vgic_probe(void)
int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
                             uint64_t address, uint32_t data, PCIDevice *dev)
{
    AddressSpace *as = pci_device_iommu_address_space(dev);
    hwaddr xlat, len, doorbell_gpa;
    MemoryRegionSection mrs;
    MemoryRegion *mr;
    int ret = 1;

    if (as == &address_space_memory) {
        return 0;
    }

    /* MSI doorbell address is translated by an IOMMU */

    rcu_read_lock();
    mr = address_space_translate(as, address, &xlat, &len, true);
    if (!mr) {
        goto unlock;
    }
    mrs = memory_region_find(mr, xlat, 1);
    if (!mrs.mr) {
        goto unlock;
    }

    doorbell_gpa = mrs.offset_within_address_space;
    memory_region_unref(mrs.mr);

    route->u.msi.address_lo = doorbell_gpa;
    route->u.msi.address_hi = doorbell_gpa >> 32;

    trace_kvm_arm_fixup_msi_route(address, doorbell_gpa);

    ret = 0;

unlock:
    rcu_read_unlock();
    return ret;
}

int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
                                int vector, PCIDevice *dev)
{
+3 −0
Original line number Diff line number Diff line
@@ -8,3 +8,6 @@ arm_gt_tval_write(int timer, uint64_t value) "gt_tval_write: timer %d value 0x%"
arm_gt_ctl_write(int timer, uint64_t value) "gt_ctl_write: timer %d value 0x%" PRIx64
arm_gt_imask_toggle(int timer, int irqstate) "gt_ctl_write: timer %d IMASK toggle, new irqstate %d"
arm_gt_cntvoff_write(uint64_t value) "gt_cntvoff_write: value 0x%" PRIx64

# target/arm/kvm.c
kvm_arm_fixup_msi_route(uint64_t iova, uint64_t gpa) "MSI iova = 0x%"PRIx64" is translated into 0x%"PRIx64