On 8/15/25 18:53, ~myrslint wrote:
From: myrslint <qemu.haziness...@passinbox.com>
Most Intel CPUs in current use have self-snoop. The few added lines of
code also check for availability of the quirk disablement option so if
some CPU does not have this feature no change of behavior will occur.
Signed-off-by: Myrsky Lintu <qemu.haziness...@passinbox.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2943
---
target/i386/kvm/kvm.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 369626f8c8..1102866a89 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -16,6 +16,7 @@
#include "qapi/qapi-events-run-state.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
+#include <asm-x86/kvm.h>
#include <math.h>
#include <sys/ioctl.h>
#include <sys/utsname.h>
@@ -3367,6 +3368,21 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
}
}
+ /* rationale: most x86 cpus in current use have self-snoop so honoring
+ * guest pat is preferrable.
More precisely, KVM will not expose KVM_X86_QUIRK_IGNORE_GUEST_PAT if
the CPU doesn't have self snoop:
if (!static_cpu_has(X86_FEATURE_SELFSNOOP))
kvm_caps.supported_quirks &= ~KVM_X86_QUIRK_IGNORE_GUEST_PAT;
+ * as well, the bochs video driver bug which
+ * motivated making this a default enabled quirk in kvm was fixed long ago
+ * */
Unfortunately, "less than one year" is not long ago. :( Maybe it can be
done in a machine-init-done notifier, and only if a bochs-drm device has
not been added? You can add a function call
kvm_hack_do_not_enable_guest_pat();
to bochs_display_realize(), and something like this to target/i386/kvm/kvm.c:
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index f9c63c422f0..0b51457e605 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2696,13 +2696,13 @@ static bool kvm_rdmsr_pkg_energy_status(X86CPU *cpu,
return true;
}
-static Notifier smram_machine_done;
+static Notifier kvm_machine_done;
static KVMMemoryListener smram_listener;
static AddressSpace smram_address_space;
static MemoryRegion smram_as_root;
static MemoryRegion smram_as_mem;
-static void register_smram_listener(Notifier *n, void *unused)
+static void register_smram_listener(void)
{
MemoryRegion *smram =
(MemoryRegion *) object_resolve_path("/machine/smram", NULL);
@@ -2730,6 +2730,18 @@ static void register_smram_listener(Notifier *n, void
*unused)
&smram_address_space, 1, "kvm-smram");
}
+static void kvm_machine_done(Notifier *n, void *unused)
+{
+ if (kvm_check_extension(s, KVM_CAP_X86_SMM) &&
+ object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE) &&
+ x86_machine_is_smm_enabled(X86_MACHINE(ms))) {
+ register_smram_listener();
+ }
+ if (!kvm_got_bochs_drm) {
+ disable_ignore_guest_pat_quirk();
+ }
+}
+
static void *kvm_msr_energy_thread(void *data)
{
KVMState *s = data;
@@ -3310,12 +3322,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
return ret;
}
- if (kvm_check_extension(s, KVM_CAP_X86_SMM) &&
- object_dynamic_cast(OBJECT(ms), TYPE_X86_MACHINE) &&
- x86_machine_is_smm_enabled(X86_MACHINE(ms))) {
- smram_machine_done.notify = register_smram_listener;
- qemu_add_machine_init_done_notifier(&smram_machine_done);
- }
+ smram_machine_done.notify = kvm_machine_done;
+ qemu_add_machine_init_done_notifier(&smram_machine_done);
if (enable_cpu_pm) {
ret = kvm_vm_enable_disable_exits(s);
Check out how kvm_arm_supports_user_irq() is done, for an example
of adding KVM hooks/hacks to commoncode.
Paolo