@@ -356,5 +356,6 @@ struct kvm_sync_regs {
#define KVM_QUIRK_LINT0_REENABLED (1 << 0)
#define KVM_QUIRK_CD_NW_CLEARED (1 << 1)
+#define KVM_QUIRK_CD_AS_WB (1 << 2)
#endif /* _ASM_X86_KVM_H */
@@ -1595,7 +1595,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
for (i = 0; i < APIC_LVT_NUM; i++)
apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
apic_update_lvtt(apic);
- if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_LINT0_REENABLED))
+ if (!kvm_check_disabled_quirks(vcpu->kvm, KVM_QUIRK_LINT0_REENABLED))
apic_set_reg(apic, APIC_LVT0,
SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT));
apic_manage_nmi_watchdog(apic, kvm_apic_get_reg(apic, APIC_LVT0));
@@ -1672,7 +1672,7 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
* does not do it - this results in some delay at
* reboot
*/
- if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_CD_NW_CLEARED))
+ if (!kvm_check_disabled_quirks(vcpu->kvm, KVM_QUIRK_CD_NW_CLEARED))
cr0 &= ~(X86_CR0_CD | X86_CR0_NW);
svm->vmcb->save.cr0 = cr0;
mark_dirty(svm->vmcb, VMCB_CR);
@@ -8703,7 +8703,10 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
if (kvm_read_cr0(vcpu) & X86_CR0_CD) {
ipat = VMX_EPT_IPAT_BIT;
- cache = MTRR_TYPE_UNCACHABLE;
+ if (kvm_check_disabled_quirks(vcpu->kvm, KVM_QUIRK_CD_AS_WB))
+ cache = MTRR_TYPE_WRBACK;
+ else
+ cache = MTRR_TYPE_UNCACHABLE;
goto exit;
}
@@ -3575,6 +3575,11 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
return r;
}
+static void kvm_init_disabled_quirks(struct kvm *kvm)
+{
+ kvm->arch.disabled_quirks = KVM_QUIRK_CD_AS_WB;
+}
+
long kvm_arch_vm_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -7422,6 +7427,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
INIT_DELAYED_WORK(&kvm->arch.kvmclock_update_work, kvmclock_update_fn);
INIT_DELAYED_WORK(&kvm->arch.kvmclock_sync_work, kvmclock_sync_fn);
+ kvm_init_disabled_quirks(kvm);
+
return 0;
}
@@ -152,6 +152,11 @@ static inline u64 get_kernel_ns(void)
return ktime_get_boot_ns();
}
+static inline bool kvm_check_disabled_quirks(struct kvm *kvm, u64 quirk)
+{
+ return !!(kvm->arch.disabled_quirks & quirk);
+}
+
void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
void kvm_set_pending_timer(struct kvm_vcpu *vcpu);