qemu-arm.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/23] target/arm/hvf: Consolidate
@ 2025-11-03 10:10 Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 01/23] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range Philippe Mathieu-Daudé
                   ` (22 more replies)
  0 siblings, 23 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Missing review: 8, 13, 22, 23

- Patches 1-11 fix migration on HVF
- Patches 12-14 remove a signal race with WFI
- Patches 15-18 correct guest timer frequency
- Patches 20-23 add missing VTimer synchronization

Since v3:
- Call qemu_real_host_page_mask/size once (rth)

Since v2:
- Improve host page size/mask uses (rth)
- Remove cpu_test_interrupt in hvf_wfi (rth)

Since v1:
- Addressed Mads & Richard comments
- Fixed migration by reworking memory listeners
  (unfortunately the current broken code has been
   used as base for WHPX)
- Sync CNTV_CTL/CVAL_EL0
- Remove WFI racy signal implementation
- Simplify PSCI Suspend (I expect the same can be
  done for the other hvf_psci_cpu_off() calls).
- Emulate more missing registers (PMU & Monitor Dbg)

From v1:
- Fix a pair of memory leak
- Check a pair of return values
- Mention calls which must be run on vCPU thread
- Force MIDR
- Use hv_vcpu_config_create/hv_vcpu_config_get_feature_reg
  when not running on vCPU thread
- Factor hvf_handle_vmexit() / hvf_handle_exception(() out
- Call hv_vcpu_run() in loop
- Guard hv_vcpu_run() between cpu_exec_start/end()
- Restrict ARM specific in AccelCPUState

Based-on: <20250829152909.1589668-14-pbonzini@redhat.com>

Philippe Mathieu-Daudé (14):
  target/i386/hvf: Use host page alignment in ept_emulation_fault()
  accel/hvf: Enforce host alignment in hv_vm_protect()
  accel/hvf: Skip WFI if CPU has work to do
  accel/hvf: Implement WFI without using pselect()
  accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU
  accel: Introduce AccelOpsClass::cpu_target_realize() hook
  accel/hvf: Add hvf_arch_cpu_realize() stubs
  target/arm: Create GTimers *after* features finalized / accel realized
  target/arm/hvf: Really set Generic Timer counter frequency
  target/arm: Only allow disabling NEON when using TCG
  accel/hvf: Introduce hvf_arch_cpu_synchronize_[pre/post]exec() hooks
  target/i386/hvf: Flush vCPU registers once before vcpu_exec() loop
  target/arm/hvf: Flush vCPU registers once before vcpu_exec() loop
  accel/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0

Richard Henderson (9):
  accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range
  target/i386/hvf: Use hvf_unprotect_dirty_range
  target/i386/hvf: Use address_space_translate in ept_emulation_fault
  accel/hvf: Simplify hvf_log_*
  accel/hvf: Move hvf_log_sync to hvf_log_clear
  accel/hvf: Simplify hvf_set_phys_mem
  accel/hvf: Drop hvf_slot and hvf_find_overlap_slot
  accel/hvf: Remove mac_slots
  target/arm/hvf: Implement dirty page tracking

 include/accel/accel-cpu-ops.h |   1 +
 include/system/hvf_int.h      |  26 ++--
 accel/accel-common.c          |   5 +
 accel/hvf/hvf-accel-ops.c     |  21 +---
 accel/hvf/hvf-all.c           | 186 +++++++++--------------------
 target/arm/cpu.c              |  67 +++++------
 target/arm/hvf/hvf.c          | 217 ++++++++++++++++++++--------------
 target/i386/hvf/hvf.c         |  61 ++++++----
 accel/hvf/trace-events        |   1 +
 9 files changed, 274 insertions(+), 311 deletions(-)

-- 
2.51.0



^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v4 01/23] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 02/23] target/i386/hvf: Use host page alignment in ept_emulation_fault() Philippe Mathieu-Daudé
                   ` (21 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 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);
+}
+
+void hvf_protect_clean_range(hwaddr addr, size_t size)
+{
+    do_hv_vm_protect(addr, size, HV_MEMORY_READ | HV_MEMORY_EXEC);
+}
+
+void hvf_unprotect_dirty_range(hwaddr addr, size_t size)
+{
+    do_hv_vm_protect(addr, size,
+                     HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
+}
+
 static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
 {
     struct mac_slot *macslot;
diff --git a/accel/hvf/trace-events b/accel/hvf/trace-events
index 2fd3e127c74..f989da59492 100644
--- a/accel/hvf/trace-events
+++ b/accel/hvf/trace-events
@@ -5,3 +5,4 @@
 # hvf-accel-ops.c
 hvf_vm_map(uint64_t paddr, uint64_t size, void *vaddr, uint8_t flags, const char r, const char w, const char e) "paddr:0x%016"PRIx64" size:0x%08"PRIx64" vaddr:%p flags:0x%02x/%c%c%c"
 hvf_vm_unmap(uint64_t paddr, uint64_t size) "paddr:0x%016"PRIx64" size:0x%08"PRIx64
+hvf_vm_protect(uint64_t paddr, size_t size, uint8_t flags, const char r, const char w, const char e) "paddr:0x%016"PRIx64" size:0x%08zx flags:0x%02x/%c%c%c"
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 02/23] target/i386/hvf: Use host page alignment in ept_emulation_fault()
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 01/23] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 03/23] accel/hvf: Enforce host alignment in hv_vm_protect() Philippe Mathieu-Daudé
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

While on x86 the host page size is fixed to 4KB, it is
better to call qemu_real_host_page_size() for consistency.

Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/i386/hvf/hvf.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 16febbac48f..9a1bf026a4a 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -76,7 +76,7 @@
 #include "qemu/main-loop.h"
 #include "qemu/accel.h"
 #include "target/i386/cpu.h"
-#include "exec/target_page.h"
+#include "exec/cpu-common.h"
 
 static Error *invtsc_mig_blocker;
 
@@ -137,9 +137,12 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
 
     if (write && slot) {
         if (slot->flags & HVF_SLOT_LOG) {
-            uint64_t dirty_page_start = gpa & ~(TARGET_PAGE_SIZE - 1u);
+            uintptr_t page_size = qemu_real_host_page_size();
+            intptr_t page_mask = -(intptr_t)page_size;
+            uint64_t dirty_page_start = gpa & page_mask;
+
             memory_region_set_dirty(slot->region, gpa - slot->start, 1);
-            hv_vm_protect(dirty_page_start, TARGET_PAGE_SIZE,
+            hv_vm_protect(dirty_page_start, page_size,
                           HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
         }
     }
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 03/23] accel/hvf: Enforce host alignment in hv_vm_protect()
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 01/23] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 02/23] target/i386/hvf: Use host page alignment in ept_emulation_fault() Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 04/23] target/i386/hvf: Use hvf_unprotect_dirty_range Philippe Mathieu-Daudé
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

hv_vm_protect() arguments must be aligned to host page.

Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 accel/hvf/hvf-all.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index e13abddbd9c..cb029e4dd4b 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -11,6 +11,7 @@
 #include "qemu/osdep.h"
 #include "qemu/error-report.h"
 #include "accel/accel-ops.h"
+#include "exec/cpu-common.h"
 #include "system/address-spaces.h"
 #include "system/memory.h"
 #include "system/hvf.h"
@@ -61,12 +62,15 @@ void assert_hvf_ok_impl(hv_return_t ret, const char *file, unsigned int line,
 static void do_hv_vm_protect(hwaddr start, size_t size,
                              hv_memory_flags_t flags)
 {
+    intptr_t page_mask = qemu_real_host_page_mask();
     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' : '-');
+    g_assert(!((uintptr_t)start & ~page_mask));
+    g_assert(!(size & ~page_mask));
 
     ret = hv_vm_protect(start, size, flags);
     assert_hvf_ok(ret);
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 04/23] target/i386/hvf: Use hvf_unprotect_dirty_range
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (2 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 03/23] accel/hvf: Enforce host alignment in hv_vm_protect() Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 05/23] target/i386/hvf: Use address_space_translate in ept_emulation_fault Philippe Mathieu-Daudé
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/i386/hvf/hvf.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 9a1bf026a4a..de06ec6125f 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -142,8 +142,7 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
             uint64_t dirty_page_start = gpa & page_mask;
 
             memory_region_set_dirty(slot->region, gpa - slot->start, 1);
