From ea7a5330b79523540ba776c529b09dc8cf3fa0c5 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 29 Jan 2019 11:46:04 +0000 Subject: exec.c: Use correct attrs in cpu_memory_rw_debug() In the softmmu version of cpu_memory_rw_debug(), we ask the CPU for the attributes to use for the virtual memory access, and we correctly use those to identify the address space index. However, we were not passing them in to the address_space_write_rom() and address_space_rw() functions. The effect of this was that a memory access from the gdbstub to a device which had behaviour that was sensitive to the memory attributes (such as some ARMv8M NVIC registers) was incorrectly always performed as if non-secure, rather than using the right security state for the CPU's current state. Fixes: https://bugs.launchpad.net/qemu/+bug/1812091 Signed-off-by: Peter Maydell Reviewed-by: Stefano Garzarella Reviewed-by: Philippe Mathieu-Daudé Message-id: 20190117133834.7480-1-peter.maydell@linaro.org --- exec.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'exec.c') diff --git a/exec.c b/exec.c index 895449f926..9557a4e523 100644 --- a/exec.c +++ b/exec.c @@ -3882,12 +3882,10 @@ int cpu_memory_rw_debug(CPUState *cpu, target_ulong addr, phys_addr += (addr & ~TARGET_PAGE_MASK); if (is_write) { address_space_write_rom(cpu->cpu_ases[asidx].as, phys_addr, - MEMTXATTRS_UNSPECIFIED, - buf, l); + attrs, buf, l); } else { address_space_rw(cpu->cpu_ases[asidx].as, phys_addr, - MEMTXATTRS_UNSPECIFIED, - buf, l, 0); + attrs, buf, l, 0); } len -= l; buf += l; -- cgit v1.2.3-55-g7522 From 047be4ed24b3a408acccf9316d619477c06cca42 Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 29 Jan 2019 11:46:04 +0000 Subject: memory: add memory_region_flush_rom_device() ROM devices go via MemoryRegionOps->write() callbacks for write operations and do not dirty/invalidate that memory. Device emulation must be able to mark memory ranges that have been modified internally (e.g. using memory_region_get_ram_ptr()). Introduce the memory_region_flush_rom_device() API for this purpose. Signed-off-by: Stefan Hajnoczi Message-id: 20190123212234.32068-2-stefanha@redhat.com Reviewed-by: Peter Maydell [PMM: fix block comment style] Signed-off-by: Peter Maydell --- exec.c | 13 +++++++++++++ include/exec/memory.h | 18 ++++++++++++++++++ 2 files changed, 31 insertions(+) (limited to 'exec.c') diff --git a/exec.c b/exec.c index 9557a4e523..da3e635f91 100644 --- a/exec.c +++ b/exec.c @@ -3162,6 +3162,19 @@ static void invalidate_and_set_dirty(MemoryRegion *mr, hwaddr addr, cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask); } +void memory_region_flush_rom_device(MemoryRegion *mr, hwaddr addr, hwaddr size) +{ + /* + * In principle this function would work on other memory region types too, + * but the ROM device use case is the only one where this operation is + * necessary. Other memory regions should use the + * address_space_read/write() APIs. + */ + assert(memory_region_is_romd(mr)); + + invalidate_and_set_dirty(mr, addr, size); +} + static int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr) { unsigned access_size_max = mr->ops->valid.max_access_size; diff --git a/include/exec/memory.h b/include/exec/memory.h index cd2f209b64..abe9cc79c0 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1344,6 +1344,24 @@ bool memory_region_snapshot_get_dirty(MemoryRegion *mr, void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size, unsigned client); +/** + * memory_region_flush_rom_device: Mark a range of pages dirty and invalidate + * TBs (for self-modifying code). + * + * The MemoryRegionOps->write() callback of a ROM device must use this function + * to mark byte ranges that have been modified internally, such as by directly + * accessing the memory returned by memory_region_get_ram_ptr(). + * + * This function marks the range dirty and invalidates TBs so that TCG can + * detect self-modifying code. + * + * @mr: the region being flushed. + * @addr: the start, relative to the start of the region, of the range being + * flushed. + * @size: the size, in bytes, of the range being flushed. + */ +void memory_region_flush_rom_device(MemoryRegion *mr, hwaddr addr, hwaddr size); + /** * memory_region_set_readonly: Turn a memory region read-only (or read-write) * -- cgit v1.2.3-55-g7522