From: David Hildenbrand <david@redhat.com>
To: "Philippe Mathieu-Daudé" <philmd@linaro.org>, qemu-devel@nongnu.org
Cc: "Paolo Bonzini" <pbonzini@redhat.com>,
"Peter Xu" <peterx@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Alex Bennée" <alex.bennee@linaro.org>,
"Alex Williamson" <alex.williamson@redhat.com>,
"Eduardo Habkost" <eduardo@habkost.net>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Elena Ufimtseva" <elena.ufimtseva@oracle.com>,
"Jagannathan Raman" <jag.raman@oracle.com>,
"Dr. David Alan Gilbert" <dave@treblig.org>,
"Stefan Zabka" <git@zabka.it>
Subject: Re: [PATCH v1 1/4] physmem: disallow direct access to RAM DEVICE in address_space_write_rom()
Date: Wed, 22 Jan 2025 12:02:05 +0100 [thread overview]
Message-ID: <54f53a7d-5ea5-436c-ab2c-e8f8b792bb45@redhat.com> (raw)
In-Reply-To: <ec89b3da-49e3-4b57-892b-8a15a786c6c2@redhat.com>
On 22.01.25 11:18, David Hildenbrand wrote:
> On 22.01.25 11:17, Philippe Mathieu-Daudé wrote:
>> On 22/1/25 11:13, David Hildenbrand wrote:
>>> On 22.01.25 11:10, David Hildenbrand wrote:
>>>> On 22.01.25 11:07, Philippe Mathieu-Daudé wrote:
>>>>> Hi David,
>>>>>
>>>>> On 20/1/25 12:14, David Hildenbrand wrote:
>>>>>> As documented in commit 4a2e242bbb306 ("memory: Don't use memcpy for
>>>>>> ram_device regions"), we disallow direct access to RAM DEVICE regions.
>>>>>>
>>>>>> Let's factor out the "supports direct access" check from
>>>>>> memory_access_is_direct() so we can reuse it, and make it a bit
>>>>>> easier to
>>>>>> read.
>>>>>>
>>>>>> This change implies that address_space_write_rom() and
>>>>>> cpu_memory_rw_debug() won't be able to write to RAM DEVICE regions. It
>>>>>> will also affect cpu_flush_icache_range(), but it's only used by
>>>>>> hw/core/loader.c after writing to ROM, so it is expected to not apply
>>>>>> here with RAM DEVICE.
>>>>>>
>>>>>> This fixes direct access to these regions where we don't want direct
>>>>>> access. We'll extend cpu_memory_rw_debug() next to also be able to
>>>>>> write to
>>>>>> these (and IO) regions.
>>>>>>
>>>>>> This is a preparation for further changes.
>>>>>>
>>>>>> Cc: Alex Williamson <alex.williamson@redhat.com>
>>>>>> Signed-off-by: David Hildenbrand <david@redhat.com>
>>>>>> ---
>>>>>> include/exec/memory.h | 30 ++++++++++++++++++++++++------
>>>>>> system/physmem.c | 3 +--
>>>>>> 2 files changed, 25 insertions(+), 8 deletions(-)
>>>>>>
>>>>>> diff --git a/include/exec/memory.h b/include/exec/memory.h
>>>>>> index 3ee1901b52..bd0ddb9cdf 100644
>>>>>> --- a/include/exec/memory.h
>>>>>> +++ b/include/exec/memory.h
>>>>>> @@ -2985,15 +2985,33 @@ MemTxResult
>>>>>> address_space_write_cached_slow(MemoryRegionCache *cache,
>>>>>> int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr);
>>>>>> bool prepare_mmio_access(MemoryRegion *mr);
>>>>>> +static inline bool
>>>>>> memory_region_supports_direct_access(MemoryRegion *mr)
>>>>>> +{
>>>>>> + /* ROM DEVICE regions only allow direct access if in ROMD mode. */
>>>>>> + if (memory_region_is_romd(mr)) {
>>>>>> + return true;
>>>>>> + }
>>>>>> + if (!memory_region_is_ram(mr)) {
>>>>>> + return false;
>>>>>> + }
>>>>>> + /*
>>>>>> + * RAM DEVICE regions can be accessed directly using memcpy,
>>>>>> but it might
>>>>>> + * be MMIO and access using mempy can be wrong (e.g., using
>>>>>> instructions not
>>>>>> + * intended for MMIO access). So we treat this as IO.
>>>>>> + */
>>>>>> + return !memory_region_is_ram_device(mr);
>>>>>> +
>>>>>> +}
>>>>>> +
>>>>>> static inline bool memory_access_is_direct(MemoryRegion *mr,
>>>>>> bool is_write)
>>>>>> {
>>>>>> - if (is_write) {
>>>>>> - return memory_region_is_ram(mr) && !mr->readonly &&
>>>>>> - !mr->rom_device && !memory_region_is_ram_device(mr);
>>>>>> - } else {
>>>>>> - return (memory_region_is_ram(mr) && !
>>>>>> memory_region_is_ram_device(mr)) ||
>>>>>
>>>>> This patch is doing multiple things at once, and I'm having hard time
>>>>> reviewing it.
>>>>
>>>> I appreciate the review, but ... really?! :)
>>>>
>>>> 25 insertions(+), 8 deletions(-)
>>>
>>> FWIW, I'll try to split it up ... I thought the comments added to
>>> memory_region_supports_direct_access() and friends are pretty clear.
>>
>> No worry, I'll give it another try. (split still welcomed, but not
>> blocking).
>
> I think unmangling the existing unreadable conditions in
> memory_access_is_direct() can be done separately; let me see what I can do.
The following should hopefully be easier to follow:
From 89519beec0de96d9c9c243a844ccb698db759893 Mon Sep 17 00:00:00 2001
From: David Hildenbrand <david@redhat.com>
Date: Wed, 22 Jan 2025 11:23:00 +0100
Subject: [PATCH 1/4] physmem: factor out memory_region_is_ram_device() check
in memory_access_is_direct()
As documented in commit 4a2e242bbb306 ("memory: Don't use memcpy for
ram_device regions"), we disallow direct access to RAM DEVICE regions.
Let's make this clearer to prepare for further changes. Note that ROMD
regions will never be RAM DEVICE at the same time.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
include/exec/memory.h | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 3ee1901b52..7931aba2ea 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -2987,12 +2987,19 @@ bool prepare_mmio_access(MemoryRegion *mr);
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
+ /*
+ * RAM DEVICE regions can be accessed directly using memcpy, but it might
+ * be MMIO and access using mempy can be wrong (e.g., using instructions not
+ * intended for MMIO access). So we treat this as IO.
+ */
+ if (memory_region_is_ram_device(mr)) {
+ return false;
+ }
if (is_write) {
return memory_region_is_ram(mr) && !mr->readonly &&
- !mr->rom_device && !memory_region_is_ram_device(mr);
+ !mr->rom_device;
} else {
- return (memory_region_is_ram(mr) && !memory_region_is_ram_device(mr)) ||
- memory_region_is_romd(mr);
+ return memory_region_is_ram(mr) || memory_region_is_romd(mr);
}
}
--
2.47.1
From ba793917cf3e35bc3b39898524ea96a85cef768d Mon Sep 17 00:00:00 2001
From: David Hildenbrand <david@redhat.com>
Date: Wed, 22 Jan 2025 11:28:19 +0100
Subject: [PATCH 2/4] physmem: factor out RAM/ROMD check in
memory_access_is_direct()
Let's factor more of the generic "is this directly accessible" check,
independent of the "write" condition out.
Note that the "!mr->rom_device" check in the write case essentially
disallows the memory_region_is_romd() condition again. Further note that
RAM DEVICE regions are also RAM regions, so we can check for RAM+ROMD
first.
This is a preparation for further changes.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
include/exec/memory.h | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 7931aba2ea..086dec5086 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -2987,6 +2987,10 @@ bool prepare_mmio_access(MemoryRegion *mr);
static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
{
+ /* ROM DEVICE regions only allow direct access if in ROMD mode. */
+ if (!memory_region_is_ram(mr) && !memory_region_is_romd(mr)) {
+ return false;
+ }
/*
* RAM DEVICE regions can be accessed directly using memcpy, but it might
* be MMIO and access using mempy can be wrong (e.g., using instructions not
@@ -2996,11 +3000,9 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
return false;
}
if (is_write) {
- return memory_region_is_ram(mr) && !mr->readonly &&
- !mr->rom_device;
- } else {
- return memory_region_is_ram(mr) || memory_region_is_romd(mr);
+ return !mr->readonly && !mr->rom_device;
}
+ return true;
}
/**
--
2.47.1
From 2ccd2af17bb9e1fd4922e1bd2dcc202de4bf8942 Mon Sep 17 00:00:00 2001
From: David Hildenbrand <david@redhat.com>
Date: Wed, 22 Jan 2025 11:34:00 +0100
Subject: [PATCH 3/4] physmem: factor out direct access check into
memory_region_supports_direct_access()
Let's factor the complete "directly accessible" check independent of
the "write" condition out so we can reuse it next.
We can now split up the checks RAM and ROMD check, so we really only check
for RAM DEVICE in case of RAM -- ROM DEVICE is neither RAM not RAM DEVICE.
Signed-off-by: David Hildenbrand <david@redhat.com>
---
include/exec/memory.h | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 086dec5086..3b4449e847 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -2985,10 +2985,13 @@ MemTxResult address_space_write_cached_slow(MemoryRegionCache *cache,
int memory_access_size(MemoryRegion *mr, unsigned l, hwaddr addr);
bool prepare_mmio_access(MemoryRegion *mr);
-static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+static inline bool memory_region_supports_direct_access(MemoryRegion *mr)
{
/* ROM DEVICE regions only allow direct access if in ROMD mode. */
- if (!memory_region_is_ram(mr) && !memory_region_is_romd(mr)) {
+ if (memory_region_is_romd(mr)) {
+ return true;
+ }
+ if (!memory_region_is_ram(mr)) {
return false;
}
/*
@@ -2996,7 +2999,12 @@ static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
* be MMIO and access using mempy can be wrong (e.g., using instructions not
* intended for MMIO access). So we treat this as IO.
*/
- if (memory_region_is_ram_device(mr)) {
+ return !memory_region_is_ram_device(mr);
+}
+
+static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
+{
+ if (!memory_region_supports_direct_access(mr)) {
return false;
}
if (is_write) {
--
2.47.1
From b9deb2c212f8edbe526152529072b89d73e2258f Mon Sep 17 00:00:00 2001
From: David Hildenbrand <david@redhat.com>
Date: Wed, 22 Jan 2025 11:35:29 +0100
Subject: [PATCH 4/4] physmem: disallow direct access to RAM DEVICE in
address_space_write_rom()
As documented in commit 4a2e242bbb306 ("memory: Don't use memcpy for
ram_device regions"), we disallow direct access to RAM DEVICE regions.
This change implies that address_space_write_rom() and
cpu_memory_rw_debug() won't be able to write to RAM DEVICE regions. It
will also affect cpu_flush_icache_range(), but it's only used by
hw/core/loader.c after writing to ROM, so it is expected to not apply
here with RAM DEVICE.
This fixes direct access to these regions where we don't want direct
access. We'll extend cpu_memory_rw_debug() next to also be able to write to
these (and IO) regions.
This is a preparation for further changes.
Cc: Alex Williamson <alex.williamson@redhat.com>
Signed-off-by: David Hildenbrand <david@redhat.com>
---
system/physmem.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/system/physmem.c b/system/physmem.c
index c76503aea8..2d4f8110e8 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -3029,8 +3029,7 @@ static inline MemTxResult address_space_write_rom_internal(AddressSpace *as,
l = len;
mr = address_space_translate(as, addr, &addr1, &l, true, attrs);
- if (!(memory_region_is_ram(mr) ||
- memory_region_is_romd(mr))) {
+ if (!memory_region_supports_direct_access(mr)) {
l = memory_access_size(mr, l, addr1);
} else {
/* ROM/RAM case */
--
2.47.1
--
Cheers,
David / dhildenb
next prev parent reply other threads:[~2025-01-22 11:03 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20250120111503.244994-1-david@redhat.com>
[not found] ` <20250120111503.244994-2-david@redhat.com>
2025-01-22 10:07 ` [PATCH v1 1/4] physmem: disallow direct access to RAM DEVICE in address_space_write_rom() Philippe Mathieu-Daudé
2025-01-22 10:10 ` David Hildenbrand
2025-01-22 10:13 ` David Hildenbrand
2025-01-22 10:17 ` Philippe Mathieu-Daudé
2025-01-22 10:18 ` David Hildenbrand
2025-01-22 11:02 ` David Hildenbrand [this message]
[not found] ` <20250120111503.244994-4-david@redhat.com>
2025-01-22 10:08 ` [PATCH v1 3/4] hmp: use cpu_get_phys_page_debug() in hmp_gva2gpa() Philippe Mathieu-Daudé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54f53a7d-5ea5-436c-ab2c-e8f8b792bb45@redhat.com \
--to=david@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=alex.williamson@redhat.com \
--cc=dave@treblig.org \
--cc=eduardo@habkost.net \
--cc=elena.ufimtseva@oracle.com \
--cc=git@zabka.it \
--cc=jag.raman@oracle.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).