From patchwork Tue Oct 30 11:47:47 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [v2,4/7] memory: provide a MemoryRegion for IOMMUs to log faults Date: Tue, 30 Oct 2012 01:47:47 -0000 From: Avi Kivity X-Patchwork-Id: 195466 Message-Id: <1351597670-23031-5-git-send-email-avi@redhat.com> To: qemu-devel@nongnu.org Cc: "Michael S. Tsirkin" , Alexander Graf , Blue Swirl , Alex Williamson , Anthony Liguori Accesses which do not translate will hit the fault region, which can then log the access. Signed-off-by: Avi Kivity --- memory.c | 9 ++++++--- memory.h | 4 ++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/memory.c b/memory.c index ba2d4a0..d6b46fd 100644 --- a/memory.c +++ b/memory.c @@ -778,7 +778,9 @@ static void memory_region_destructor_rom_device(MemoryRegion *mr) static void memory_region_destructor_iommu(MemoryRegion *mr) { address_space_destroy(mr->iommu_target_as); + address_space_destroy(mr->iommu_fault_as); g_free(mr->iommu_target_as); + g_free(mr->iommu_fault_as); } static bool memory_region_wrong_endianness(MemoryRegion *mr) @@ -1001,9 +1003,7 @@ static void memory_region_iommu_rw(MemoryRegion *iommu, hwaddr addr, xlat = (tlb.translated_addr & ~tlb.addr_mask) | (addr & tlb.addr_mask); address_space_rw(iommu->iommu_target_as, xlat, buf, clen, is_write); } else { - if (!is_write) { - memset(buf, 0xff, clen); - } + address_space_rw(iommu->iommu_fault_as, addr, buf, clen, is_write); } buf += clen; addr += clen; @@ -1068,6 +1068,7 @@ static void memory_region_iommu_write(void *opaque, hwaddr addr, void memory_region_init_iommu(MemoryRegion *mr, MemoryRegionIOMMUOps *ops, MemoryRegion *target, + MemoryRegion *fault, const char *name, uint64_t size) { @@ -1079,6 +1080,8 @@ void memory_region_init_iommu(MemoryRegion *mr, mr->destructor = memory_region_destructor_iommu; mr->iommu_target_as = g_new(AddressSpace, 1); address_space_init(mr->iommu_target_as, target); + mr->iommu_fault_as = g_new(AddressSpace, 1); + address_space_init(mr->iommu_fault_as, fault); } static uint64_t invalid_read(void *opaque, hwaddr addr, diff --git a/memory.h b/memory.h index 47362c9..6312197 100644 --- a/memory.h +++ b/memory.h @@ -162,6 +162,7 @@ struct MemoryRegion { unsigned ioeventfd_nb; MemoryRegionIoeventfd *ioeventfds; struct AddressSpace *iommu_target_as; + struct AddressSpace *iommu_fault_as; }; struct MemoryRegionPortio { @@ -361,12 +362,15 @@ void memory_region_init_reservation(MemoryRegion *mr, * @ops: a function that translates addresses into the @target region * @target: a #MemoryRegion that will be used to satisfy accesses to translated * addresses + * @fault: a #MemoryRegion for servicing failed translations; accessed with + * untranslated addresses * @name: used for debugging; not visible to the user or ABI * @size: size of the region. */ void memory_region_init_iommu(MemoryRegion *mr, MemoryRegionIOMMUOps *ops, MemoryRegion *target, + MemoryRegion *fault, const char *name, uint64_t size);