* [PATCH v5 01/19] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 02/19] target/i386/hvf: Use host page alignment in ept_emulation_fault() Philippe Mathieu-Daudé
` (18 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 02/19] target/i386/hvf: Use host page alignment in ept_emulation_fault()
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 01/19] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 03/19] accel/hvf: Enforce host alignment in hv_vm_protect() Philippe Mathieu-Daudé
` (17 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 03/19] accel/hvf: Enforce host alignment in hv_vm_protect()
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 01/19] accel/hvf: Create hvf_protect_clean_range, hvf_unprotect_dirty_range Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 02/19] target/i386/hvf: Use host page alignment in ept_emulation_fault() Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 04/19] target/i386/hvf: Use hvf_unprotect_dirty_range Philippe Mathieu-Daudé
` (16 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 04/19] target/i386/hvf: Use hvf_unprotect_dirty_range
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (2 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 03/19] accel/hvf: Enforce host alignment in hv_vm_protect() Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 05/19] target/i386/hvf: Use address_space_translate in ept_emulation_fault Philippe Mathieu-Daudé
` (15 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 05/19] target/i386/hvf: Use address_space_translate in ept_emulation_fault
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (3 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 04/19] target/i386/hvf: Use hvf_unprotect_dirty_range Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 06/19] accel/hvf: Simplify hvf_log_* Philippe Mathieu-Daudé
` (14 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 06/19] accel/hvf: Simplify hvf_log_*
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (4 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 05/19] target/i386/hvf: Use address_space_translate in ept_emulation_fault Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 07/19] accel/hvf: Move hvf_log_sync to hvf_log_clear Philippe Mathieu-Daudé
` (13 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 07/19] accel/hvf: Move hvf_log_sync to hvf_log_clear
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (5 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 06/19] accel/hvf: Simplify hvf_log_* Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 08/19] accel/hvf: Simplify hvf_set_phys_mem Philippe Mathieu-Daudé
` (12 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 08/19] accel/hvf: Simplify hvf_set_phys_mem
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (6 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 07/19] accel/hvf: Move hvf_log_sync to hvf_log_clear Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 09/19] accel/hvf: Drop hvf_slot and hvf_find_overlap_slot Philippe Mathieu-Daudé
` (11 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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>
---
v5: s/gva/gpa/ (Akihiko)
---
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..5781b17fa4e 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 gpa = 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(gpa, 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(gpa, size);
+ ret = hv_vm_unmap(gpa, 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(gpa, size, mem, flags,
+ flags & HV_MEMORY_READ ? 'R' : '-',
+ flags & HV_MEMORY_WRITE ? 'W' : '-',
+ flags & HV_MEMORY_EXEC ? 'X' : '-');
+ ret = hv_vm_map(mem, gpa, 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] 22+ messages in thread* [PATCH v5 09/19] accel/hvf: Drop hvf_slot and hvf_find_overlap_slot
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (7 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 08/19] accel/hvf: Simplify hvf_set_phys_mem Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 10/19] accel/hvf: Remove mac_slots Philippe Mathieu-Daudé
` (10 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 10/19] accel/hvf: Remove mac_slots
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (8 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 09/19] accel/hvf: Drop hvf_slot and hvf_find_overlap_slot Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 11/19] target/arm/hvf: Implement dirty page tracking Philippe Mathieu-Daudé
` (9 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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 5781b17fa4e..ed28e073643 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] 22+ messages in thread* [PATCH v5 11/19] target/arm/hvf: Implement dirty page tracking
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (9 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 10/19] accel/hvf: Remove mac_slots Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 12/19] accel/hvf: Skip WFI if CPU has work to do Philippe Mathieu-Daudé
` (8 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 12/19] accel/hvf: Skip WFI if CPU has work to do
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (10 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 11/19] target/arm/hvf: Implement dirty page tracking Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 13/19] accel/hvf: Implement WFI without using pselect() Philippe Mathieu-Daudé
` (7 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal,
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] 22+ messages in thread* [PATCH v5 13/19] accel/hvf: Implement WFI without using pselect()
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (11 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 12/19] accel/hvf: Skip WFI if CPU has work to do Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 14/19] accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU Philippe Mathieu-Daudé
` (6 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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>
---
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] 22+ messages in thread* [PATCH v5 14/19] accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (12 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 13/19] accel/hvf: Implement WFI without using pselect() Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 15/19] accel: Introduce AccelOpsClass::cpu_target_realize() hook Philippe Mathieu-Daudé
` (5 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 15/19] accel: Introduce AccelOpsClass::cpu_target_realize() hook
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (13 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 14/19] accel/hvf: Have PSCI CPU_SUSPEND halt the vCPU Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 16/19] accel/hvf: Add hvf_arch_cpu_realize() stubs Philippe Mathieu-Daudé
` (4 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 16/19] accel/hvf: Add hvf_arch_cpu_realize() stubs
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (14 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 15/19] accel: Introduce AccelOpsClass::cpu_target_realize() hook Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 17/19] target/arm: Create GTimers *after* features finalized / accel realized Philippe Mathieu-Daudé
` (3 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 17/19] target/arm: Create GTimers *after* features finalized / accel realized
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (15 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 16/19] accel/hvf: Add hvf_arch_cpu_realize() stubs Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 18/19] target/arm/hvf: Really set Generic Timer counter frequency Philippe Mathieu-Daudé
` (2 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 18/19] target/arm/hvf: Really set Generic Timer counter frequency
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (16 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 17/19] target/arm: Create GTimers *after* features finalized / accel realized Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-14 20:04 ` [PATCH v5 19/19] target/arm: Only allow disabling NEON when using TCG Philippe Mathieu-Daudé
2025-11-15 2:22 ` [PATCH v5 00/19] target/arm/hvf: Consolidate Akihiko Odaki
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* [PATCH v5 19/19] target/arm: Only allow disabling NEON when using TCG
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (17 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 18/19] target/arm/hvf: Really set Generic Timer counter frequency Philippe Mathieu-Daudé
@ 2025-11-14 20:04 ` Philippe Mathieu-Daudé
2025-11-15 2:22 ` [PATCH v5 00/19] target/arm/hvf: Consolidate Akihiko Odaki
19 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-14 20:04 UTC (permalink / raw)
To: qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Akihiko Odaki,
Philippe Mathieu-Daudé, Roman Bolshakov, Mads Ynddal
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] 22+ messages in thread* Re: [PATCH v5 00/19] target/arm/hvf: Consolidate
2025-11-14 20:04 [PATCH v5 00/19] target/arm/hvf: Consolidate Philippe Mathieu-Daudé
` (18 preceding siblings ...)
2025-11-14 20:04 ` [PATCH v5 19/19] target/arm: Only allow disabling NEON when using TCG Philippe Mathieu-Daudé
@ 2025-11-15 2:22 ` Akihiko Odaki
2025-11-17 9:25 ` Philippe Mathieu-Daudé
19 siblings, 1 reply; 22+ messages in thread
From: Akihiko Odaki @ 2025-11-15 2:22 UTC (permalink / raw)
To: Philippe Mathieu-Daudé, qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Roman Bolshakov, Mads Ynddal
On 2025/11/15 5:04, Philippe Mathieu-Daudé wrote:
> Missing review: #8
>
> - Patches 1-11 fix migration on HVF
> - Patches 12-14 remove a signal race with WFI
> - Patches 15-18 correct guest timer frequency
>
> Since v4:
> - Rename gva -> gpa in hvf_set_phys_mem (Akihiko)
> - Dropped missing VTimer synchronization patches for 10.2
>
> 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é (10):
> 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
>
> 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 | 22 +---
> accel/accel-common.c | 5 +
> accel/hvf/hvf-accel-ops.c | 19 +---
> accel/hvf/hvf-all.c | 186 ++++++++++------------------------
> target/arm/cpu.c | 67 ++++++------
> target/arm/hvf/hvf.c | 167 +++++++++++++++---------------
> target/i386/hvf/hvf.c | 44 ++++----
> accel/hvf/trace-events | 1 +
> 9 files changed, 208 insertions(+), 304 deletions(-)
>
For the whole series:
Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
^ permalink raw reply [flat|nested] 22+ messages in thread* Re: [PATCH v5 00/19] target/arm/hvf: Consolidate
2025-11-15 2:22 ` [PATCH v5 00/19] target/arm/hvf: Consolidate Akihiko Odaki
@ 2025-11-17 9:25 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 22+ messages in thread
From: Philippe Mathieu-Daudé @ 2025-11-17 9:25 UTC (permalink / raw)
To: Akihiko Odaki, qemu-devel
Cc: Alexander Graf, qemu-arm, Phil Dennis-Jordan, Paolo Bonzini,
Richard Henderson, Peter Collingbourne, Cameron Esfahani,
Mohamed Mediouni, Peter Maydell, Roman Bolshakov, Mads Ynddal
On 15/11/25 03:22, Akihiko Odaki wrote:
> On 2025/11/15 5:04, Philippe Mathieu-Daudé wrote:
>> Philippe Mathieu-Daudé (10):
>> 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
>>
>> 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
> For the whole series:
> Reviewed-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
Thanks Akihiko :)
^ permalink raw reply [flat|nested] 22+ messages in thread