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