@samitouri / QOSamiQemu / commits / 5dacb3b8fa

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)