* [PULL 01/19] tests/functional: preserve PYTHONPATH entries
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 02/19] tdx: fix use-after-free in tdx_fetch_cpuid Paolo Bonzini
` (18 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Alyssa Ross
From: Alyssa Ross <hi@alyssa.is>
Otherwise, it's not possible to use a packaged qemu.qmp.
Fixes: 1497377857 ("tests/functional: Prepare the meson build system for the functional tests")
Signed-off-by: Alyssa Ross <hi@alyssa.is>
Link: https://lore.kernel.org/r/20260323084739.1013748-1-hi@alyssa.is
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
tests/functional/meson.build | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 9bec5a07516..8c4d7f70e17 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -76,8 +76,10 @@ foreach speed : ['quick', 'thorough']
endif
test_env.set('QEMU_TEST_QEMU_BINARY', test_emulator.full_path())
test_env.set('QEMU_BUILD_ROOT', meson.project_build_root())
- test_env.set('PYTHONPATH', meson.project_source_root() / 'python:' +
- meson.current_source_dir())
+ test_env.prepend('PYTHONPATH',
+ meson.project_source_root() / 'python',
+ meson.current_source_dir(),
+ separator : ':')
# Define the GDB environment variable if gdb is available.
gdb = get_option('gdb')
@@ -96,8 +98,10 @@ foreach speed : ['quick', 'thorough']
teststamp = testname + '.tstamp'
test_precache_env = environment()
test_precache_env.set('QEMU_TEST_PRECACHE', meson.current_build_dir() / teststamp)
- test_precache_env.set('PYTHONPATH', meson.project_source_root() / 'python:' +
- meson.current_source_dir())
+ test_precache_env.prepend('PYTHONPATH',
+ meson.project_source_root() / 'python',
+ meson.current_source_dir(),
+ separator : ':')
precache = custom_target('func-precache-' + testname,
output: teststamp,
command: [python, testpath],
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 02/19] tdx: fix use-after-free in tdx_fetch_cpuid
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
2026-03-25 16:44 ` [PULL 01/19] tests/functional: preserve PYTHONPATH entries Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 03/19] treewide: replace qemu_hw_version() with QEMU_HW_VERSION Paolo Bonzini
` (17 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Stefan Weil, qemu-stable
This is mostly harmless right now because the "if" is never
hit, but the code as written makes no sense.
Reported-by: Stefan Weil <sw@weilnetz.de>
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/kvm/tdx.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
index 4cae99c281a..4714c9d514e 100644
--- a/target/i386/kvm/tdx.c
+++ b/target/i386/kvm/tdx.c
@@ -848,7 +848,7 @@ static struct kvm_cpuid2 *tdx_fetch_cpuid(CPUState *cpu, int *ret)
r = tdx_vcpu_ioctl(cpu, KVM_TDX_GET_CPUID, 0, fetch_cpuid, &local_err);
if (r == -E2BIG) {
g_free(fetch_cpuid);
- size = fetch_cpuid->nent;
+ size *= 2;
}
} while (r == -E2BIG);
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 03/19] treewide: replace qemu_hw_version() with QEMU_HW_VERSION
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
2026-03-25 16:44 ` [PULL 01/19] tests/functional: preserve PYTHONPATH entries Paolo Bonzini
2026-03-25 16:44 ` [PULL 02/19] tdx: fix use-after-free in tdx_fetch_cpuid Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 04/19] whpx: i386: workaround for Windows 10 support Paolo Bonzini
` (16 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Daniel P. Berrangé
The version is never set on 2.5+ machine types, so qemu_hw_version() and
qemu_set_hw_version() are not needed anymore.
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
include/hw/core/boards.h | 6 ------
include/qemu/hw-version.h | 18 ++++--------------
hw/ide/core.c | 2 +-
hw/scsi/megasas.c | 2 +-
hw/scsi/scsi-bus.c | 2 +-
hw/scsi/scsi-disk.c | 2 +-
system/vl.c | 4 ----
target/s390x/cpu_models.c | 2 +-
util/osdep.c | 12 ------------
9 files changed, 9 insertions(+), 41 deletions(-)
diff --git a/include/hw/core/boards.h b/include/hw/core/boards.h
index f85f31bd90d..b8dad0a1074 100644
--- a/include/hw/core/boards.h
+++ b/include/hw/core/boards.h
@@ -197,11 +197,6 @@ typedef struct {
* used to provide @cpu_index to socket number mapping, allowing
* a machine to group CPU threads belonging to the same socket/package
* Returns: socket number given cpu_index belongs to.
- * @hw_version:
- * Value of QEMU_VERSION when the machine was added to QEMU.
- * Set only by old machines because they need to keep
- * compatibility on code that exposed QEMU_VERSION to guests in
- * the past (and now use qemu_hw_version()).
* @possible_cpu_arch_ids:
* Returns an array of @CPUArchId architecture-dependent CPU IDs
* which includes CPU IDs for present and possible to hotplug CPUs.
@@ -297,7 +292,6 @@ struct MachineClass {
const char *default_display;
const char *default_nic;
GPtrArray *compat_props;
- const char *hw_version;
ram_addr_t default_ram_size;
const char *default_cpu_type;
bool default_kernel_irqchip_split;
diff --git a/include/qemu/hw-version.h b/include/qemu/hw-version.h
index 730a8c904d9..ce318cd8435 100644
--- a/include/qemu/hw-version.h
+++ b/include/qemu/hw-version.h
@@ -1,5 +1,5 @@
/*
- * QEMU "hardware version" machinery
+ * QEMU "hardware version" constant
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
@@ -8,20 +8,10 @@
#define QEMU_HW_VERSION_H
/*
- * Starting on QEMU 2.5, qemu_hw_version() returns "2.5+" by default
- * instead of QEMU_VERSION, so setting hw_version on MachineClass
- * is no longer mandatory.
- *
- * Do NOT change this string, or it will break compatibility on all
- * machine classes that don't set hw_version.
+ * Starting on QEMU 2.5, devices with a version string in their
+ * identification data return "2.5+" instead of QEMU_VERSION. Do
+ * NOT change this string as it is visible to guests.
*/
#define QEMU_HW_VERSION "2.5+"
-/* QEMU "hardware version" setting. Used to replace code that exposed
- * QEMU_VERSION to guests in the past and need to keep compatibility.
- * Do not use qemu_hw_version() in new code.
- */
-void qemu_set_hw_version(const char *);
-const char *qemu_hw_version(void);
-
#endif
diff --git a/hw/ide/core.c b/hw/ide/core.c
index b45abf067b2..d6719dbf31d 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -2660,7 +2660,7 @@ int ide_init_drive(IDEState *s, IDEDevice *dev, IDEDriveKind kind, Error **errp)
if (dev->version) {
pstrcpy(s->version, sizeof(s->version), dev->version);
} else {
- pstrcpy(s->version, sizeof(s->version), qemu_hw_version());
+ pstrcpy(s->version, sizeof(s->version), QEMU_HW_VERSION);
}
ide_reset(s);
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index f62e420a91e..0276886d594 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -782,7 +782,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
memcpy(info.product_name, base_class->product_name, 24);
snprintf(info.serial_number, 32, "%s", s->hba_serial);
- snprintf(info.package_version, 0x60, "%s-QEMU", qemu_hw_version());
+ snprintf(info.package_version, 0x60, "%s-QEMU", QEMU_HW_VERSION);
memcpy(info.image_component[0].name, "APP", 3);
snprintf(info.image_component[0].version, 10, "%s-QEMU",
base_class->product_version);
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 9b8656dd832..1a6b181b9d6 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -703,7 +703,7 @@ static bool scsi_target_emulate_inquiry(SCSITargetReq *r)
r->buf[7] = 0x10 | (r->req.bus->info->tcq ? 0x02 : 0); /* Sync, TCQ. */
memcpy(&r->buf[8], "QEMU ", 8);
memcpy(&r->buf[16], "QEMU TARGET ", 16);
- pstrcpy((char *) &r->buf[32], 4, qemu_hw_version());
+ pstrcpy((char *) &r->buf[32], 4, QEMU_HW_VERSION);
}
return true;
}
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index a5201855352..5ba5b46c4f4 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -2543,7 +2543,7 @@ static void scsi_realize(SCSIDevice *dev, Error **errp)
}
if (!s->version) {
- s->version = g_strdup(qemu_hw_version());
+ s->version = g_strdup(QEMU_HW_VERSION);
}
if (!s->vendor) {
s->vendor = g_strdup("QEMU");
diff --git a/system/vl.c b/system/vl.c
index 38d7b849e0a..246623b3196 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2212,10 +2212,6 @@ static void qemu_create_machine(QDict *qdict)
cpu_exec_init_all();
- if (machine_class->hw_version) {
- qemu_set_hw_version(machine_class->hw_version);
- }
-
/*
* Get the default machine options from the machine if it is not already
* specified either by the configuration file or by the command line.
diff --git a/target/s390x/cpu_models.c b/target/s390x/cpu_models.c
index 954a7a99a9e..0b88868289b 100644
--- a/target/s390x/cpu_models.c
+++ b/target/s390x/cpu_models.c
@@ -955,7 +955,7 @@ static void s390_qemu_cpu_model_class_init(ObjectClass *oc, const void *data)
xcc->is_migration_safe = true;
xcc->desc = g_strdup_printf("QEMU Virtual CPU version %s",
- qemu_hw_version());
+ QEMU_HW_VERSION);
}
static void s390_max_cpu_model_class_init(ObjectClass *oc, const void *data)
diff --git a/util/osdep.c b/util/osdep.c
index 000e7daac8b..4a8b8b5a90f 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -31,8 +31,6 @@
#include "qemu/hw-version.h"
#include "monitor/monitor.h"
-static const char *hw_version = QEMU_HW_VERSION;
-
int socket_set_cork(int fd, int v)
{
#if defined(SOL_TCP) && defined(TCP_CORK)
@@ -533,16 +531,6 @@ ssize_t qemu_send_full(int s, const void *buf, size_t count)
return total;
}
-void qemu_set_hw_version(const char *version)
-{
- hw_version = version;
-}
-
-const char *qemu_hw_version(void)
-{
- return hw_version;
-}
-
#ifdef _WIN32
static void socket_cleanup(void)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 04/19] whpx: i386: workaround for Windows 10 support
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (2 preceding siblings ...)
2026-03-25 16:44 ` [PULL 03/19] treewide: replace qemu_hw_version() with QEMU_HW_VERSION Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 05/19] whpx: i386: enable exceptions VM exit only when needed Paolo Bonzini
` (15 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Windows Server 2022 and later support
WHvCapabilityCodeProcessorPerfmonFeatures and
WHvPartitionPropertyCodeSyntheticProcessorFeaturesBanks.
Windows 10 supports neither of those.
As the QEMU executable doesn't have a manifest, OS version
queries do not return the actual Windows version but 6.2.9200
which corresponds to Windows 8. Windows Server 2022 and Windows
11 still use the 10.0 number, with distinction being the build
number.
As such, use the absence of perf monitoring feature query as
a cutoff to detect if a legacy OS is present.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-2-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 43 ++++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 15 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 4d5d3dbd243..015c0f1dc99 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -1948,6 +1948,7 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
WHV_CAPABILITY_FEATURES features = {0};
WHV_PROCESSOR_FEATURES_BANKS processor_features;
WHV_PROCESSOR_PERFMON_FEATURES perfmon_features;
+ bool is_legacy_os = false;
whpx = &whpx_global;
@@ -2096,21 +2097,29 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
hr = whp_dispatch.WHvGetCapability(
WHvCapabilityCodeProcessorPerfmonFeatures, &perfmon_features,
sizeof(WHV_PROCESSOR_PERFMON_FEATURES), &whpx_cap_size);
+ /*
+ * Relying on this is a crutch to maintain Windows 10 support.
+ *
+ * WHvCapabilityCodeProcessorPerfmonFeatures and
+ * WHvPartitionPropertyCodeSyntheticProcessorFeaturesBanks
+ * are implemented starting from Windows Server 2022 (build 20348).
+ */
if (FAILED(hr)) {
- error_report("WHPX: Failed to get performance monitoring features, hr=%08lx", hr);
- ret = -ENOSPC;
- goto error;
- }
-
- hr = whp_dispatch.WHvSetPartitionProperty(
- whpx->partition,
- WHvPartitionPropertyCodeProcessorPerfmonFeatures,
- &perfmon_features,
- sizeof(WHV_PROCESSOR_PERFMON_FEATURES));
- if (FAILED(hr)) {
- error_report("WHPX: Failed to set performance monitoring features, hr=%08lx", hr);
- ret = -EINVAL;
- goto error;
+ warn_report("WHPX: Failed to get performance "
+ "monitoring features, hr=%08lx", hr);
+ is_legacy_os = true;
+ } else {
+ hr = whp_dispatch.WHvSetPartitionProperty(
+ whpx->partition,
+ WHvPartitionPropertyCodeProcessorPerfmonFeatures,
+ &perfmon_features,
+ sizeof(WHV_PROCESSOR_PERFMON_FEATURES));
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to set performance "
+ "monitoring features, hr=%08lx", hr);
+ ret = -EINVAL;
+ goto error;
+ }
}
/* Enable synthetic processor features */
@@ -2138,7 +2147,7 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
synthetic_features.Bank0.DirectSyntheticTimers = 1;
}
- if (whpx->hyperv_enlightenments_allowed) {
+ if (!is_legacy_os && whpx->hyperv_enlightenments_allowed) {
hr = whp_dispatch.WHvSetPartitionProperty(
whpx->partition,
WHvPartitionPropertyCodeSyntheticProcessorFeaturesBanks,
@@ -2149,6 +2158,10 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
ret = -EINVAL;
goto error;
}
+ } else if (is_legacy_os && whpx->hyperv_enlightenments_required) {
+ error_report("Hyper-V enlightenments not available on legacy Windows");
+ ret = -EINVAL;
+ goto error;
}
/* Register for MSR and CPUID exits */
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 05/19] whpx: i386: enable exceptions VM exit only when needed
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (3 preceding siblings ...)
2026-03-25 16:44 ` [PULL 04/19] whpx: i386: workaround for Windows 10 support Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 06/19] whpx: i386: skip TSC read for MMIO exits Paolo Bonzini
` (14 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
The exceptions VM exit was enabled with an empty bitmask
even when not used.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-3-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 23 ++++++++++++++++++++---
1 file changed, 20 insertions(+), 3 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 015c0f1dc99..8f1835ee95c 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -903,13 +903,31 @@ static void whpx_init_emu(void)
HRESULT whpx_set_exception_exit_bitmap(UINT64 exceptions)
{
struct whpx_state *whpx = &whpx_global;
- WHV_PARTITION_PROPERTY prop = { 0, };
+ WHV_PARTITION_PROPERTY prop;
HRESULT hr;
if (exceptions == whpx->exception_exit_bitmap) {
return S_OK;
}
+ /* Register for MSR and CPUID exits */
+ memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
+ prop.ExtendedVmExits.X64MsrExit = 1;
+ if (exceptions != 0) {
+ prop.ExtendedVmExits.ExceptionExit = 1;
+ }
+
+ hr = whp_dispatch.WHvSetPartitionProperty(
+ whpx->partition,
+ WHvPartitionPropertyCodeExtendedVmExits,
+ &prop,
+ sizeof(WHV_PARTITION_PROPERTY));
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to enable extended VM exits, hr=%08lx", hr);
+ return hr;
+ }
+
+ memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
prop.ExceptionExitBitmap = exceptions;
hr = whp_dispatch.WHvSetPartitionProperty(
@@ -2167,7 +2185,6 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
/* Register for MSR and CPUID exits */
memset(&prop, 0, sizeof(WHV_PARTITION_PROPERTY));
prop.ExtendedVmExits.X64MsrExit = 1;
- prop.ExtendedVmExits.ExceptionExit = 1;
hr = whp_dispatch.WHvSetPartitionProperty(
whpx->partition,
@@ -2175,7 +2192,7 @@ int whpx_accel_init(AccelState *as, MachineState *ms)
&prop,
sizeof(WHV_PARTITION_PROPERTY));
if (FAILED(hr)) {
- error_report("WHPX: Failed to enable MSR & CPUIDexit, hr=%08lx", hr);
+ error_report("WHPX: Failed to enable extended VM exits, hr=%08lx", hr);
ret = -EINVAL;
goto error;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 06/19] whpx: i386: skip TSC read for MMIO exits
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (4 preceding siblings ...)
2026-03-25 16:44 ` [PULL 05/19] whpx: i386: enable exceptions VM exit only when needed Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 07/19] whpx: i386: skip XCRs " Paolo Bonzini
` (13 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
The TSC value isn't needed for vmexit processing.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-4-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 8f1835ee95c..ac03445d9da 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -606,7 +606,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu));
- if (!env->tsc_valid) {
+ if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && !env->tsc_valid) {
whpx_get_tsc(cpu);
env->tsc_valid = !runstate_is_running();
}
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 07/19] whpx: i386: skip XCRs read for MMIO exits
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (5 preceding siblings ...)
2026-03-25 16:44 ` [PULL 06/19] whpx: i386: skip TSC read for MMIO exits Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 08/19] whpx: i386: don't restore segment registers after MMIO handling Paolo Bonzini
` (12 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
The XCR0 value isn't currently needed for vmexit processing.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-5-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index ac03445d9da..c0c7ba91772 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -689,7 +689,9 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
* Extended control registers needs to be handled separately depending
* on whether xsave is supported/enabled or not.
*/
- whpx_get_xcrs(cpu);
+ if (level > WHPX_LEVEL_FAST_RUNTIME_STATE) {
+ whpx_get_xcrs(cpu);
+ }
/* 16 XMM registers */
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 08/19] whpx: i386: don't restore segment registers after MMIO handling
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (6 preceding siblings ...)
2026-03-25 16:44 ` [PULL 07/19] whpx: i386: skip XCRs " Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 09/19] target/i386: emulate: add new callbacks Paolo Bonzini
` (11 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-6-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index c0c7ba91772..69d141e7cce 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -416,19 +416,21 @@ void whpx_set_registers(CPUState *cpu, WHPXStateLevel level)
assert(whpx_register_names[idx] == WHvX64RegisterRflags);
lflags_to_rflags(env);
vcxt.values[idx++].Reg64 = env->eflags;
-
- /* Translate 6+4 segment registers. HV and QEMU order matches */
assert(idx == WHvX64RegisterEs);
- for (i = 0; i < 6; i += 1, idx += 1) {
- vcxt.values[idx].Segment = whpx_seg_q2h(&env->segs[i], v86, r86);
- }
- assert(idx == WHvX64RegisterLdtr);
- /*
- * Skip those registers for synchronisation after MMIO accesses
- * as they're not going to be modified in that case.
- */
if (level > WHPX_LEVEL_FAST_RUNTIME_STATE) {
+
+ /* Translate 6+4 segment registers. HV and QEMU order matches */
+ for (i = 0; i < 6; i += 1, idx += 1) {
+ vcxt.values[idx].Segment = whpx_seg_q2h(&env->segs[i], v86, r86);
+ }
+
+ assert(idx == WHvX64RegisterLdtr);
+ /*
+ * Skip those registers for synchronisation after MMIO accesses
+ * as they're not going to be modified in that case.
+ */
+
vcxt.values[idx++].Segment = whpx_seg_q2h(&env->ldt, 0, 0);
assert(idx == WHvX64RegisterTr);
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 09/19] target/i386: emulate: add new callbacks
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (7 preceding siblings ...)
2026-03-25 16:44 ` [PULL 08/19] whpx: i386: don't restore segment registers after MMIO handling Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 10/19] whpx: i386: add implementation of new x86_emul_ops Paolo Bonzini
` (10 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
On Hyper-V fetching some guest registers is really expensive, so
add a way to query some state from information provided by Hyper-V
to save time on vmexits.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-7-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/emulate/x86_emu.h | 3 +++
target/i386/emulate/x86_helpers.c | 6 ++++++
target/i386/emulate/x86_mmu.c | 3 +++
3 files changed, 12 insertions(+)
diff --git a/target/i386/emulate/x86_emu.h b/target/i386/emulate/x86_emu.h
index 0f284b0c3d1..4ed970bd536 100644
--- a/target/i386/emulate/x86_emu.h
+++ b/target/i386/emulate/x86_emu.h
@@ -32,6 +32,9 @@ struct x86_emul_ops {
int size, int count);
void (*simulate_rdmsr)(CPUState *cs);
void (*simulate_wrmsr)(CPUState *cs);
+ bool (*is_protected_mode)(CPUState *cpu);
+ bool (*is_long_mode)(CPUState *cpu);
+ bool (*is_user_mode)(CPUState *cpu);
};
extern const struct x86_emul_ops *emul_ops;
diff --git a/target/i386/emulate/x86_helpers.c b/target/i386/emulate/x86_helpers.c
index 024f9a2afcf..ebbf40f2b05 100644
--- a/target/i386/emulate/x86_helpers.c
+++ b/target/i386/emulate/x86_helpers.c
@@ -211,6 +211,9 @@ bool x86_is_protected(CPUState *cpu)
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
uint64_t cr0 = env->cr[0];
+ if (emul_ops->is_protected_mode) {
+ return emul_ops->is_protected_mode(cpu);
+ }
return cr0 & CR0_PE_MASK;
}
@@ -234,6 +237,9 @@ bool x86_is_long_mode(CPUState *cpu)
uint64_t efer = env->efer;
uint64_t lme_lma = (MSR_EFER_LME | MSR_EFER_LMA);
+ if (emul_ops->is_long_mode) {
+ return emul_ops->is_long_mode(cpu);
+ }
return ((efer & lme_lma) == lme_lma);
}
diff --git a/target/i386/emulate/x86_mmu.c b/target/i386/emulate/x86_mmu.c
index 4e39bae025e..670939acdba 100644
--- a/target/i386/emulate/x86_mmu.c
+++ b/target/i386/emulate/x86_mmu.c
@@ -49,6 +49,9 @@
static bool is_user(CPUState *cpu)
{
+ if (emul_ops->is_user_mode) {
+ return emul_ops->is_user_mode(cpu);
+ }
return false;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 10/19] whpx: i386: add implementation of new x86_emul_ops
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (8 preceding siblings ...)
2026-03-25 16:44 ` [PULL 09/19] target/i386: emulate: add new callbacks Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 11/19] target/i386: emulate: indirect access to CRs Paolo Bonzini
` (9 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
target/i386/emulate now has new ops for fetching whether the guest is in
protected mode, long mode or user mode without fetching control
registers.
Use those for faster vmexits.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-8-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 69d141e7cce..b97dc9fd514 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -885,10 +885,32 @@ static void read_segment_descriptor(CPUState *cpu,
}
}
+static bool is_protected_mode(CPUState *cpu)
+{
+ AccelCPUState *vcpu = cpu->accel;
+
+ return vcpu->exit_ctx.VpContext.ExecutionState.Cr0Pe == 1;
+}
+
+static bool is_long_mode(CPUState *cpu)
+{
+ AccelCPUState *vcpu = cpu->accel;
+
+ return vcpu->exit_ctx.VpContext.ExecutionState.EferLma == 1;
+}
+
+static bool is_user_mode(CPUState *cpu)
+{
+ AccelCPUState *vcpu = cpu->accel;
+ return vcpu->exit_ctx.VpContext.ExecutionState.Cpl == 3;
+}
static const struct x86_emul_ops whpx_x86_emul_ops = {
.read_segment_descriptor = read_segment_descriptor,
- .handle_io = handle_io
+ .handle_io = handle_io,
+ .is_protected_mode = is_protected_mode,
+ .is_long_mode = is_long_mode,
+ .is_user_mode = is_user_mode
};
static void whpx_init_emu(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 11/19] target/i386: emulate: indirect access to CRs
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (9 preceding siblings ...)
2026-03-25 16:44 ` [PULL 10/19] whpx: i386: add implementation of new x86_emul_ops Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 12/19] whpx: i386: " Paolo Bonzini
` (8 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Prepare to have on-demand fetch of registers from the backend during
faults.
For x86_64 macOS, copy the function there too.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-9-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/emulate/x86_emu.h | 3 +++
target/i386/emulate/x86_helpers.c | 27 ++++++++++++++++-----------
target/i386/emulate/x86_mmu.c | 8 ++------
target/i386/hvf/x86.c | 11 +++++++++++
4 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/target/i386/emulate/x86_emu.h b/target/i386/emulate/x86_emu.h
index 4ed970bd536..a8d4c93098d 100644
--- a/target/i386/emulate/x86_emu.h
+++ b/target/i386/emulate/x86_emu.h
@@ -28,6 +28,7 @@ struct x86_emul_ops {
MMUTranslateResult (*mmu_gva_to_gpa) (CPUState *cpu, target_ulong gva, uint64_t *gpa, MMUTranslateFlags flags);
void (*read_segment_descriptor)(CPUState *cpu, struct x86_segment_descriptor *desc,
enum X86Seg seg);
+ target_ulong (*read_cr) (CPUState *cpu, int cr);
void (*handle_io)(CPUState *cpu, uint16_t port, void *data, int direction,
int size, int count);
void (*simulate_rdmsr)(CPUState *cs);
@@ -45,6 +46,8 @@ void x86_emul_raise_exception(CPUX86State *env, int exception_index, int error_c
target_ulong read_reg(CPUX86State *env, int reg, int size);
void write_reg(CPUX86State *env, int reg, target_ulong val, int size);
+target_ulong x86_read_cr(CPUState *cpu, int cr);
+
target_ulong read_val_from_reg(void *reg_ptr, int size);
void write_val_to_reg(void *reg_ptr, target_ulong val, int size);
bool write_val_ext(CPUX86State *env, struct x86_decode_op *decode, target_ulong val, int size);
diff --git a/target/i386/emulate/x86_helpers.c b/target/i386/emulate/x86_helpers.c
index ebbf40f2b05..c817015ef92 100644
--- a/target/i386/emulate/x86_helpers.c
+++ b/target/i386/emulate/x86_helpers.c
@@ -206,15 +206,26 @@ bool x86_read_call_gate(CPUState *cpu, struct x86_call_gate *idt_desc,
return true;
}
-bool x86_is_protected(CPUState *cpu)
+target_ulong x86_read_cr(CPUState *cpu, int cr)
{
X86CPU *x86_cpu = X86_CPU(cpu);
CPUX86State *env = &x86_cpu->env;
- uint64_t cr0 = env->cr[0];
+
+ if (emul_ops->read_cr) {
+ return emul_ops->read_cr(cpu, cr);
+ }
+ return env->cr[cr];
+}
+
+bool x86_is_protected(CPUState *cpu)
+{
+ uint64_t cr0;
+
if (emul_ops->is_protected_mode) {
return emul_ops->is_protected_mode(cpu);
}
+ cr0 = x86_read_cr(cpu, 0);
return cr0 & CR0_PE_MASK;
}
@@ -245,9 +256,7 @@ bool x86_is_long_mode(CPUState *cpu)
bool x86_is_la57(CPUState *cpu)
{
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- uint64_t is_la57 = env->cr[4] & CR4_LA57_MASK;
+ uint64_t is_la57 = x86_read_cr(cpu, 4) & CR4_LA57_MASK;
return is_la57;
}
@@ -259,18 +268,14 @@ bool x86_is_long64_mode(CPUState *cpu)
bool x86_is_paging_mode(CPUState *cpu)
{
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- uint64_t cr0 = env->cr[0];
+ uint64_t cr0 = x86_read_cr(cpu, 0);
return cr0 & CR0_PG_MASK;
}
bool x86_is_pae_enabled(CPUState *cpu)
{
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- uint64_t cr4 = env->cr[4];
+ uint64_t cr4 = x86_read_cr(cpu, 4);
return cr4 & CR4_PAE_MASK;
}
diff --git a/target/i386/emulate/x86_mmu.c b/target/i386/emulate/x86_mmu.c
index 670939acdba..ba0ebe4268d 100644
--- a/target/i386/emulate/x86_mmu.c
+++ b/target/i386/emulate/x86_mmu.c
@@ -114,8 +114,6 @@ static bool get_pt_entry(CPUState *cpu, struct gpt_translation *pt,
static MMUTranslateResult test_pt_entry(CPUState *cpu, struct gpt_translation *pt,
int level, int *largeness, bool pae, MMUTranslateFlags flags)
{
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
uint64_t pte = pt->pte[level];
if (!pte_present(pte)) {
@@ -130,7 +128,7 @@ static MMUTranslateResult test_pt_entry(CPUState *cpu, struct gpt_translation *p
*largeness = level;
}
- uint32_t cr0 = env->cr[0];
+ uint32_t cr0 = x86_read_cr(cpu, 0);
/* check protection */
if (cr0 & CR0_WP_MASK) {
if (mmu_validate_write(flags) && !pte_write_access(pte)) {
@@ -184,11 +182,9 @@ static inline uint64_t large_page_gpa(struct gpt_translation *pt, bool pae,
static MMUTranslateResult walk_gpt(CPUState *cpu, target_ulong addr, MMUTranslateFlags flags,
struct gpt_translation *pt, bool pae)
{
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
int top_level, level;
int largeness = 0;
- target_ulong cr3 = env->cr[3];
+ target_ulong cr3 = x86_read_cr(cpu, 3);
uint64_t page_mask = pae ? PAE_PTE_PAGE_MASK : LEGACY_PTE_PAGE_MASK;
MMUTranslateResult res;
diff --git a/target/i386/hvf/x86.c b/target/i386/hvf/x86.c
index 7fe710aca3b..bae2f30fa28 100644
--- a/target/i386/hvf/x86.c
+++ b/target/i386/hvf/x86.c
@@ -143,6 +143,17 @@ bool x86_is_la57(CPUState *cpu)
return false;
}
+target_ulong x86_read_cr(CPUState *cpu, int cr)
+{
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+
+ if (emul_ops->read_cr) {
+ return emul_ops->read_cr(cpu, cr);
+ }
+ return env->cr[cr];
+}
+
bool x86_is_long64_mode(CPUState *cpu)
{
struct vmx_segment desc;
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 12/19] whpx: i386: indirect access to CRs
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (10 preceding siblings ...)
2026-03-25 16:44 ` [PULL 11/19] target/i386: emulate: indirect access to CRs Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 13/19] target/i386: emulate: segmentation rework Paolo Bonzini
` (7 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-10-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 32 +++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index b97dc9fd514..71b33a632ac 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -905,12 +905,42 @@ static bool is_user_mode(CPUState *cpu)
return vcpu->exit_ctx.VpContext.ExecutionState.Cpl == 3;
}
+static target_ulong read_cr(CPUState *cpu, int cr)
+{
+ WHV_REGISTER_NAME whv_cr;
+ WHV_REGISTER_VALUE val;
+
+ switch (cr) {
+ case 0:
+ whv_cr = WHvX64RegisterCr0;
+ break;
+ case 2:
+ whv_cr = WHvX64RegisterCr2;
+ break;
+ case 3:
+ whv_cr = WHvX64RegisterCr3;
+ break;
+ case 4:
+ whv_cr = WHvX64RegisterCr4;
+ break;
+ case 8:
+ whv_cr = WHvX64RegisterCr8;
+ break;
+ default:
+ abort();
+ }
+ whpx_get_reg(cpu, whv_cr, &val);
+
+ return val.Reg64;
+}
+
static const struct x86_emul_ops whpx_x86_emul_ops = {
.read_segment_descriptor = read_segment_descriptor,
.handle_io = handle_io,
.is_protected_mode = is_protected_mode,
.is_long_mode = is_long_mode,
- .is_user_mode = is_user_mode
+ .is_user_mode = is_user_mode,
+ .read_cr = read_cr
};
static void whpx_init_emu(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 13/19] target/i386: emulate: segmentation rework
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (11 preceding siblings ...)
2026-03-25 16:44 ` [PULL 12/19] whpx: i386: " Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 14/19] whpx: i386: fetch segments on-demand Paolo Bonzini
` (6 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Make accesses to segments all go through read_segment_descriptor
to be able to fetch segment state on-demand.
Switch away from SegmentCache to the x86_segment_descriptor
that is already used by read_segment_descriptor.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-11-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/emulate/x86_helpers.c | 50 ++++++++++++-------------------
1 file changed, 19 insertions(+), 31 deletions(-)
diff --git a/target/i386/emulate/x86_helpers.c b/target/i386/emulate/x86_helpers.c
index c817015ef92..63bae3582fe 100644
--- a/target/i386/emulate/x86_helpers.c
+++ b/target/i386/emulate/x86_helpers.c
@@ -43,49 +43,37 @@ static CpuMode cpu_mode(CPUState *cpu)
return m;
}
-static bool segment_type_ro(const SegmentCache *seg)
+static bool segment_type_ro(const x86_segment_descriptor desc)
{
- uint32_t type_ = (seg->flags >> DESC_TYPE_SHIFT) & 15;
+ uint32_t type_ = desc.type;
return (type_ & (~RWRX_SEGMENT_TYPE)) == 0;
}
-static bool segment_type_code(const SegmentCache *seg)
+static bool segment_type_code(const x86_segment_descriptor desc)
{
- uint32_t type_ = (seg->flags >> DESC_TYPE_SHIFT) & 15;
+ uint32_t type_ = desc.type;
return (type_ & CODE_SEGMENT_TYPE) != 0;
}
-static bool segment_expands_down(const SegmentCache *seg)
+static bool segment_expands_down(const x86_segment_descriptor desc)
{
- uint32_t type_ = (seg->flags >> DESC_TYPE_SHIFT) & 15;
+ uint32_t type_ = desc.type;
- if (segment_type_code(seg)) {
+ if (segment_type_code(desc)) {
return false;
}
return (type_ & EXPAND_DOWN_SEGMENT_TYPE) != 0;
}
-static uint32_t segment_limit(const SegmentCache *seg)
+static uint8_t segment_db(const x86_segment_descriptor desc)
{
- uint32_t limit = seg->limit;
- uint32_t granularity = (seg->flags & DESC_G_MASK) != 0;
-
- if (granularity != 0) {
- limit = (limit << 12) | 0xFFF;
- }
-
- return limit;
+ return desc.db;
}
-static uint8_t segment_db(const SegmentCache *seg)
+static uint32_t segment_max_limit(const x86_segment_descriptor desc)
{
- return (seg->flags >> DESC_B_SHIFT) & 1;
-}
-
-static uint32_t segment_max_limit(const SegmentCache *seg)
-{
- if (segment_db(seg) != 0) {
+ if (segment_db(desc) != 0) {
return 0xFFFFFFFF;
}
return 0xFFFF;
@@ -96,15 +84,15 @@ static int linearize(CPUState *cpu,
X86Seg seg_idx)
{
enum CpuMode mode;
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- SegmentCache *seg = &env->segs[seg_idx];
- target_ulong base = seg->base;
+ struct x86_segment_descriptor desc;
+ target_ulong base;
target_ulong logical_addr_32b;
uint32_t limit;
/* TODO: the emulator will not pass us "write" indicator yet */
bool write = false;
+ emul_ops->read_segment_descriptor(cpu, &desc, seg_idx);
+ base = x86_segment_base(&desc);
mode = cpu_mode(cpu);
switch (mode) {
@@ -116,21 +104,21 @@ static int linearize(CPUState *cpu,
break;
case PROTECTED_MODE:
case REAL_MODE:
- if (segment_type_ro(seg) && write) {
+ if (segment_type_ro(desc) && write) {
error_report("Cannot write to read-only segment");
return -1;
}
logical_addr_32b = logical_addr & 0xFFFFFFFF;
- limit = segment_limit(seg);
+ limit = x86_segment_limit(&desc);
- if (segment_expands_down(seg)) {
+ if (segment_expands_down(desc)) {
if (logical_addr_32b >= limit) {
error_report("Address exceeds limit (expands down)");
return -1;
}
- limit = segment_max_limit(seg);
+ limit = segment_max_limit(desc);
}
if (logical_addr_32b > limit) {
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 14/19] whpx: i386: fetch segments on-demand
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (12 preceding siblings ...)
2026-03-25 16:44 ` [PULL 13/19] target/i386: emulate: segmentation rework Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 15/19] whpx: i386: fast runtime state reads Paolo Bonzini
` (5 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Instead of save/restore, fetch segments dynamically.
Rely on the fetched state instead of loading from memory.
Or, if available, on the VM exit context.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-12-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 71 +++++++++++++++++++++++++++++++------
1 file changed, 60 insertions(+), 11 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 71b33a632ac..6f232786422 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -868,21 +868,70 @@ static int whpx_handle_portio(CPUState *cpu,
return 0;
}
+static void whpx_segment_to_x86_descriptor(CPUState *cpu, WHV_X64_SEGMENT_REGISTER* reg,
+ struct x86_segment_descriptor *desc)
+{
+ uint32_t limit;
+ desc->g = reg->Granularity;
+
+ /*
+ * Hyper-V can return reg->Granularity == 0
+ * with a higher limit than 0xfffff.
+ *
+ * Detect that case and set desc->g
+ * with shifting the limit properly.
+ */
+ if (!desc->g && reg->Limit <= 0xfffff) {
+ limit = reg->Limit;
+ } else {
+ limit = (reg->Limit >> 12);
+ desc->g = 1;
+ }
+
+ x86_set_segment_limit(desc, limit);
+ x86_set_segment_base(desc, reg->Base);
+
+ desc->type = reg->SegmentType;
+ desc->s = reg->NonSystemSegment;
+ desc->dpl = reg->DescriptorPrivilegeLevel;
+ desc->p = reg->Present;
+ desc->avl = reg->Available;
+ desc->l = reg->Long;
+ desc->db = reg->Default;
+}
+
+static void whpx_read_segment_descriptor(CPUState *cpu, WHV_X64_SEGMENT_REGISTER* reg,
+ X86Seg seg)
+{
+ AccelCPUState *vcpu = cpu->accel;
+ WHV_REGISTER_NAME reg_name = WHvX64RegisterEs + seg;
+ WHV_REGISTER_VALUE val;
+
+ if (seg == R_CS) {
+ *reg = vcpu->exit_ctx.VpContext.Cs;
+ return;
+ }
+ if (vcpu->exit_ctx.ExitReason == WHvRunVpExitReasonX64IoPortAccess) {
+ if (seg == R_DS) {
+ *reg = vcpu->exit_ctx.IoPortAccess.Ds;
+ return;
+ } else if (seg == R_ES) {
+ *reg = vcpu->exit_ctx.IoPortAccess.Es;
+ return;
+ }
+ }
+
+ whpx_get_reg(cpu, reg_name, &val);
+ *reg = val.Segment;
+}
+
static void read_segment_descriptor(CPUState *cpu,
struct x86_segment_descriptor *desc,
enum X86Seg seg_idx)
{
- bool ret;
- X86CPU *x86_cpu = X86_CPU(cpu);
- CPUX86State *env = &x86_cpu->env;
- SegmentCache *seg = &env->segs[seg_idx];
- x86_segment_selector sel = { .sel = seg->selector & 0xFFFF };
-
- ret = x86_read_segment_descriptor(cpu, desc, sel);
- if (ret == false) {
- error_report("failed to read segment descriptor");
- abort();
- }
+ WHV_X64_SEGMENT_REGISTER reg;
+ whpx_read_segment_descriptor(cpu, ®, seg_idx);
+ whpx_segment_to_x86_descriptor(cpu, ®, desc);
}
static bool is_protected_mode(CPUState *cpu)
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 15/19] whpx: i386: fast runtime state reads
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (13 preceding siblings ...)
2026-03-25 16:44 ` [PULL 14/19] whpx: i386: fetch segments on-demand Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 16/19] hw/audio/sb16: validate VMState fields in post_load Paolo Bonzini
` (4 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Now that there's an on-demand interface for fetching CRs
and segments, only query GPRs and query everything else
on-demand for vmexits.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324151323.74473-13-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/whpx/whpx-all.c | 77 +++++++++++++++++++++++++++++++++----
1 file changed, 70 insertions(+), 7 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 6f232786422..acae61e089d 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -156,6 +156,26 @@ static const WHV_REGISTER_NAME whpx_register_names[] = {
*/
};
+static const WHV_REGISTER_NAME whpx_register_names_for_vmexit[] = {
+ /* X64 General purpose registers */
+ WHvX64RegisterRax,
+ WHvX64RegisterRcx,
+ WHvX64RegisterRdx,
+ WHvX64RegisterRbx,
+ WHvX64RegisterRsp,
+ WHvX64RegisterRbp,
+ WHvX64RegisterRsi,
+ WHvX64RegisterRdi,
+ WHvX64RegisterR8,
+ WHvX64RegisterR9,
+ WHvX64RegisterR10,
+ WHvX64RegisterR11,
+ WHvX64RegisterR12,
+ WHvX64RegisterR13,
+ WHvX64RegisterR14,
+ WHvX64RegisterR15,
+};
+
struct whpx_register_set {
WHV_REGISTER_VALUE values[RTL_NUMBER_OF(whpx_register_names)];
};
@@ -593,6 +613,47 @@ static void whpx_get_xcrs(CPUState *cpu)
cpu_env(cpu)->xcr0 = xcr0.Reg64;
}
+static void whpx_get_registers_for_vmexit(CPUState *cpu, WHPXStateLevel level)
+{
+ struct whpx_state *whpx = &whpx_global;
+ AccelCPUState *vcpu = cpu->accel;
+ X86CPU *x86_cpu = X86_CPU(cpu);
+ CPUX86State *env = &x86_cpu->env;
+ struct whpx_register_set vcxt;
+ HRESULT hr;
+ int idx;
+ int idx_next;
+
+ assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu));
+
+ hr = whp_dispatch.WHvGetVirtualProcessorRegisters(
+ whpx->partition, cpu->cpu_index,
+ whpx_register_names_for_vmexit,
+ RTL_NUMBER_OF(whpx_register_names_for_vmexit),
+ &vcxt.values[0]);
+ if (FAILED(hr)) {
+ error_report("WHPX: Failed to get virtual processor context, hr=%08lx",
+ hr);
+ }
+
+ idx = 0;
+
+ /* Indexes for first 16 registers match between HV and QEMU definitions */
+ idx_next = 16;
+ for (idx = 0; idx < CPU_NB_REGS; idx += 1) {
+ env->regs[idx] = vcxt.values[idx].Reg64;
+ }
+ idx = idx_next;
+
+ env->eip = vcpu->exit_ctx.VpContext.Rip;
+ env->eflags = vcpu->exit_ctx.VpContext.Rflags;
+ rflags_to_lflags(env);
+
+ assert(idx == RTL_NUMBER_OF(whpx_register_names_for_vmexit));
+
+ x86_update_hflags(env);
+}
+
void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
{
struct whpx_state *whpx = &whpx_global;
@@ -608,7 +669,11 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
assert(cpu_is_stopped(cpu) || qemu_cpu_is_self(cpu));
- if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && !env->tsc_valid) {
+ if (level == WHPX_LEVEL_FAST_RUNTIME_STATE) {
+ return whpx_get_registers_for_vmexit(cpu, level);
+ }
+
+ if (!env->tsc_valid) {
whpx_get_tsc(cpu);
env->tsc_valid = !runstate_is_running();
}
@@ -623,7 +688,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
hr);
}
- if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && whpx_irqchip_in_kernel()) {
+ if (whpx_irqchip_in_kernel()) {
/*
* Fetch the TPR value from the emulated APIC. It may get overwritten
* below with the value from CR8 returned by
@@ -680,7 +745,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
env->cr[4] = vcxt.values[idx++].Reg64;
assert(whpx_register_names[idx] == WHvX64RegisterCr8);
tpr = vcxt.values[idx++].Reg64;
- if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && tpr != vcpu->tpr) {
+ if (tpr != vcpu->tpr) {
vcpu->tpr = tpr;
cpu_set_apic_tpr(x86_cpu->apic_state, whpx_cr8_to_apic_tpr(tpr));
}
@@ -691,9 +756,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
* Extended control registers needs to be handled separately depending
* on whether xsave is supported/enabled or not.
*/
- if (level > WHPX_LEVEL_FAST_RUNTIME_STATE) {
- whpx_get_xcrs(cpu);
- }
+ whpx_get_xcrs(cpu);
/* 16 XMM registers */
assert(whpx_register_names[idx] == WHvX64RegisterXmm0);
@@ -768,7 +831,7 @@ void whpx_get_registers(CPUState *cpu, WHPXStateLevel level)
assert(idx == RTL_NUMBER_OF(whpx_register_names));
- if (level > WHPX_LEVEL_FAST_RUNTIME_STATE && whpx_irqchip_in_kernel()) {
+ if (whpx_irqchip_in_kernel()) {
whpx_apic_get(x86_cpu->apic_state);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 16/19] hw/audio/sb16: validate VMState fields in post_load
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (14 preceding siblings ...)
2026-03-25 16:44 ` [PULL 15/19] whpx: i386: fast runtime state reads Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 17/19] target/i386: expose AMD GMET feature Paolo Bonzini
` (3 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Jenny Guanni Qu, qemu-stable
From: Jenny Guanni Qu <qguanni@gmail.com>
The SB16 VMState loads in_index and out_data_len as raw INT32
values with no bounds validation. A crafted migration stream or
VM snapshot can set these to values exceeding their respective
buffer sizes (in2_data[10] and out_data[50]), causing heap OOB
write in dsp_write() and heap OOB read in dsp_read().
Add bounds checks in sb16_post_load() to reject invalid values
before they can be used as array indices.
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3326
Reported-by: Jenny Guanni Qu <qguanni@gmail.com>
Signed-off-by: Jenny Guanni Qu <qguanni@gmail.com>
Link: https://lore.kernel.org/r/20260318192918.65481-1-qguanni@gmail.com
Cc: qemu-stable@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/audio/sb16.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 1b5e452a29b..1838d3ef7bd 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1286,6 +1286,13 @@ static int sb16_post_load (void *opaque, int version_id)
{
SB16State *s = opaque;
+
+ if (s->in_index < 0 || s->in_index > (int)sizeof(s->in2_data)) {
+ return -1;
+ }
+ if (s->out_data_len < 0 || s->out_data_len > (int)sizeof(s->out_data)) {
+ return -1;
+ }
if (s->voice) {
audio_be_close_out(s->audio_be, s->voice);
s->voice = NULL;
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 17/19] target/i386: expose AMD GMET feature
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (15 preceding siblings ...)
2026-03-25 16:44 ` [PULL 16/19] hw/audio/sb16: validate VMState fields in post_load Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 18/19] target/i386: emulate: set PG_ERROR_W_MASK as expected Paolo Bonzini
` (2 subsequent siblings)
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel
This is implemented entirely by the hypervisor, so only the bit has to be
exposed.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/cpu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b5e483e8cd2..d02f6f0653e 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -1170,7 +1170,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] = {
"tsc-scale", "vmcb-clean", "flushbyasid", "decodeassists",
NULL, NULL, "pause-filter", NULL,
"pfthreshold", "avic", NULL, "v-vmsave-vmload",
- "vgif", NULL, NULL, NULL,
+ "vgif", "gmet", NULL, NULL,
NULL, NULL, NULL, NULL,
NULL, "vnmi", NULL, NULL,
"svme-addr-chk", NULL, NULL, NULL,
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 18/19] target/i386: emulate: set PG_ERROR_W_MASK as expected
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (16 preceding siblings ...)
2026-03-25 16:44 ` [PULL 17/19] target/i386: expose AMD GMET feature Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:44 ` [PULL 19/19] target/i386: emulate: follow priv_check_exempt Paolo Bonzini
2026-03-25 16:53 ` [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Peter Maydell
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Make setting PG_ERROR_W_MASK no longer dependent on the access
being a priv violation.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324230016.80914-2-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/emulate/x86_mmu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/target/i386/emulate/x86_mmu.c b/target/i386/emulate/x86_mmu.c
index ba0ebe4268d..1aa373f5b38 100644
--- a/target/i386/emulate/x86_mmu.c
+++ b/target/i386/emulate/x86_mmu.c
@@ -248,7 +248,7 @@ static int translate_res_to_error_code(MMUTranslateResult res, bool is_write, bo
if (!(res & MMU_TRANSLATE_PAGE_NOT_MAPPED)) {
error_code |= PG_ERROR_P_MASK;
}
- if (is_write && (res & MMU_TRANSLATE_PRIV_VIOLATION)) {
+ if (is_write) {
error_code |= PG_ERROR_W_MASK;
}
if (res & MMU_TRANSLATE_INVALID_PT_FLAGS) {
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* [PULL 19/19] target/i386: emulate: follow priv_check_exempt
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (17 preceding siblings ...)
2026-03-25 16:44 ` [PULL 18/19] target/i386: emulate: set PG_ERROR_W_MASK as expected Paolo Bonzini
@ 2026-03-25 16:44 ` Paolo Bonzini
2026-03-25 16:53 ` [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Peter Maydell
19 siblings, 0 replies; 22+ messages in thread
From: Paolo Bonzini @ 2026-03-25 16:44 UTC (permalink / raw)
To: qemu-devel; +Cc: Mohamed Mediouni
From: Mohamed Mediouni <mohamed@unpredictable.fr>
Follow priv_check_exempt flag argument for
x86_write_mem_priv/x86_read_mem_priv.
Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr>
Link: https://lore.kernel.org/r/20260324230016.80914-3-mohamed@unpredictable.fr
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/emulate/x86_mmu.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/target/i386/emulate/x86_mmu.c b/target/i386/emulate/x86_mmu.c
index 1aa373f5b38..c69ae96acb7 100644
--- a/target/i386/emulate/x86_mmu.c
+++ b/target/i386/emulate/x86_mmu.c
@@ -263,14 +263,19 @@ static MMUTranslateResult x86_write_mem_ex(CPUState *cpu, void *data, target_ulo
CPUX86State *env = &x86_cpu->env;
MMUTranslateResult translate_res = MMU_TRANSLATE_SUCCESS;
+ MMUTranslateFlags translate_flags = MMU_TRANSLATE_VALIDATE_WRITE;
MemTxResult mem_tx_res;
uint64_t gpa;
+ if (priv_check_exempt) {
+ translate_flags |= MMU_TRANSLATE_PRIV_CHECKS_EXEMPT;
+ }
+
while (bytes > 0) {
/* copy page */
int copy = MIN(bytes, 0x1000 - (gva & 0xfff));
- translate_res = mmu_gva_to_gpa(cpu, gva, &gpa, MMU_TRANSLATE_VALIDATE_WRITE);
+ translate_res = mmu_gva_to_gpa(cpu, gva, &gpa, translate_flags);
if (translate_res) {
int error_code = translate_res_to_error_code(translate_res, true, is_user(cpu));
env->cr[2] = gva;
@@ -311,14 +316,19 @@ static MMUTranslateResult x86_read_mem_ex(CPUState *cpu, void *data, target_ulon
CPUX86State *env = &x86_cpu->env;
MMUTranslateResult translate_res = MMU_TRANSLATE_SUCCESS;
+ MMUTranslateFlags translate_flags = 0;
MemTxResult mem_tx_res;
uint64_t gpa;
+ if (priv_check_exempt) {
+ translate_flags |= MMU_TRANSLATE_PRIV_CHECKS_EXEMPT;
+ }
+
while (bytes > 0) {
/* copy page */
int copy = MIN(bytes, 0x1000 - (gva & 0xfff));
- translate_res = mmu_gva_to_gpa(cpu, gva, &gpa, 0);
+ translate_res = mmu_gva_to_gpa(cpu, gva, &gpa, translate_flags);
if (translate_res) {
int error_code = translate_res_to_error_code(translate_res, false, is_user(cpu));
env->cr[2] = gva;
--
2.53.0
^ permalink raw reply related [flat|nested] 22+ messages in thread* Re: [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc
2026-03-25 16:44 [PULL 00/19] Fixes (including big i386/emulate performance improvement) for 11.0-rc Paolo Bonzini
` (18 preceding siblings ...)
2026-03-25 16:44 ` [PULL 19/19] target/i386: emulate: follow priv_check_exempt Paolo Bonzini
@ 2026-03-25 16:53 ` Peter Maydell
19 siblings, 0 replies; 22+ messages in thread
From: Peter Maydell @ 2026-03-25 16:53 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: qemu-devel
On Wed, 25 Mar 2026 at 16:45, Paolo Bonzini <pbonzini@redhat.com> wrote:
>
> The following changes since commit 8e711856d7639cbffa51405f2cc2366e3d9e3a23:
>
> Merge tag 'hppa-fixes-for-v11-pull-request' of https://github.com/hdeller/qemu-hppa into staging (2026-03-20 10:04:48 +0000)
>
> are available in the Git repository at:
>
> https://gitlab.com/bonzini/qemu.git tags/for-upstream
>
> for you to fetch changes up to dfbc524fdd8932951791e78121be0ddca0529162:
>
> target/i386: emulate: follow priv_check_exempt (2026-03-25 17:43:41 +0100)
>
> ----------------------------------------------------------------
> * tests/functional: preserve PYTHONPATH entries
> * target/i386: show GMET feature
> * target/i386/emulate, whpx/i386: on-demand access to runtime state, MMU fixes
> * tdx: fix use-after-free in tdx_fetch_cpuid
> * treewide: replace qemu_hw_version() with QEMU_HW_VERSION
> * sb16: detect invalid migration stream
>
Hi -- this has conflicts in tests/functional/meson.build --
could you rebase and resend, please?
thanks
-- PMM
^ permalink raw reply [flat|nested] 22+ messages in thread