-            hv_vm_protect(dirty_page_start, page_size,
-                          HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
+            hvf_unprotect_dirty_range(dirty_page_start, page_size);
         }
     }
 
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 05/23] target/i386/hvf: Use address_space_translate in ept_emulation_fault
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (3 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 04/23] target/i386/hvf: Use hvf_unprotect_dirty_range Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 06/23] accel/hvf: Simplify hvf_log_* Philippe Mathieu-Daudé
                   ` (17 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

The hvf_slot structure is a poor replacement for properly
looking up a memory region in the address space.
Use memory_region_get_dirty_log_mask instead of HVF_SLOT_LOG.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/i386/hvf/hvf.c | 37 ++++++++++++++++++-------------------
 1 file changed, 18 insertions(+), 19 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index de06ec6125f..d0ee00425f0 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -119,9 +119,12 @@ void hvf_handle_io(CPUState *env, uint16_t port, void *buffer,
     }
 }
 
-static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
+static bool ept_emulation_fault(CPUState *cs, uint64_t gpa, uint64_t ept_qual)
 {
-    int read, write;
+    bool read, write;
+    MemoryRegion *mr;
+    hwaddr gpa_page = gpa & qemu_real_host_page_mask();
+    hwaddr xlat;
 
     /* EPT fault on an instruction fetch doesn't make sense here */
     if (ept_qual & EPT_VIOLATION_INST_FETCH) {
@@ -129,21 +132,22 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
     }
 
     /* EPT fault must be a read fault or a write fault */
-    read = ept_qual & EPT_VIOLATION_DATA_READ ? 1 : 0;
-    write = ept_qual & EPT_VIOLATION_DATA_WRITE ? 1 : 0;
-    if ((read | write) == 0) {
+    read = ept_qual & EPT_VIOLATION_DATA_READ;
+    write = ept_qual & EPT_VIOLATION_DATA_WRITE;
+    if (!read && !write) {
         return false;
     }
 
-    if (write && slot) {
-        if (slot->flags & HVF_SLOT_LOG) {
-            uintptr_t page_size = qemu_real_host_page_size();
-            intptr_t page_mask = -(intptr_t)page_size;
-            uint64_t dirty_page_start = gpa & page_mask;
+    mr = address_space_translate(cpu_get_address_space(cs, X86ASIdx_MEM),
+                                 gpa_page, &xlat, NULL, write,
+                                 MEMTXATTRS_UNSPECIFIED);
 
-            memory_region_set_dirty(slot->region, gpa - slot->start, 1);
-            hvf_unprotect_dirty_range(dirty_page_start, page_size);
-        }
+    /* Handle dirty page logging for ram. */
+    if (write && memory_region_get_dirty_log_mask(mr)) {
+        uintptr_t page_size = qemu_real_host_page_size();
+
+        memory_region_set_dirty(mr, gpa_page + xlat, page_size);
+        hvf_unprotect_dirty_range(gpa_page, page_size);
     }
 
     /*
@@ -156,9 +160,6 @@ static bool ept_emulation_fault(hvf_slot *slot, uint64_t gpa, uint64_t ept_qual)
         return false;
     }
 
-    if (!slot) {
-        return true;
-    }
     if (!memory_region_is_ram(slot->region) &&
         !(read && memory_region_is_romd(slot->region))) {
         return true;
@@ -764,7 +765,6 @@ static int hvf_handle_vmexit(CPUState *cpu)
     /* Need to check if MMIO or unmapped fault */
     case EXIT_REASON_EPT_FAULT:
     {
-        hvf_slot *slot;
         uint64_t gpa = rvmcs(cpu->accel->fd, VMCS_GUEST_PHYSICAL_ADDRESS);
 
         if (((idtvec_info & VMCS_IDT_VEC_VALID) == 0) &&
@@ -772,9 +772,8 @@ static int hvf_handle_vmexit(CPUState *cpu)
             vmx_set_nmi_blocking(cpu);
         }
 
-        slot = hvf_find_overlap_slot(gpa, 1);
         /* mmio */
-        if (ept_emulation_fault(slot, gpa, exit_qual)) {
+        if (ept_emulation_fault(cpu, gpa, exit_qual)) {
             struct x86_decode decode;
 
             hvf_load_regs(cpu);
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 06/23] accel/hvf: Simplify hvf_log_*
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (4 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 05/23] target/i386/hvf: Use address_space_translate in ept_emulation_fault Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 07/23] accel/hvf: Move hvf_log_sync to hvf_log_clear Philippe Mathieu-Daudé
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

Rely on the AddressSpace and MemoryRegion structures
rather than hvf_slot.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 include/system/hvf_int.h |  3 ---
 accel/hvf/hvf-all.c      | 40 ++++++++++------------------------------
 2 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index 5a57691885f..ee7ab689f45 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -24,9 +24,6 @@ typedef hv_vcpu_t hvf_vcpuid;
 typedef hv_vcpuid_t hvf_vcpuid;
 #endif
 
-/* hvf_slot flags */
-#define HVF_SLOT_LOG (1 << 0)
-
 typedef struct hvf_slot {
     uint64_t start;
     uint64_t size;
diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index cb029e4dd4b..601e63c7f9a 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -204,45 +204,24 @@ static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
     }
 }
 
-static void hvf_set_dirty_tracking(MemoryRegionSection *section, bool on)
-{
-    hvf_slot *slot;
-
-    slot = hvf_find_overlap_slot(
-            section->offset_within_address_space,
-            int128_get64(section->size));
-
-    /* protect region against writes; begin tracking it */
-    if (on) {
-        slot->flags |= HVF_SLOT_LOG;
-        hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
-                      HV_MEMORY_READ | HV_MEMORY_EXEC);
-    /* stop tracking region*/
-    } else {
-        slot->flags &= ~HVF_SLOT_LOG;
-        hv_vm_protect((uintptr_t)slot->start, (size_t)slot->size,
-                      HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
-    }
-}
-
 static void hvf_log_start(MemoryListener *listener,
                           MemoryRegionSection *section, int old, int new)
 {
-    if (old != 0) {
-        return;
+    assert(new != 0);
+    if (old == 0) {
+        hvf_protect_clean_range(section->offset_within_address_space,
+                                int128_get64(section->size));
     }
-
-    hvf_set_dirty_tracking(section, 1);
 }
 
 static void hvf_log_stop(MemoryListener *listener,
                          MemoryRegionSection *section, int old, int new)
 {
-    if (new != 0) {
-        return;
+    assert(old != 0);
+    if (new == 0) {
+        hvf_unprotect_dirty_range(section->offset_within_address_space,
+                                  int128_get64(section->size));
     }
-
-    hvf_set_dirty_tracking(section, 0);
 }
 
 static void hvf_log_sync(MemoryListener *listener,
@@ -252,7 +231,8 @@ static void hvf_log_sync(MemoryListener *listener,
      * sync of dirty pages is handled elsewhere; just make sure we keep
      * tracking the region.
      */
-    hvf_set_dirty_tracking(section, 1);
+    hvf_protect_clean_range(section->offset_within_address_space,
+                            int128_get64(section->size));
 }
 
 static void hvf_region_add(MemoryListener *listener,
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 07/23] accel/hvf: Move hvf_log_sync to hvf_log_clear
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (5 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 06/23] accel/hvf: Simplify hvf_log_* Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 08/23] accel/hvf: Simplify hvf_set_phys_mem Philippe Mathieu-Daudé
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

Right idea, wrong hook.  log_sync is called before using
dirty bit data (which for hvf is already up-to-date),
whereas log_clear is called before cleaning the range.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 accel/hvf/hvf-all.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index 601e63c7f9a..f203a6251f0 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -224,12 +224,13 @@ static void hvf_log_stop(MemoryListener *listener,
     }
 }
 
-static void hvf_log_sync(MemoryListener *listener,
-                         MemoryRegionSection *section)
+static void hvf_log_clear(MemoryListener *listener,
+                          MemoryRegionSection *section)
 {
     /*
-     * sync of dirty pages is handled elsewhere; just make sure we keep
-     * tracking the region.
+     * The dirty page bits within section are being cleared.
+     * Some number of those pages may have been dirtied and
+     * the write permission enabled.  Reset the range read-only.
      */
     hvf_protect_clean_range(section->offset_within_address_space,
                             int128_get64(section->size));
@@ -254,7 +255,7 @@ static MemoryListener hvf_memory_listener = {
     .region_del = hvf_region_del,
     .log_start = hvf_log_start,
     .log_stop = hvf_log_stop,
-    .log_sync = hvf_log_sync,
+    .log_clear = hvf_log_clear,
 };
 
 static int hvf_accel_init(AccelState *as, MachineState *ms)
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 08/23] accel/hvf: Simplify hvf_set_phys_mem
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (6 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 07/23] accel/hvf: Move hvf_log_sync to hvf_log_clear Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 11:59   ` Akihiko Odaki
  2025-11-03 10:10 ` [PATCH v4 09/23] accel/hvf: Drop hvf_slot and hvf_find_overlap_slot Philippe Mathieu-Daudé
                   ` (14 subsequent siblings)
  22 siblings, 1 reply; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

All of the complicated parts of updating the address space
are handled by address_space_update_topology_pass.
Do not create or use hvf_slot structures.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 accel/hvf/hvf-all.c | 111 +++++++-------------------------------------
 1 file changed, 17 insertions(+), 94 deletions(-)

diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index f203a6251f0..76b8d4d4068 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -87,45 +87,16 @@ void hvf_unprotect_dirty_range(hwaddr addr, size_t size)
                      HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
 }
 
