Add the following helpers: * section_access_allowed() - used to check memory access permissions.
* section_covers_region_addr() - used to implement GuestMemoryRegion::check_address(). * section_fuzz_dma_read() - used to insert a fuzzing hook before read/load operations. Signed-off-by: Zhao Liu <[email protected]> --- Changes since v1: * Drop section_get_host_addr() for two reasons: - GuestMemoryRegion::get_host_address() doesn't accept Permissions and MemTxAttrs arguments, which doesn't map well to QEMU's complex use cases. - section_get_host_addr() itself doesn't differentiate between MMIO and RAM. Although this could be fixed, the first reason makes it unnecessary. --- include/system/memory.h | 39 +++++++++++++++++++++++++++++++++++++++ system/physmem.c | 20 ++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/system/memory.h b/include/system/memory.h index 7e64a39662be..18f269ac4dab 100644 --- a/include/system/memory.h +++ b/include/system/memory.h @@ -2878,6 +2878,45 @@ MemTxResult address_space_read(const AddressSpace *as, hwaddr addr, MemTxResult address_space_set(const AddressSpace *as, hwaddr addr, uint8_t c, hwaddr len, MemTxAttrs attrs); +/** + * section_access_allowed: Check if a memory transaction is allowed. + * + * @section: The #MemoryRegionSection to be accessed. + * @attrs: Memory transaction attributes. + * @addr: The address within that memory region. + * @len: The number of bytes to access. + * + * Returns: true if the transaction is allowed, false if denied. + */ +bool section_access_allowed(MemoryRegionSection *section, + MemTxAttrs attrs, hwaddr addr, + hwaddr len); + +/** + * section_covers_region_addr: Check if a region address is covered by + * a #MemoryRegionSection. + * + * @section: The #MemoryRegionSection to check against. + * @region_addr: The address within the memory region referenced by the + * @section. + * + * Returns: true if the address is covered by the section, false otherwise. + */ +bool section_covers_region_addr(const MemoryRegionSection *section, + hwaddr region_addr); + +/** + * section_fuzz_dma_read: Wrapper for fuzz_dma_read_cb(). + * + * @section: The #MemoryRegionSection to be accessed. + * @addr: The memory address to be fuzzed. + * @len: The length of the memory to fuzz. + * + * This function is a wrapper for fuzz_dma_read_cb(). + */ +void section_fuzz_dma_read(MemoryRegionSection *section, + hwaddr addr, hwaddr len); + /* Coalesced MMIO regions are areas where write operations can be reordered. * This usually implies that write operations are side-effect free. This allows * batching which can make a major impact on performance when using diff --git a/system/physmem.c b/system/physmem.c index 1162819c1080..c227d4680e33 100644 --- a/system/physmem.c +++ b/system/physmem.c @@ -321,6 +321,19 @@ static inline bool section_covers_addr(const MemoryRegionSection *section, int128_getlo(section->size), addr); } +bool section_covers_region_addr(const MemoryRegionSection *section, + hwaddr region_addr) +{ + return section->offset_within_region <= region_addr && + section->offset_within_region + int128_get64(section->size) >= region_addr; +} + +void section_fuzz_dma_read(MemoryRegionSection *section, + hwaddr addr, hwaddr len) +{ + fuzz_dma_read_cb(addr, len, section->mr); +} + static MemoryRegionSection *phys_page_find(AddressSpaceDispatch *d, hwaddr addr) { PhysPageEntry lp = d->phys_map, *p; @@ -3236,6 +3249,13 @@ static bool memory_region_access_allowed(MemoryRegion *mr, MemTxAttrs attrs, return false; } +bool section_access_allowed(MemoryRegionSection *section, + MemTxAttrs attrs, hwaddr addr, + hwaddr len) +{ + return memory_region_access_allowed(section->mr, attrs, addr, len); +} + static MemTxResult flatview_write_continue_step(MemTxAttrs attrs, const uint8_t *buf, hwaddr len, hwaddr mr_addr, -- 2.34.1
