Commit 51644ab7 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

memory: add address_space_access_valid



The old-style IOMMU lets you check whether an access is valid in a
given DMAContext.  There is no equivalent for AddressSpace in the
memory API, implement it with a lookup of the dispatch tree.

Reviewed-by: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent c353e4cc
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -298,6 +298,11 @@ bool iommu_dma_memory_valid(DMAContext *dma, dma_addr_t addr, dma_addr_t len,
            plen = len;
        }

        if (!address_space_access_valid(dma->as, paddr, len,
                                        dir == DMA_DIRECTION_FROM_DEVICE)) {
            return false;
        }

        len -= plen;
        addr += plen;
    }
+21 −0
Original line number Diff line number Diff line
@@ -2067,6 +2067,27 @@ static void cpu_notify_map_clients(void)
    }
}

bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write)
{
    MemoryRegionSection *section;
    hwaddr l, xlat;

    while (len > 0) {
        l = len;
        section = address_space_translate(as, addr, &xlat, &l, is_write);
        if (!memory_access_is_direct(section->mr, is_write)) {
            l = memory_access_size(l, addr);
            if (!memory_region_access_valid(section->mr, xlat, l, is_write)) {
                return false;
            }
        }

        len -= l;
        addr += l;
    }
    return true;
}

/* Map a physical memory region into a host virtual address.
 * May map a subset of the requested range, given by and returned in *plen.
 * May return NULL if resources needed to perform the mapping are exhausted.
+15 −0
Original line number Diff line number Diff line
@@ -866,6 +866,21 @@ MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr,
                                             hwaddr *xlat, hwaddr *len,
                                             bool is_write);

/* address_space_access_valid: check for validity of accessing an address
 * space range
 *
 * Check whether memory is assigned to the given address space range.
 *
 * For now, addr and len should be aligned to a page size.  This limitation
 * will be lifted in the future.
 *
 * @as: #AddressSpace to be accessed
 * @addr: address within that address space
 * @len: length of the area to be checked
 * @is_write: indicates the transfer direction
 */
bool address_space_access_valid(AddressSpace *as, hwaddr addr, int len, bool is_write);

/* address_space_map: map a physical memory region into a host virtual address
 *
 * May map a subset of the requested range, given by and returned in @plen.
+2 −1
Original line number Diff line number Diff line
@@ -113,7 +113,8 @@ static inline bool dma_memory_valid(DMAContext *dma,
                                    DMADirection dir)
{
    if (!dma_has_iommu(dma)) {
        return true;
        return address_space_access_valid(dma->as, addr, len,
                                          dir == DMA_DIRECTION_FROM_DEVICE);
    } else {
        return iommu_dma_memory_valid(dma, addr, len, dir);
    }