-static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
-{
-    struct mac_slot *macslot;
-    hv_return_t ret;
-
-    macslot = &mac_slots[slot->slot_id];
-
-    if (macslot->present) {
-        if (macslot->size != slot->size) {
-            macslot->present = 0;
-            trace_hvf_vm_unmap(macslot->gpa_start, macslot->size);
-            ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
-            assert_hvf_ok(ret);
-        }
-    }
-
-    if (!slot->size) {
-        return 0;
-    }
-
-    macslot->present = 1;
-    macslot->gpa_start = slot->start;
-    macslot->size = slot->size;
-    trace_hvf_vm_map(slot->start, slot->size, slot->mem, flags,
-                     flags & HV_MEMORY_READ ?  'R' : '-',
-                     flags & HV_MEMORY_WRITE ? 'W' : '-',
-                     flags & HV_MEMORY_EXEC ?  'X' : '-');
-    ret = hv_vm_map(slot->mem, slot->start, slot->size, flags);
-    assert_hvf_ok(ret);
-    return 0;
-}
-
 static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
 {
-    hvf_slot *mem;
     MemoryRegion *area = section->mr;
     bool writable = !area->readonly && !area->rom_device;
     hv_memory_flags_t flags;
     uint64_t page_size = qemu_real_host_page_size();
+    uint64_t gva = section->offset_within_address_space;
+    uint64_t size = int128_get64(section->size);
+    hv_return_t ret;
+    void *mem;
 
     if (!memory_region_is_ram(area)) {
         if (writable) {
@@ -139,69 +110,28 @@ static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
         }
     }
 
-    if (!QEMU_IS_ALIGNED(int128_get64(section->size), page_size) ||
-        !QEMU_IS_ALIGNED(section->offset_within_address_space, page_size)) {
+    if (!QEMU_IS_ALIGNED(size, page_size) ||
+        !QEMU_IS_ALIGNED(gva, page_size)) {
         /* Not page aligned, so we can not map as RAM */
         add = false;
     }
 
-    mem = hvf_find_overlap_slot(
-            section->offset_within_address_space,
-            int128_get64(section->size));
-
-    if (mem && add) {
-        if (mem->size == int128_get64(section->size) &&
-            mem->start == section->offset_within_address_space &&
-            mem->mem == (memory_region_get_ram_ptr(area) +
-            section->offset_within_region)) {
-            return; /* Same region was attempted to register, go away. */
-        }
-    }
-
-    /* Region needs to be reset. set the size to 0 and remap it. */
-    if (mem) {
-        mem->size = 0;
-        if (do_hvf_set_memory(mem, 0)) {
-            error_report("Failed to reset overlapping slot");
-            abort();
-        }
-    }
-
     if (!add) {
+        trace_hvf_vm_unmap(gva, size);
+        ret = hv_vm_unmap(gva, size);
+        assert_hvf_ok(ret);
         return;
     }
 
-    if (area->readonly ||
-        (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
-        flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
-    } else {
-        flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
-    }
+    flags = HV_MEMORY_READ | HV_MEMORY_EXEC | (writable ? HV_MEMORY_WRITE : 0);
+    mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
 
-    /* Now make a new slot. */
-    int x;
-
-    for (x = 0; x < hvf_state->num_slots; ++x) {
-        mem = &hvf_state->slots[x];
-        if (!mem->size) {
-            break;
-        }
-    }
-
-    if (x == hvf_state->num_slots) {
-        error_report("No free slots");
-        abort();
-    }
-
-    mem->size = int128_get64(section->size);
-    mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
-    mem->start = section->offset_within_address_space;
-    mem->region = area;
-
-    if (do_hvf_set_memory(mem, flags)) {
-        error_report("Error registering new memory slot");
-        abort();
-    }
+    trace_hvf_vm_map(gva, size, mem, flags,
+                     flags & HV_MEMORY_READ ?  'R' : '-',
+                     flags & HV_MEMORY_WRITE ? 'W' : '-',
+                     flags & HV_MEMORY_EXEC ?  'X' : '-');
+    ret = hv_vm_map(mem, gva, size, flags);
+    assert_hvf_ok(ret);
 }
 
 static void hvf_log_start(MemoryListener *listener,
@@ -260,7 +190,6 @@ static MemoryListener hvf_memory_listener = {
 
 static int hvf_accel_init(AccelState *as, MachineState *ms)
 {
-    int x;
     hv_return_t ret;
     HVFState *s = HVF_STATE(as);
     int pa_range = 36;
@@ -281,12 +210,6 @@ static int hvf_accel_init(AccelState *as, MachineState *ms)
     }
     assert_hvf_ok(ret);
 
-    s->num_slots = ARRAY_SIZE(s->slots);
-    for (x = 0; x < s->num_slots; ++x) {
-        s->slots[x].size = 0;
-        s->slots[x].slot_id = x;
-    }
-
     QTAILQ_INIT(&s->hvf_sw_breakpoints);
 
     hvf_state = s;
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 09/23] accel/hvf: Drop hvf_slot and hvf_find_overlap_slot
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (7 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 08/23] accel/hvf: Simplify hvf_set_phys_mem Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 10/23] accel/hvf: Remove mac_slots Philippe Mathieu-Daudé
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

These are now unused.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 include/system/hvf_int.h  | 13 -------------
 accel/hvf/hvf-accel-ops.c | 14 --------------
 2 files changed, 27 deletions(-)

diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index ee7ab689f45..d842d4b2b99 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -24,15 +24,6 @@ typedef hv_vcpu_t hvf_vcpuid;
 typedef hv_vcpuid_t hvf_vcpuid;
 #endif
 
-typedef struct hvf_slot {
-    uint64_t start;
-    uint64_t size;
-    uint8_t *mem;
-    int slot_id;
-    uint32_t flags;
-    MemoryRegion *region;
-} hvf_slot;
-
 typedef struct hvf_vcpu_caps {
     uint64_t vmx_cap_pinbased;
     uint64_t vmx_cap_procbased;
@@ -45,9 +36,6 @@ typedef struct hvf_vcpu_caps {
 struct HVFState {
     AccelState parent_obj;
 
-    hvf_slot slots[32];
-    int num_slots;
-
     hvf_vcpu_caps *hvf_caps;
     uint64_t vtimer_offset;
     QTAILQ_HEAD(, hvf_sw_breakpoint) hvf_sw_breakpoints;
@@ -70,7 +58,6 @@ void assert_hvf_ok_impl(hv_return_t ret, const char *file, unsigned int line,
 const char *hvf_return_string(hv_return_t ret);
 int hvf_arch_init(void);
 hv_return_t hvf_arch_vm_create(MachineState *ms, uint32_t pa_range);
-hvf_slot *hvf_find_overlap_slot(uint64_t, uint64_t);
 void hvf_kick_vcpu_thread(CPUState *cpu);
 
 /* Must be called by the owning thread */
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 3e5feecd8a7..bbb0b385fe9 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -64,20 +64,6 @@ HVFState *hvf_state;
 
 /* Memory slots */
 
-hvf_slot *hvf_find_overlap_slot(uint64_t start, uint64_t size)
-{
-    hvf_slot *slot;
-    int x;
-    for (x = 0; x < hvf_state->num_slots; ++x) {
-        slot = &hvf_state->slots[x];
-        if (slot->size && start < (slot->start + slot->size) &&
-            (start + size) > slot->start) {
-            return slot;
-        }
-    }
-    return NULL;
-}
-
 static void do_hvf_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
 {
     if (!cpu->vcpu_dirty) {
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 10/23] accel/hvf: Remove mac_slots
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (8 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 09/23] accel/hvf: Drop hvf_slot and hvf_find_overlap_slot Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 11/23] target/arm/hvf: Implement dirty page tracking Philippe Mathieu-Daudé
                   ` (12 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

This data structure is no longer used.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 accel/hvf/hvf-all.c | 9 ---------
 1 file changed, 9 deletions(-)

diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
index 76b8d4d4068..cbd0858b763 100644
--- a/accel/hvf/hvf-all.c
+++ b/accel/hvf/hvf-all.c
@@ -22,15 +22,6 @@
 
 bool hvf_allowed;
 
-struct mac_slot {
-    int present;
-    uint64_t size;
-    uint64_t gpa_start;
-    uint64_t gva;
-};
-
-struct mac_slot mac_slots[32];
-
 const char *hvf_return_string(hv_return_t ret)
 {
     switch (ret) {
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 11/23] target/arm/hvf: Implement dirty page tracking
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (9 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 10/23] accel/hvf: Remove mac_slots Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 12/23] accel/hvf: Skip WFI if CPU has work to do Philippe Mathieu-Daudé
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

From: Richard Henderson <richard.henderson@linaro.org>

Notice writes to pages which are being monitored.  Mark the page dirty,
re-enable writes, and retry the instruction without emulation.

Assert the fault is not from a stage1 page table walk.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Tested-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/arm/hvf/hvf.c | 52 ++++++++++++++++++++++++++++++++++++--------
 1 file changed, 43 insertions(+), 9 deletions(-)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index de1e8fb8a05..0f584b8137a 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1869,9 +1869,10 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
         uint32_t srt = (syndrome >> 16) & 0x1f;
         uint32_t cm = (syndrome >> 8) & 0x1;
         uint64_t val = 0;
+        uint64_t ipa = excp->physical_address;
+        AddressSpace *as = cpu_get_address_space(cpu, ARMASIdx_NS);
 
-        trace_hvf_data_abort(excp->virtual_address,
-                             excp->physical_address, isv,
+        trace_hvf_data_abort(excp->virtual_address, ipa, isv,
                              iswrite, s1ptw, len, srt);
 
         if (cm) {
@@ -1880,23 +1881,56 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
             break;
         }
 
+        /* Handle dirty page logging for ram. */
+        if (iswrite) {
+            hwaddr xlat;
+            MemoryRegion *mr = address_space_translate(as, ipa, &xlat,
+                                                       NULL, true,
+                                                       MEMTXATTRS_UNSPECIFIED);
+            if (memory_region_is_ram(mr)) {
+                uintptr_t page_size = qemu_real_host_page_size();
+                intptr_t page_mask = -(intptr_t)page_size;
+                uint64_t ipa_page = ipa & page_mask;
+
+                /* TODO: Inject exception to the guest. */
+                assert(!mr->readonly);
+
+                if (memory_region_get_dirty_log_mask(mr)) {
+                    memory_region_set_dirty(mr, ipa_page + xlat, page_size);
+                    hvf_unprotect_dirty_range(ipa_page, page_size);
+                }
+
+                /* Retry with page writes enabled. */
+                break;
+            }
+        }
+
+        /*
+         * TODO: If s1ptw, this is an error in the guest os page tables.
+         * Inject the exception into the guest.
+         */
+        assert(!s1ptw);
+
+        /*
+         * TODO: ISV will be 0 for SIMD or SVE accesses.
+         * Inject the exception into the guest.
+         */
         assert(isv);
 
+        /*
+         * Emulate MMIO.
+         * TODO: Inject faults for errors.
+         */
         if (iswrite) {
             val = hvf_get_reg(cpu, srt);
-            address_space_write(&address_space_memory,
-                                excp->physical_address,
-                                MEMTXATTRS_UNSPECIFIED, &val, len);
+            address_space_write(as, ipa, MEMTXATTRS_UNSPECIFIED, &val, len);
         } else {
-            address_space_read(&address_space_memory,
-                               excp->physical_address,
-                               MEMTXATTRS_UNSPECIFIED, &val, len);
+            address_space_read(as, ipa, MEMTXATTRS_UNSPECIFIED, &val, len);
             if (sse) {
                 val = sextract64(val, 0, len * 8);
             }
             hvf_set_reg(cpu, srt, val);
         }
-
         advance_pc = true;
         break;
     }
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 12/23] accel/hvf: Skip WFI if CPU has work to do
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (10 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 11/23] target/arm/hvf: Implement dirty page tracking Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 13/23] accel/hvf: Implement WFI without using pselect() Philippe Mathieu-Daudé
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni, Alex Bennée

Avoid sleeping vCPU thread for any pending work, not just IRQs.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/hvf/hvf.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 0f584b8137a..5e46e8bf4dd 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -1737,8 +1737,11 @@ static void hvf_wfi(CPUState *cpu)
     uint64_t nanos;
     uint32_t cntfrq;
 
-    if (cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD | CPU_INTERRUPT_FIQ)) {
-        /* Interrupt pending, no need to wait */
+    if (cpu_has_work(cpu)) {
+        /*
+         * Don't bother to go into our "low power state" if
+         * we would just wake up immediately.
+         */
         return;
     }
 
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 13/23] accel/hvf: Implement WFI without using pselect()
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (11 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 12/23] accel/hvf: Skip WFI if CPU has work to do Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 12:17   ` Akihiko Odaki
  2025-11-03 10:10 ` [PATCH v4 14/23] accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU Philippe Mathieu-Daudé
                   ` (9 subsequent siblings)
  22 siblings, 1 reply; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Return to the main loop where we'll be waken again.
This avoid a tricky race with signals introduced in
commit 219c101fa7f ("Add HVF WFI handler").

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 include/system/hvf_int.h  |  1 -
 accel/hvf/hvf-accel-ops.c |  3 --
 target/arm/hvf/hvf.c      | 74 +++------------------------------------
 3 files changed, 5 insertions(+), 73 deletions(-)

diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index d842d4b2b99..c8e407a1463 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -47,7 +47,6 @@ struct AccelCPUState {
 #ifdef __aarch64__
     hv_vcpu_exit_t *exit;
     bool vtimer_masked;
-    sigset_t unblock_ipi_mask;
     bool guest_debug_enabled;
 #endif
 };
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index bbb0b385fe9..5922eb02e70 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -134,9 +134,6 @@ static int hvf_init_vcpu(CPUState *cpu)
     sigact.sa_handler = dummy_signal;
     sigaction(SIG_IPI, &sigact, NULL);
 
-    pthread_sigmask(SIG_BLOCK, NULL, &cpu->accel->unblock_ipi_mask);
-    sigdelset(&cpu->accel->unblock_ipi_mask, SIG_IPI);
-
 #ifdef __aarch64__
     r = hv_vcpu_create(&cpu->accel->fd,
                        (hv_vcpu_exit_t **)&cpu->accel->exit, NULL);
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 5e46e8bf4dd..51fd8c7175b 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -301,7 +301,7 @@ void hvf_arm_init_debug(void)
 #define TMR_CTL_IMASK   (1 << 1)
 #define TMR_CTL_ISTATUS (1 << 2)
 
-static void hvf_wfi(CPUState *cpu);
+static int hvf_wfi(CPUState *cpu);
 
 static uint32_t chosen_ipa_bit_size;
 
@@ -1703,81 +1703,17 @@ static uint64_t hvf_vtimer_val_raw(void)
     return mach_absolute_time() - hvf_state->vtimer_offset;
 }
 
-static uint64_t hvf_vtimer_val(void)
+static int hvf_wfi(CPUState *cpu)
 {
-    if (!runstate_is_running()) {
-        /* VM is paused, the vtimer value is in vtimer.vtimer_val */
-        return vtimer.vtimer_val;
-    }
-
-    return hvf_vtimer_val_raw();
-}
-
-static void hvf_wait_for_ipi(CPUState *cpu, struct timespec *ts)
-{
-    /*
-     * Use pselect to sleep so that other threads can IPI us while we're
-     * sleeping.
-     */
-    qatomic_set_mb(&cpu->thread_kicked, false);
-    bql_unlock();
-    pselect(0, 0, 0, 0, ts, &cpu->accel->unblock_ipi_mask);
-    bql_lock();
-}
-
-static void hvf_wfi(CPUState *cpu)
-{
-    ARMCPU *arm_cpu = ARM_CPU(cpu);
-    struct timespec ts;
-    hv_return_t r;
-    uint64_t ctl;
-    uint64_t cval;
-    int64_t ticks_to_sleep;
-    uint64_t seconds;
-    uint64_t nanos;
-    uint32_t cntfrq;
-
     if (cpu_has_work(cpu)) {
         /*
          * Don't bother to go into our "low power state" if
          * we would just wake up immediately.
          */
-        return;
+        return 0;
     }
 
-    r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, &ctl);
-    assert_hvf_ok(r);
-
-    if (!(ctl & 1) || (ctl & 2)) {
-        /* Timer disabled or masked, just wait for an IPI. */
-        hvf_wait_for_ipi(cpu, NULL);
-        return;
-    }
-
-    r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, &cval);
-    assert_hvf_ok(r);
-
-    ticks_to_sleep = cval - hvf_vtimer_val();
-    if (ticks_to_sleep < 0) {
-        return;
-    }
-
-    cntfrq = gt_cntfrq_period_ns(arm_cpu);
-    seconds = muldiv64(ticks_to_sleep, cntfrq, NANOSECONDS_PER_SECOND);
-    ticks_to_sleep -= muldiv64(seconds, NANOSECONDS_PER_SECOND, cntfrq);
-    nanos = ticks_to_sleep * cntfrq;
-
-    /*
-     * Don't sleep for less than the time a context switch would take,
-     * so that we can satisfy fast timer requests on the same CPU.
-     * Measurements on M1 show the sweet spot to be ~2ms.
-     */
-    if (!seconds && nanos < (2 * SCALE_MS)) {
-        return;
-    }
-
-    ts = (struct timespec) { seconds, nanos };
-    hvf_wait_for_ipi(cpu, &ts);
+    return EXCP_HLT;
 }
 
 /* Must be called by the owning thread */
@@ -1967,7 +1903,7 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
     case EC_WFX_TRAP:
         advance_pc = true;
         if (!(syndrome & WFX_IS_WFE)) {
-            hvf_wfi(cpu);
+            ret = hvf_wfi(cpu);
         }
         break;
     case EC_AA64_HVC:
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 14/23] accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (12 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 13/23] accel/hvf: Implement WFI without using pselect() Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 15/23] accel: Introduce AccelOpsClass::cpu_target_realize() hook Philippe Mathieu-Daudé
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Return EXCP_HLT to the main loop.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/hvf/hvf.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 51fd8c7175b..59a2ef53629 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -301,8 +301,6 @@ void hvf_arm_init_debug(void)
 #define TMR_CTL_IMASK   (1 << 1)
 #define TMR_CTL_ISTATUS (1 << 2)
 
-static int hvf_wfi(CPUState *cpu);
-
 static uint32_t chosen_ipa_bit_size;
 
 typedef struct HVFVTimer {
@@ -1008,7 +1006,7 @@ static void hvf_psci_cpu_off(ARMCPU *arm_cpu)
  * Returns 0 on success
  *         -1 when the PSCI call is unknown,
  */
-static bool hvf_handle_psci_call(CPUState *cpu)
+static bool hvf_handle_psci_call(CPUState *cpu, int *excp_ret)
 {
     ARMCPU *arm_cpu = ARM_CPU(cpu);
     CPUARMState *env = &arm_cpu->env;
@@ -1091,9 +1089,8 @@ static bool hvf_handle_psci_call(CPUState *cpu)
             ret = QEMU_PSCI_RET_INVALID_PARAMS;
             break;
         }
-        /* Powerdown is not supported, we always go into WFI */
         env->xregs[0] = 0;
-        hvf_wfi(cpu);
+        *excp_ret = EXCP_HLT;
         break;
     case QEMU_PSCI_0_1_FN_MIGRATE:
     case QEMU_PSCI_0_2_FN_MIGRATE:
@@ -1910,7 +1907,7 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
         cpu_synchronize_state(cpu);
         if (arm_is_psci_call(arm_cpu, EXCP_HVC)) {
             /* Do NOT advance $pc for HVC */
-            if (!hvf_handle_psci_call(cpu)) {
+            if (!hvf_handle_psci_call(cpu, &ret)) {
                 trace_hvf_unknown_hvc(env->pc, env->xregs[0]);
                 /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
                 env->xregs[0] = -1;
@@ -1926,7 +1923,7 @@ static int hvf_handle_exception(CPUState *cpu, hv_vcpu_exit_exception_t *excp)
             /* Secure Monitor Call exception, we need to advance $pc */
             advance_pc = true;
 
-            if (!hvf_handle_psci_call(cpu)) {
+            if (!hvf_handle_psci_call(cpu, &ret)) {
                 trace_hvf_unknown_smc(env->xregs[0]);
                 /* SMCCC 1.3 section 5.2 says every unknown SMCCC call returns -1 */
                 env->xregs[0] = -1;
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 15/23] accel: Introduce AccelOpsClass::cpu_target_realize() hook
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (13 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 14/23] accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 16/23] accel/hvf: Add hvf_arch_cpu_realize() stubs Philippe Mathieu-Daudé
                   ` (7 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Allow accelerators to set vCPU properties before its realization.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/accel/accel-cpu-ops.h | 1 +
 accel/accel-common.c          | 5 +++++
 2 files changed, 6 insertions(+)

diff --git a/include/accel/accel-cpu-ops.h b/include/accel/accel-cpu-ops.h
index 0674764914f..9c07a903ea0 100644
--- a/include/accel/accel-cpu-ops.h
+++ b/include/accel/accel-cpu-ops.h
@@ -34,6 +34,7 @@ struct AccelOpsClass {
     /* initialization function called when accel is chosen */
     void (*ops_init)(AccelClass *ac);
 
+    bool (*cpu_target_realize)(CPUState *cpu, Error **errp);
     bool (*cpus_are_resettable)(void);
     void (*cpu_reset_hold)(CPUState *cpu);
 
diff --git a/accel/accel-common.c b/accel/accel-common.c
index 850c5ab4b8e..eecb2a292af 100644
--- a/accel/accel-common.c
+++ b/accel/accel-common.c
@@ -106,6 +106,11 @@ bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
     if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) {
         return false;
     }
+    if (acc->ops
+        && acc->ops->cpu_target_realize
+        && !acc->ops->cpu_target_realize(cpu, errp)) {
+        return false;
+    }
 
     return true;
 }
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 16/23] accel/hvf: Add hvf_arch_cpu_realize() stubs
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (14 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 15/23] accel: Introduce AccelOpsClass::cpu_target_realize() hook Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 17/23] target/arm: Create GTimers *after* features finalized / accel realized Philippe Mathieu-Daudé
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Implement HVF AccelOpsClass::cpu_target_realize() hook as
empty stubs. Target implementations will come separately.

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/system/hvf_int.h  | 2 ++
 accel/hvf/hvf-accel-ops.c | 2 ++
 target/arm/hvf/hvf.c      | 5 +++++
 target/i386/hvf/hvf.c     | 5 +++++
 4 files changed, 14 insertions(+)

diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index c8e407a1463..96790b49386 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -106,4 +106,6 @@ int hvf_update_guest_debug(CPUState *cpu);
  */
 bool hvf_arch_supports_guest_debug(void);
 
+bool hvf_arch_cpu_realize(CPUState *cpu, Error **errp);
+
 #endif
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 5922eb02e70..02c5d01670d 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -356,6 +356,8 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
 {
     AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
 
+    ops->cpu_target_realize = hvf_arch_cpu_realize;
+
     ops->create_vcpu_thread = hvf_start_vcpu_thread;
     ops->kick_vcpu_thread = hvf_kick_vcpu_thread;
     ops->handle_interrupt = generic_handle_interrupt;
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 59a2ef53629..8208d345daa 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -972,6 +972,11 @@ int hvf_arch_init_vcpu(CPUState *cpu)
     return 0;
 }
 
+bool hvf_arch_cpu_realize(CPUState *cs, Error **errp)
+{
+    return true;
+}
+
 void hvf_kick_vcpu_thread(CPUState *cpu)
 {
     hv_return_t ret;
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index d0ee00425f0..1b189efb4c7 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -370,6 +370,11 @@ int hvf_arch_init_vcpu(CPUState *cpu)
     return 0;
 }
 
+bool hvf_arch_cpu_realize(CPUState *cs, Error **errp)
+{
+    return true;
+}
+
 static void hvf_store_events(CPUState *cpu, uint32_t ins_len, uint64_t idtvec_info)
 {
     X86CPU *x86_cpu = X86_CPU(cpu);
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 17/23] target/arm: Create GTimers *after* features finalized / accel realized
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (15 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 16/23] accel/hvf: Add hvf_arch_cpu_realize() stubs Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 18/23] target/arm/hvf: Really set Generic Timer counter frequency Philippe Mathieu-Daudé
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Call generic (including accelerator) cpu_realize() handlers
*before* setting @gt_cntfrq_hz default

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
---
 target/arm/cpu.c | 65 ++++++++++++++++++++++++------------------------
 1 file changed, 33 insertions(+), 32 deletions(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 39292fb9bc1..b392374df98 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1636,26 +1636,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
         return;
     }
 
-    if (!cpu->gt_cntfrq_hz) {
-        /*
-         * 0 means "the board didn't set a value, use the default". (We also
-         * get here for the CONFIG_USER_ONLY case.)
-         * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
-         * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
-         * which gives a 16ns tick period.
-         *
-         * We will use the back-compat value:
-         *  - for QEMU CPU types added before we standardized on 1GHz
-         *  - for versioned machine types with a version of 9.0 or earlier
-         */
-        if (arm_feature(env, ARM_FEATURE_BACKCOMPAT_CNTFRQ) ||
-            cpu->backcompat_cntfrq) {
-            cpu->gt_cntfrq_hz = GTIMER_BACKCOMPAT_HZ;
-        } else {
-            cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
-        }
-    }
-
 #ifndef CONFIG_USER_ONLY
     /* The NVIC and M-profile CPU are two halves of a single piece of
      * hardware; trying to use one without the other is a command line
@@ -1702,7 +1682,40 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
             return;
         }
     }
+#endif
 
+    cpu_exec_realizefn(cs, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    arm_cpu_finalize_features(cpu, &local_err);
+    if (local_err != NULL) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    if (!cpu->gt_cntfrq_hz) {
+        /*
+         * 0 means "the board didn't set a value, use the default". (We also
+         * get here for the CONFIG_USER_ONLY case.)
+         * ARMv8.6 and later CPUs architecturally must use a 1GHz timer; before
+         * that it was an IMPDEF choice, and QEMU initially picked 62.5MHz,
+         * which gives a 16ns tick period.
+         *
+         * We will use the back-compat value:
+         *  - for QEMU CPU types added before we standardized on 1GHz
+         *  - for versioned machine types with a version of 9.0 or earlier
+         */
+        if (arm_feature(env, ARM_FEATURE_BACKCOMPAT_CNTFRQ) ||
+            cpu->backcompat_cntfrq) {
+            cpu->gt_cntfrq_hz = GTIMER_BACKCOMPAT_HZ;
+        } else {
+            cpu->gt_cntfrq_hz = GTIMER_DEFAULT_HZ;
+        }
+    }
+#ifndef CONFIG_USER_ONLY
     {
         uint64_t scale = gt_cntfrq_period_ns(cpu);
 
@@ -1723,18 +1736,6 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
     }
 #endif
 
-    cpu_exec_realizefn(cs, &local_err);
-    if (local_err != NULL) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
-    arm_cpu_finalize_features(cpu, &local_err);
-    if (local_err != NULL) {
-        error_propagate(errp, local_err);
-        return;
-    }
-
 #ifdef CONFIG_USER_ONLY
     /*
      * User mode relies on IC IVAU instructions to catch modification of
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 18/23] target/arm/hvf: Really set Generic Timer counter frequency
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (16 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 17/23] target/arm: Create GTimers *after* features finalized / accel realized Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 19/23] target/arm: Only allow disabling NEON when using TCG Philippe Mathieu-Daudé
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Setting ARMCPU::gt_cntfrq_hz in hvf_arch_init_vcpu() is
not correct because the timers have already be initialized
with the default frequency.

Set it earlier in the AccelOpsClass::cpu_target_realize()
handler instead, and assert the value is correct when
reaching hvf_arch_init_vcpu().

Fixes: a1477da3dde ("hvf: Add Apple Silicon support")
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/hvf/hvf.c | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 8208d345daa..e1113e3d6ca 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -897,6 +897,13 @@ cleanup:
     return ret;
 }
 
+static uint64_t get_cntfrq_el0(void)
+{
+    uint64_t freq_hz = 0;
+    asm volatile("mrs %0, cntfrq_el0" : "=r"(freq_hz));
+    return freq_hz;
+}
+
 int hvf_arch_init_vcpu(CPUState *cpu)
 {
     ARMCPU *arm_cpu = ARM_CPU(cpu);
@@ -908,7 +915,9 @@ int hvf_arch_init_vcpu(CPUState *cpu)
     int i;
 
     env->aarch64 = true;
-    asm volatile("mrs %0, cntfrq_el0" : "=r"(arm_cpu->gt_cntfrq_hz));
+
+    /* system count frequency sanity check */
+    assert(arm_cpu->gt_cntfrq_hz == get_cntfrq_el0());
 
     /* Allocate enough space for our sysreg sync */
     arm_cpu->cpreg_indexes = g_renew(uint64_t, arm_cpu->cpreg_indexes,
@@ -974,6 +983,15 @@ int hvf_arch_init_vcpu(CPUState *cpu)
 
 bool hvf_arch_cpu_realize(CPUState *cs, Error **errp)
 {
+    ARMCPU *cpu = ARM_CPU(cs);
+
+    /*
+     * We must set the counter frequency HVF will be using
+     * early, before arm_cpu_realizefn initializes the timers
+     * with it.
+     */
+    cpu->gt_cntfrq_hz = get_cntfrq_el0();
+
     return true;
 }
 
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 19/23] target/arm: Only allow disabling NEON when using TCG
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (17 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 18/23] target/arm/hvf: Really set Generic Timer counter frequency Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 20/23] accel/hvf: Introduce hvf_arch_cpu_synchronize_[pre/post]exec() hooks Philippe Mathieu-Daudé
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Only allow disabling NEON when using TCG.

This avoids confusing user experience:

  $ qemu-system-aarch64 -M virt -accel hvf \
                        -cpu host,neon=off,vfp=off,vfp-d32=off
  qemu-system-aarch64: AArch64 CPUs must have both VFP and Neon or neither

  $ qemu-system-aarch64 -M virt -accel hvf \
                        -cpu host,neon=off,vfp=off,vfp-d32=off
  qemu-system-aarch64: ARM CPUs must have both VFP-D32 and Neon or neither

  $ qemu-system-aarch64 -M virt -accel hvf \
                        -cpu host,neon=off,vfp=off,vfp-d32=off
  qemu-system-aarch64: can't apply global host-arm-cpu.vfp-d32=off: Property 'host-arm-cpu.vfp-d32' not found

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/cpu.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index b392374df98..eaf76532eca 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1460,7 +1460,7 @@ static void arm_cpu_post_init(Object *obj)
 
     if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) {
         cpu->has_neon = true;
-        if (!kvm_enabled()) {
+        if (tcg_enabled() || qtest_enabled()) {
             qdev_property_add_static(DEVICE(obj), &arm_cpu_has_neon_property);
         }
     }
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 20/23] accel/hvf: Introduce hvf_arch_cpu_synchronize_[pre/post]exec() hooks
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (18 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 19/23] target/arm: Only allow disabling NEON when using TCG Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 21/23] target/i386/hvf: Flush vCPU registers once before vcpu_exec() loop Philippe Mathieu-Daudé
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/system/hvf_int.h  | 4 ++++
 accel/hvf/hvf-accel-ops.c | 2 ++
 target/arm/hvf/hvf.c      | 8 ++++++++
 target/i386/hvf/hvf.c     | 8 ++++++++
 4 files changed, 22 insertions(+)

diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index 96790b49386..3120a4593a4 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -71,6 +71,10 @@ int hvf_arch_put_registers(CPUState *);
 int hvf_arch_get_registers(CPUState *);
 /* Must be called by the owning thread */
 void hvf_arch_update_guest_debug(CPUState *cpu);
+/* Must be called by the owning thread */
+void hvf_arch_cpu_synchronize_pre_exec(CPUState *cpu);
+/* Must be called by the owning thread */
+void hvf_arch_cpu_synchronize_post_exec(CPUState *cpu);
 
 void hvf_protect_clean_range(hwaddr addr, size_t size);
 void hvf_unprotect_dirty_range(hwaddr addr, size_t size);
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index 02c5d01670d..56ff259a14d 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -177,10 +177,12 @@ static void *hvf_cpu_thread_fn(void *arg)
     do {
         qemu_process_cpu_events(cpu);
         if (cpu_can_run(cpu)) {
+            hvf_arch_cpu_synchronize_pre_exec(cpu);
             r = hvf_arch_vcpu_exec(cpu);
             if (r == EXCP_DEBUG) {
                 cpu_handle_guest_debug(cpu);
             }
+            hvf_arch_cpu_synchronize_post_exec(cpu);
         }
     } while (!cpu->unplug || cpu_can_run(cpu));
 
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index e1113e3d6ca..8d0a528dceb 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -2017,6 +2017,14 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
     return ret;
 }
 
+void hvf_arch_cpu_synchronize_pre_exec(CPUState *cpu)
+{
+}
+
+void hvf_arch_cpu_synchronize_post_exec(CPUState *cpu)
+{
+}
+
 int hvf_arch_vcpu_exec(CPUState *cpu)
 {
     int ret;
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 1b189efb4c7..5134f302c08 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -729,6 +729,14 @@ void hvf_simulate_wrmsr(CPUState *cs)
     printf("write msr %llx\n", RCX(cs));*/
 }
 
+void hvf_arch_cpu_synchronize_pre_exec(CPUState *cpu)
+{
+}
+
+void hvf_arch_cpu_synchronize_post_exec(CPUState *cpu)
+{
+}
+
 static int hvf_handle_vmexit(CPUState *cpu)
 {
     X86CPU *x86_cpu = env_archcpu(cpu_env(cpu));
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 21/23] target/i386/hvf: Flush vCPU registers once before vcpu_exec() loop
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (19 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 20/23] accel/hvf: Introduce hvf_arch_cpu_synchronize_[pre/post]exec() hooks Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 22/23] target/arm/hvf: " Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 23/23] accel/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0 Philippe Mathieu-Daudé
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/i386/hvf/hvf.c | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 5134f302c08..51b3d392879 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -731,6 +731,10 @@ void hvf_simulate_wrmsr(CPUState *cs)
 
 void hvf_arch_cpu_synchronize_pre_exec(CPUState *cpu)
 {
+    if (cpu->vcpu_dirty) {
+        hvf_arch_put_registers(cpu);
+        cpu->vcpu_dirty = false;
+    }
 }
 
 void hvf_arch_cpu_synchronize_post_exec(CPUState *cpu)
@@ -990,11 +994,6 @@ int hvf_arch_vcpu_exec(CPUState *cpu)
     }
 
     do {
-        if (cpu->vcpu_dirty) {
-            hvf_arch_put_registers(cpu);
-            cpu->vcpu_dirty = false;
-        }
-
         if (hvf_inject_interrupts(cpu)) {
             return EXCP_INTERRUPT;
         }
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 22/23] target/arm/hvf: Flush vCPU registers once before vcpu_exec() loop
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (20 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 21/23] target/i386/hvf: Flush vCPU registers once before vcpu_exec() loop Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 10:10 ` [PATCH v4 23/23] accel/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0 Philippe Mathieu-Daudé
  22 siblings, 0 replies; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/arm/hvf/hvf.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 8d0a528dceb..268a0bcd8ea 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -2019,6 +2019,7 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
 
 void hvf_arch_cpu_synchronize_pre_exec(CPUState *cpu)
 {
+    flush_cpu_state(cpu);
 }
 
 void hvf_arch_cpu_synchronize_post_exec(CPUState *cpu)
@@ -2034,8 +2035,6 @@ int hvf_arch_vcpu_exec(CPUState *cpu)
         return EXCP_HLT;
     }
 
-    flush_cpu_state(cpu);
-
     do {
         if (!(cpu->singlestep_enabled & SSTEP_NOIRQ) &&
             hvf_inject_interrupts(cpu)) {
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [PATCH v4 23/23] accel/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0
  2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
                   ` (21 preceding siblings ...)
  2025-11-03 10:10 ` [PATCH v4 22/23] target/arm/hvf: " Philippe Mathieu-Daudé
@ 2025-11-03 10:10 ` Philippe Mathieu-Daudé
  2025-11-03 12:45   ` Akihiko Odaki
  22 siblings, 1 reply; 27+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-03 10:10 UTC (permalink / raw)
  To: qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Philippe Mathieu-Daudé,
	Richard Henderson, Akihiko Odaki, Peter Collingbourne,
	Cameron Esfahani, Mads Ynddal, Mohamed Mediouni

Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/arm/hvf/hvf.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 268a0bcd8ea..60378075882 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -200,6 +200,9 @@ void hvf_arm_init_debug(void)
 #define SYSREG_PMCEID0_EL0    SYSREG(3, 3, 9, 12, 6)
 #define SYSREG_PMCEID1_EL0    SYSREG(3, 3, 9, 12, 7)
 #define SYSREG_PMCCNTR_EL0    SYSREG(3, 3, 9, 13, 0)
+
+#define SYSREG_CNTV_CTL_EL0   SYSREG(3, 3, 14, 3, 1)
+#define SYSREG_CNTV_CVAL_EL0  SYSREG(3, 3, 14, 3, 2)
 #define SYSREG_PMCCFILTR_EL0  SYSREG(3, 3, 14, 15, 7)
 
 #define SYSREG_ICC_AP0R0_EL1     SYSREG(3, 0, 12, 8, 4)
@@ -2017,13 +2020,49 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
     return ret;
 }
 
+static void hvf_sync_vtimer_pre_exec(CPUState *cpu)
+{
+    hv_return_t r;
+    uint64_t val;
+    bool b;
+
+    b = hvf_sysreg_read_cp(cpu, "VTimer", SYSREG_CNTV_CVAL_EL0, &val);
+    assert(b);
+    r = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, val);
+    assert_hvf_ok(r);
+
+    b = hvf_sysreg_read_cp(cpu, "VTimer", SYSREG_CNTV_CTL_EL0, &val);
+    assert(b);
+    r = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, val);
+    assert_hvf_ok(r);
+}
+
+static void hvf_sync_vtimer_post_exec(CPUState *cpu)
+{
+    hv_return_t r;
+    uint64_t val;
+    bool b;
+
+    r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, &val);
+    assert_hvf_ok(r);
+    b = hvf_sysreg_write_cp(cpu, "VTimer", SYSREG_CNTV_CVAL_EL0, val);
+    assert(b);
+
+    r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, &val);
+    assert_hvf_ok(r);
+    b = hvf_sysreg_write_cp(cpu, "VTimer", SYSREG_CNTV_CTL_EL0, val);
+    assert(b);
+}
+
 void hvf_arch_cpu_synchronize_pre_exec(CPUState *cpu)
 {
+    hvf_sync_vtimer_pre_exec(cpu);
     flush_cpu_state(cpu);
 }
 
 void hvf_arch_cpu_synchronize_post_exec(CPUState *cpu)
 {
+    hvf_sync_vtimer_post_exec(cpu);
 }
 
 int hvf_arch_vcpu_exec(CPUState *cpu)
-- 
2.51.0



^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [PATCH v4 08/23] accel/hvf: Simplify hvf_set_phys_mem
  2025-11-03 10:10 ` [PATCH v4 08/23] accel/hvf: Simplify hvf_set_phys_mem Philippe Mathieu-Daudé
@ 2025-11-03 11:59   ` Akihiko Odaki
  0 siblings, 0 replies; 27+ messages in thread
From: Akihiko Odaki @ 2025-11-03 11:59 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Richard Henderson,
	Peter Collingbourne, Cameron Esfahani, Mads Ynddal,
	Mohamed Mediouni

On 2025/11/03 19:10, Philippe Mathieu-Daudé wrote:
> From: Richard Henderson <richard.henderson@linaro.org>
> 
> All of the complicated parts of updating the address space
> are handled by address_space_update_topology_pass.
> Do not create or use hvf_slot structures.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   accel/hvf/hvf-all.c | 111 +++++++-------------------------------------
>   1 file changed, 17 insertions(+), 94 deletions(-)
> 
> diff --git a/accel/hvf/hvf-all.c b/accel/hvf/hvf-all.c
> index f203a6251f0..76b8d4d4068 100644
> --- a/accel/hvf/hvf-all.c
> +++ b/accel/hvf/hvf-all.c
> @@ -87,45 +87,16 @@ void hvf_unprotect_dirty_range(hwaddr addr, size_t size)
>                        HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC);
>   }
>   
> -static int do_hvf_set_memory(hvf_slot *slot, hv_memory_flags_t flags)
> -{
> -    struct mac_slot *macslot;
> -    hv_return_t ret;
> -
> -    macslot = &mac_slots[slot->slot_id];
> -
> -    if (macslot->present) {
> -        if (macslot->size != slot->size) {
> -            macslot->present = 0;
> -            trace_hvf_vm_unmap(macslot->gpa_start, macslot->size);
> -            ret = hv_vm_unmap(macslot->gpa_start, macslot->size);
> -            assert_hvf_ok(ret);
> -        }
> -    }
> -
> -    if (!slot->size) {
> -        return 0;
> -    }
> -
> -    macslot->present = 1;
> -    macslot->gpa_start = slot->start;
> -    macslot->size = slot->size;
> -    trace_hvf_vm_map(slot->start, slot->size, slot->mem, flags,
> -                     flags & HV_MEMORY_READ ?  'R' : '-',
> -                     flags & HV_MEMORY_WRITE ? 'W' : '-',
> -                     flags & HV_MEMORY_EXEC ?  'X' : '-');
> -    ret = hv_vm_map(slot->mem, slot->start, slot->size, flags);
> -    assert_hvf_ok(ret);
> -    return 0;
> -}
> -
>   static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
>   {
> -    hvf_slot *mem;
>       MemoryRegion *area = section->mr;
>       bool writable = !area->readonly && !area->rom_device;
>       hv_memory_flags_t flags;
>       uint64_t page_size = qemu_real_host_page_size();
> +    uint64_t gva = section->offset_within_address_space;
> +    uint64_t size = int128_get64(section->size);
> +    hv_return_t ret;
> +    void *mem;
>   
>       if (!memory_region_is_ram(area)) {
>           if (writable) {
> @@ -139,69 +110,28 @@ static void hvf_set_phys_mem(MemoryRegionSection *section, bool add)
>           }
>       }
>   
> -    if (!QEMU_IS_ALIGNED(int128_get64(section->size), page_size) ||
> -        !QEMU_IS_ALIGNED(section->offset_within_address_space, page_size)) {
> +    if (!QEMU_IS_ALIGNED(size, page_size) ||
> +        !QEMU_IS_ALIGNED(gva, page_size)) {
>           /* Not page aligned, so we can not map as RAM */
>           add = false;
>       }
>   
> -    mem = hvf_find_overlap_slot(
> -            section->offset_within_address_space,
> -            int128_get64(section->size));
> -
> -    if (mem && add) {
> -        if (mem->size == int128_get64(section->size) &&
> -            mem->start == section->offset_within_address_space &&
> -            mem->mem == (memory_region_get_ram_ptr(area) +
> -            section->offset_within_region)) {
> -            return; /* Same region was attempted to register, go away. */
> -        }
> -    }
> -
> -    /* Region needs to be reset. set the size to 0 and remap it. */
> -    if (mem) {
> -        mem->size = 0;
> -        if (do_hvf_set_memory(mem, 0)) {
> -            error_report("Failed to reset overlapping slot");
> -            abort();
> -        }
> -    }
> -
>       if (!add) {
> +        trace_hvf_vm_unmap(gva, size);
> +        ret = hv_vm_unmap(gva, size);

I think you meant gpa.

> +        assert_hvf_ok(ret);
>           return;
>       }
>   
> -    if (area->readonly ||
> -        (!memory_region_is_ram(area) && memory_region_is_romd(area))) {
> -        flags = HV_MEMORY_READ | HV_MEMORY_EXEC;
> -    } else {
> -        flags = HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC;
> -    }
> +    flags = HV_MEMORY_READ | HV_MEMORY_EXEC | (writable ? HV_MEMORY_WRITE : 0);
> +    mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
>   
> -    /* Now make a new slot. */
> -    int x;
> -
> -    for (x = 0; x < hvf_state->num_slots; ++x) {
> -        mem = &hvf_state->slots[x];
> -        if (!mem->size) {
> -            break;
> -        }
> -    }
> -
> -    if (x == hvf_state->num_slots) {
> -        error_report("No free slots");
> -        abort();
> -    }
> -
> -    mem->size = int128_get64(section->size);
> -    mem->mem = memory_region_get_ram_ptr(area) + section->offset_within_region;
> -    mem->start = section->offset_within_address_space;
> -    mem->region = area;
> -
> -    if (do_hvf_set_memory(mem, flags)) {
> -        error_report("Error registering new memory slot");
> -        abort();
> -    }
> +    trace_hvf_vm_map(gva, size, mem, flags,
> +                     flags & HV_MEMORY_READ ?  'R' : '-',
> +                     flags & HV_MEMORY_WRITE ? 'W' : '-',
> +                     flags & HV_MEMORY_EXEC ?  'X' : '-');
> +    ret = hv_vm_map(mem, gva, size, flags);
> +    assert_hvf_ok(ret);
>   }
>   
>   static void hvf_log_start(MemoryListener *listener,
> @@ -260,7 +190,6 @@ static MemoryListener hvf_memory_listener = {
>   
>   static int hvf_accel_init(AccelState *as, MachineState *ms)
>   {
> -    int x;
>       hv_return_t ret;
>       HVFState *s = HVF_STATE(as);
>       int pa_range = 36;
> @@ -281,12 +210,6 @@ static int hvf_accel_init(AccelState *as, MachineState *ms)
>       }
>       assert_hvf_ok(ret);
>   
> -    s->num_slots = ARRAY_SIZE(s->slots);
> -    for (x = 0; x < s->num_slots; ++x) {
> -        s->slots[x].size = 0;
> -        s->slots[x].slot_id = x;
> -    }
> -
>       QTAILQ_INIT(&s->hvf_sw_breakpoints);
>   
>       hvf_state = s;



^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v4 13/23] accel/hvf: Implement WFI without using pselect()
  2025-11-03 10:10 ` [PATCH v4 13/23] accel/hvf: Implement WFI without using pselect() Philippe Mathieu-Daudé
@ 2025-11-03 12:17   ` Akihiko Odaki
  0 siblings, 0 replies; 27+ messages in thread
From: Akihiko Odaki @ 2025-11-03 12:17 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Richard Henderson,
	Peter Collingbourne, Cameron Esfahani, Mads Ynddal,
	Mohamed Mediouni

On 2025/11/03 19:10, Philippe Mathieu-Daudé wrote:
> Return to the main loop where we'll be waken again.
> This avoid a tricky race with signals introduced in
> commit 219c101fa7f ("Add HVF WFI handler").
> 
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v4 23/23] accel/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0
  2025-11-03 10:10 ` [PATCH v4 23/23] accel/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0 Philippe Mathieu-Daudé
@ 2025-11-03 12:45   ` Akihiko Odaki
  0 siblings, 0 replies; 27+ messages in thread
From: Akihiko Odaki @ 2025-11-03 12:45 UTC (permalink / raw)
  To: Philippe Mathieu-Daudé, qemu-devel
  Cc: Roman Bolshakov, Alexander Graf, Phil Dennis-Jordan, qemu-arm,
	Paolo Bonzini, Peter Maydell, Richard Henderson,
	Peter Collingbourne, Cameron Esfahani, Mads Ynddal,
	Mohamed Mediouni

On 2025/11/03 19:10, Philippe Mathieu-Daudé wrote:
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> ---
>   target/arm/hvf/hvf.c | 39 +++++++++++++++++++++++++++++++++++++++
>   1 file changed, 39 insertions(+)
> 
> diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
> index 268a0bcd8ea..60378075882 100644
> --- a/target/arm/hvf/hvf.c
> +++ b/target/arm/hvf/hvf.c
> @@ -200,6 +200,9 @@ void hvf_arm_init_debug(void)
>   #define SYSREG_PMCEID0_EL0    SYSREG(3, 3, 9, 12, 6)
>   #define SYSREG_PMCEID1_EL0    SYSREG(3, 3, 9, 12, 7)
>   #define SYSREG_PMCCNTR_EL0    SYSREG(3, 3, 9, 13, 0)
> +
> +#define SYSREG_CNTV_CTL_EL0   SYSREG(3, 3, 14, 3, 1)
> +#define SYSREG_CNTV_CVAL_EL0  SYSREG(3, 3, 14, 3, 2)
>   #define SYSREG_PMCCFILTR_EL0  SYSREG(3, 3, 14, 15, 7)
>   
>   #define SYSREG_ICC_AP0R0_EL1     SYSREG(3, 0, 12, 8, 4)
> @@ -2017,13 +2020,49 @@ static int hvf_handle_vmexit(CPUState *cpu, hv_vcpu_exit_t *exit)
>       return ret;
>   }
>   
> +static void hvf_sync_vtimer_pre_exec(CPUState *cpu)
> +{
> +    hv_return_t r;
> +    uint64_t val;
> +    bool b;
> +
> +    b = hvf_sysreg_read_cp(cpu, "VTimer", SYSREG_CNTV_CVAL_EL0, &val);
> +    assert(b);
> +    r = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, val);
> +    assert_hvf_ok(r);
> +
> +    b = hvf_sysreg_read_cp(cpu, "VTimer", SYSREG_CNTV_CTL_EL0, &val);
> +    assert(b);
> +    r = hv_vcpu_set_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, val);
> +    assert_hvf_ok(r);
> +}
> +
> +static void hvf_sync_vtimer_post_exec(CPUState *cpu)
> +{
> +    hv_return_t r;
> +    uint64_t val;
> +    bool b;
> +
> +    r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CVAL_EL0, &val);
> +    assert_hvf_ok(r);
> +    b = hvf_sysreg_write_cp(cpu, "VTimer", SYSREG_CNTV_CVAL_EL0, val);
> +    assert(b);
> +
> +    r = hv_vcpu_get_sys_reg(cpu->accel->fd, HV_SYS_REG_CNTV_CTL_EL0, &val);
> +    assert_hvf_ok(r);
> +    b = hvf_sysreg_write_cp(cpu, "VTimer", SYSREG_CNTV_CTL_EL0, val);
> +    assert(b);
> +}
> +
>   void hvf_arch_cpu_synchronize_pre_exec(CPUState *cpu)
>   {
> +    hvf_sync_vtimer_pre_exec(cpu);

Perhaps this should be called from hvf_put_registers(). It will gate the 
logic behind the vcpu_dirty flag, and, after all, hvf_put_registers() is 
a function for setting registers like what hvf_sync_vtimer_pre_exec() sets.

>       flush_cpu_state(cpu);
>   }
>   
>   void hvf_arch_cpu_synchronize_post_exec(CPUState *cpu)
>   {
> +    hvf_sync_vtimer_post_exec(cpu);
>   }
>   
>   int hvf_arch_vcpu_exec(CPUState *cpu)



