KVM: i386: Default disable ignore guest PAT quirk
Add a new accelerator option that allows the guest to adjust the PAT. This is already the case for TDX guests and allows using virtio-gpu Venus with RADV or NVIDIA drivers. The quirk is disabled by default. Since this caused problems with Linux's Bochs video device driver, add a knob to leave it enabled, and for now do ont enable it by default. Signed-off-by: Myrsky Lintu <qemu.haziness801@passinbox.com> Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2943 Link: https://lore.kernel.org/r/175527721636.15451.4393515241478547957-1@git.sr.ht [Add property; for now leave it off by default. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
myrslint committed
Aug 15, 2025 at 16:53 UTC
5dacb3b8fab99f8b4ed52b8d0334ff4547a01ab5
3 files changed
+51
-1
accel/kvm/kvm-all.c
+1
@@ -4277,6 +4277,7 @@ static void kvm_accel_instance_init(Object *obj)
4277
s->xen_evtchn_max_pirq = 256;
4278
s->device = NULL;
4279
s->msr_energy.enable = false;
4280
+ s->honor_guest_pat = ON_OFF_AUTO_OFF;
4281
}
4282
4283
/**
include/system/kvm_int.h
+1
@@ -167,6 +167,7 @@ struct KVMState
167
uint16_t xen_gnttab_max_frames;
168
uint16_t xen_evtchn_max_pirq;
169
char *device;
170
+ OnOffAuto honor_guest_pat;
171
};
172
173
void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml,
target/i386/kvm/kvm.c
+49
-1
@@ -3595,8 +3595,30 @@ int kvm_arch_init(MachineState *ms, KVMState *s)
3595
if (first) {
3596
kvm_vmfd_add_change_notifier(&kvm_vmfd_change_notifier);
3597
}
3598
- first = false;
3598
3599
+ /*
3600
+ * Most x86 CPUs in current use have self-snoop, so honoring guest PAT is
3601
+ * preferable. As well, the bochs video driver bug which motivated making
3602
+ * this a default-enabled quirk in KVM was fixed long ago.
3603
+ */
3604
+ if (s->honor_guest_pat != ON_OFF_AUTO_OFF) {
3605
+ ret = kvm_check_extension(s, KVM_CAP_DISABLE_QUIRKS2);
3606
+ if (ret & KVM_X86_QUIRK_IGNORE_GUEST_PAT) {
3607
+ ret = kvm_vm_enable_cap(s, KVM_CAP_DISABLE_QUIRKS2, 0,
3608
+ KVM_X86_QUIRK_IGNORE_GUEST_PAT);
3609
+ if (ret < 0) {
3610
+ error_report("failed to disable KVM_X86_QUIRK_IGNORE_GUEST_PAT");
3611
+ return ret;
3612
+ }
3613
+ } else {
3614
+ if (s->honor_guest_pat == ON_OFF_AUTO_ON) {
3615
+ error_report("KVM does not support disabling ignore-guest-PAT quirk");
3616
+ return -EINVAL;
3617
+ }
3618
+ }
3619
+ }
3620
+
3621
+ first = false;
3622
return 0;
3623
}
3624
@@ -7053,6 +7075,24 @@ static void kvm_arch_set_xen_evtchn_max_pirq(Object *obj, Visitor *v,
7075
s->xen_evtchn_max_pirq = value;
7076
}
7077
7078
+static int kvm_arch_get_honor_guest_pat(Object *obj, Error **errp)
7079
+{
7080
+ KVMState *s = KVM_STATE(obj);
7081
+ return s->honor_guest_pat;
7082
+}
7083
+
7084
+static void kvm_arch_set_honor_guest_pat(Object *obj, int value, Error **errp)
7085
+{
7086
+ KVMState *s = KVM_STATE(obj);
7087
+
7088
+ if (s->fd != -1) {
7089
+ error_setg(errp, "Cannot set properties after the accelerator has been initialized");
7090
+ return;
7091
+ }
7092
+
7093
+ s->honor_guest_pat = value;
7094
+}
7095
+
7096
void kvm_arch_accel_class_init(ObjectClass *oc)
7097
{
7098
object_class_property_add_enum(oc, "notify-vmexit", "NotifyVMexitOption",
@@ -7092,6 +7132,14 @@ void kvm_arch_accel_class_init(ObjectClass *oc)
7132
NULL, NULL);
7133
object_class_property_set_description(oc, "xen-evtchn-max-pirq",
7134
"Maximum number of Xen PIRQs");
7135
+
7136
+ object_class_property_add_enum(oc, "honor-guest-pat", "OnOffAuto",
7137
+ &OnOffAuto_lookup,
7138
+ kvm_arch_get_honor_guest_pat,
7139
+ kvm_arch_set_honor_guest_pat);
7140
+ object_class_property_set_description(oc, "honor-guest-pat",
7141
+ "Disable KVM quirk that ignores guest PAT "
7142
+ "memory type settings (default: auto)");
7143
}
7144
7145
void kvm_set_max_apic_id(uint32_t max_apic_id)