On 2026/07/09 7:13, Philippe Mathieu-Daudé wrote:
On 3/11/25 11:10, Philippe Mathieu-Daudé wrote:
From: Richard Henderson <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
Tested-by: Philippe Mathieu-Daudé <[email protected]>
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
---
include/system/hvf_int.h | 3 +++
accel/hvf/hvf-all.c | 25 +++++++++++++++++++++++++
accel/hvf/trace-events | 1 +
3 files changed, 29 insertions(+)
diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index 3d2be4092ef..5a57691885f 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -89,6 +89,9 @@ int hvf_arch_get_registers(CPUState *);
/* Must be called by the owning thread */
void hvf_arch_update_guest_debug(CPUState *cpu);
+void hvf_protect_clean_range(hwaddr addr, size_t size);
+void hvf_unprotect_dirty_range(hwaddr addr, size_t size);
+
struct hvf_sw_breakpoint {
vaddr pc;
vaddr saved_insn;
diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index 0a4b498e836..e13abddbd9c 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -58,6 +58,31 @@ void assert_hvf_ok_impl(hv_return_t ret, const char
*file, unsigned int line,
abort();
}
+static void do_hv_vm_protect(hwaddr start, size_t size,
+ hv_memory_flags_t flags)
+{
+ hv_return_t ret;
+
+ trace_hvf_vm_protect(start, size, flags,
+ flags & HV_MEMORY_READ ? 'R' : '-',
+ flags & HV_MEMORY_WRITE ? 'W' : '-',
+ flags & HV_MEMORY_EXEC ? 'X' : '-');
+
+ ret = hv_vm_protect(start, size, flags);
+ assert_hvf_ok(ret);
Maybe this assertion is a bit aggressive toward users, since while
we know the host limits, we don't know what the guest wants to do.
I got:
qemu-system-aarch64: Error: ret = HV_ERROR (0xfae94001, at ../../accel/
hvf/hvf-all.c:77)
Running with '-trace hvf_vm_map':
hvf_vm_map paddr:0x0000000010000000 size:0x00020000 vaddr:0x104514000
flags:0x07/RWX
hvf_vm_map paddr:0x0000000000000000 size:0x00020000 vaddr:0x104890000
flags:0x07/RWX
hvf_vm_map paddr:0x0000000400000000 size:0x80000000 vaddr:0x380000000
flags:0x07/RWX
hvf_vm_map paddr:0x0000000030bc0000 size:0x00040000 vaddr:0x1048b4000
flags:0x07/RWX
hvf_vm_map paddr:0x0000000050bc0000 size:0x00040000 vaddr:0x1048f8000
flags:0x07/RWX
hvf_vm_protect paddr:0x0000000430000000 size:0x00004000 flags:0x05/R-X
hvf_vm_protect paddr:0x0000000030000000 size:0x00004000 flags:0x05/R-X
qemu-system-aarch64: Error: ret = HV_ERROR (0xfae94001, at ../../accel/
hvf/hvf-all.c:77)
Should we propagate the error to upper layer?
Are there cases we can safely ignore?
I don't think this should be propagated to the guest. In this case the
failing hv_vm_protect() is for a GPA that was not mapped into HVF in the
first place.
The memory listener currently calls hvf_log_start() for every dirty-log
section, but hvf_set_phys_mem() intentionally skips some sections, for
example writable non-RAM regions where we want every access to trap. KVM
handles the equivalent case by looking up the matching slot and
returning if there is none.
So I think we should only ignore/skip protect for ranges that we know do
not have an HVF mapping. We should not ignore arbitrary hv_vm_protect()
failures for mapped RAM, because then dirty logging can miss writes or
keep faulting forever.
A fix probably needs factoring the same mappable section test used by
hvf_set_phys_mem() and using it in log_start, log_stop and log_clear.
Regards,
Akihiko Odaki