^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2025-11-03 12:47 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-03 10:10 [PATCH v4 00/23] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 01/23] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 02/23] target/i386/hvf: Use host page alignment in ept_emulation_fault() Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 03/23] accel/hvf: Enforce host alignment in hv_vm_protect() Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 04/23] target/i386/hvf: Use hvf_unprotect_dirty_range Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 05/23] target/i386/hvf: Use address_space_translate in ept_emulation_fault Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 06/23] accel/hvf: Simplify hvf_log_* Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 07/23] accel/hvf: Move hvf_log_sync to hvf_log_clear Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 08/23] accel/hvf: Simplify hvf_set_phys_mem Philippe Mathieu-Daudé
2025-11-03 11:59   ` Akihiko Odaki
2025-11-03 10:10 ` [PATCH v4 09/23] accel/hvf: Drop hvf_slot and hvf_find_overlap_slot Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 10/23] accel/hvf: Remove mac_slots Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 11/23] target/arm/hvf: Implement dirty page tracking Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 12/23] accel/hvf: Skip WFI if CPU has work to do Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 13/23] accel/hvf: Implement WFI without using pselect() Philippe Mathieu-Daudé
2025-11-03 12:17   ` Akihiko Odaki
2025-11-03 10:10 ` [PATCH v4 14/23] accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 15/23] accel: Introduce AccelOpsClass::cpu_target_realize() hook Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 16/23] accel/hvf: Add hvf_arch_cpu_realize() stubs Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 17/23] target/arm: Create GTimers *after* features finalized / accel realized Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 18/23] target/arm/hvf: Really set Generic Timer counter frequency Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 19/23] target/arm: Only allow disabling NEON when using TCG Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 20/23] accel/hvf: Introduce hvf_arch_cpu_synchronize_[pre/post]exec() hooks Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 21/23] target/i386/hvf: Flush vCPU registers once before vcpu_exec() loop Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 22/23] target/arm/hvf: " Philippe Mathieu-Daudé
2025-11-03 10:10 ` [PATCH v4 23/23] accel/hvf: Sync CNTV_CTL_EL0 & CNTV_CVAL_EL0 Philippe Mathieu-Daudé
2025-11-03 12:45   ` Akihiko Odaki

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).