From nobody Fri Nov 7 14:38:35 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 15479950585251.65053825539826; Sun, 20 Jan 2019 06:37:38 -0800 (PST) Received: from localhost ([127.0.0.1]:40612 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1glEED-0003tg-FC for importer@patchew.org; Sun, 20 Jan 2019 09:37:37 -0500 Received: from eggs.gnu.org ([209.51.188.92]:58729) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1glECI-0002pf-70 for qemu-devel@nongnu.org; Sun, 20 Jan 2019 09:35:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1glECG-0002To-9u for qemu-devel@nongnu.org; Sun, 20 Jan 2019 09:35:38 -0500 Received: from mx1.redhat.com ([209.132.183.28]:45178) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1glECC-0002Pf-2V for qemu-devel@nongnu.org; Sun, 20 Jan 2019 09:35:33 -0500 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 805473DE03; Sun, 20 Jan 2019 14:35:28 +0000 (UTC) Received: from localhost (ovpn-116-40.ams2.redhat.com [10.36.116.40]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1CF5719C7D; Sun, 20 Jan 2019 14:35:27 +0000 (UTC) From: Stefan Hajnoczi To: qemu-devel@nongnu.org Date: Sun, 20 Jan 2019 14:34:49 +0000 Message-Id: <20190120143452.21683-2-stefanha@redhat.com> In-Reply-To: <20190120143452.21683-1-stefanha@redhat.com> References: <20190120143452.21683-1-stefanha@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Sun, 20 Jan 2019 14:35:28 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/4] memory: add memory_region_flush_rom_device() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , jim@groklearning.com, =?UTF-8?q?Steffen=20G=C3=B6rtz?= , qemu-arm@nongnu.org, Joel Stanley , Paolo Bonzini , jusual@mail.ru Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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 --- include/exec/memory.h | 18 ++++++++++++++++++ exec.c | 12 ++++++++++++ 2 files changed, 30 insertions(+) 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); =20 +/** + * memory_region_flush_rom_device: Mark a range of pages dirty and invalid= ate + * TBs (for self-modifying code). + * + * The MemoryRegionOps->write() callback of a ROM device must use this fun= ction + * to mark byte ranges that have been modified internally, such as by dire= ctly + * 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 bei= ng + * 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-wri= te) * diff --git a/exec.c b/exec.c index 895449f926..105ff21e74 100644 --- a/exec.c +++ b/exec.c @@ -3162,6 +3162,18 @@ static void invalidate_and_set_dirty(MemoryRegion *m= r, hwaddr addr, cpu_physical_memory_set_dirty_range(addr, length, dirty_log_mask); } =20 +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 =3D mr->ops->valid.max_access_size; --=20 2.20.1