From mboxrd@z Thu Jan 1 00:00:00 1970 From: Paolo Bonzini Subject: Re: [PATCH] KVM: x86: Support for disabling quirks Date: Mon, 13 Apr 2015 12:34:28 +0200 Message-ID: <552B9BB4.7090908@redhat.com> References: <1428879221-29996-1-git-send-email-namit@cs.technion.ac.il> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 7bit Cc: kvm@vger.kernel.org, jan.kiszka@siemens.com, bsd@redhat.com, avi.kivity@gmail.com To: Nadav Amit Return-path: Received: from mx1.redhat.com ([209.132.183.28]:60133 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753456AbbDMKeo (ORCPT ); Mon, 13 Apr 2015 06:34:44 -0400 In-Reply-To: <1428879221-29996-1-git-send-email-namit@cs.technion.ac.il> Sender: kvm-owner@vger.kernel.org List-ID: On 13/04/2015 00:53, Nadav Amit wrote: > Introducing KVM_CAP_DISABLE_QUIRKS for disabling x86 quirks that were previous > created in order to overcome QEMU issues. Those issue were mostly result of > invalid VM BIOS. Currently there are two quirks that can be disabled: > > 1. KVM_QUIRK_LINT0_REENABLED - LINT0 was enabled after boot > 2. KVM_QUIRK_CD_NW_CLEARED - CD and NW are cleared after boot > > These two issues are already resolved in recent releases of QEMU, and would > therefore be disabled by QEMU. > > Signed-off-by: Nadav Amit > --- > Documentation/virtual/kvm/api.txt | 3 ++- > arch/x86/include/asm/kvm_host.h | 2 ++ > arch/x86/include/uapi/asm/kvm.h | 3 +++ > arch/x86/kvm/lapic.c | 5 +++-- > arch/x86/kvm/svm.c | 3 ++- > arch/x86/kvm/x86.c | 29 +++++++++++++++++++++++++++++ > include/uapi/linux/kvm.h | 1 + > 7 files changed, 42 insertions(+), 4 deletions(-) > > diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt > index bc9f6fe..3931221 100644 > --- a/Documentation/virtual/kvm/api.txt > +++ b/Documentation/virtual/kvm/api.txt > @@ -959,7 +959,8 @@ documentation when it pops into existence). > 4.37 KVM_ENABLE_CAP > > Capability: KVM_CAP_ENABLE_CAP, KVM_CAP_ENABLE_CAP_VM > -Architectures: ppc, s390 > +Architectures: x86 (only KVM_CAP_ENABLE_CAP_VM), > + mips (only KVM_CAP_ENABLE_CAP), ppc, s390 > Type: vcpu ioctl, vm ioctl (with KVM_CAP_ENABLE_CAP_VM) > Parameters: struct kvm_enable_cap (in) > Returns: 0 on success; -1 on error > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index dea2e7e..f80ad59 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -635,6 +635,8 @@ struct kvm_arch { > #endif > > bool boot_vcpu_runs_old_kvmclock; > + > + u64 disabled_quirks; > }; > > struct kvm_vm_stat { > diff --git a/arch/x86/include/uapi/asm/kvm.h b/arch/x86/include/uapi/asm/kvm.h > index d7dcef5..2fec75e 100644 > --- a/arch/x86/include/uapi/asm/kvm.h > +++ b/arch/x86/include/uapi/asm/kvm.h > @@ -345,4 +345,7 @@ struct kvm_xcrs { > struct kvm_sync_regs { > }; > > +#define KVM_QUIRK_LINT0_REENABLED (1 << 0) > +#define KVM_QUIRK_CD_NW_CLEARED (1 << 1) > + > #endif /* _ASM_X86_KVM_H */ > diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c > index 4a6e58a..fe2d89e 100644 > --- a/arch/x86/kvm/lapic.c > +++ b/arch/x86/kvm/lapic.c > @@ -1577,8 +1577,9 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) > for (i = 0; i < APIC_LVT_NUM; i++) > apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); > apic->lapic_timer.timer_mode = 0; > - apic_set_reg(apic, APIC_LVT0, > - SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); > + if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_LINT0_REENABLED)) > + apic_set_reg(apic, APIC_LVT0, > + SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); > > apic_set_reg(apic, APIC_DFR, 0xffffffffU); > apic_set_spiv(apic, 0xff); > diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c > index ce741b8..46299da 100644 > --- a/arch/x86/kvm/svm.c > +++ b/arch/x86/kvm/svm.c > @@ -1575,7 +1575,8 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) > * does not do it - this results in some delay at > * reboot > */ > - cr0 &= ~(X86_CR0_CD | X86_CR0_NW); > + if (!(vcpu->kvm->arch.disabled_quirks & KVM_QUIRK_CD_NW_CLEARED)) > + cr0 &= ~(X86_CR0_CD | X86_CR0_NW); > svm->vmcb->save.cr0 = cr0; > mark_dirty(svm->vmcb, VMCB_CR); > update_cr0_intercept(svm); > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index b8cb1d0..c3859a6 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -2778,6 +2778,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) > case KVM_CAP_HYPERV_TIME: > case KVM_CAP_IOAPIC_POLARITY_IGNORED: > case KVM_CAP_TSC_DEADLINE_TIMER: > + case KVM_CAP_ENABLE_CAP_VM: > #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT > case KVM_CAP_ASSIGN_DEV_IRQ: > case KVM_CAP_PCI_2_3: > @@ -3825,6 +3826,26 @@ int kvm_vm_ioctl_irq_line(struct kvm *kvm, struct kvm_irq_level *irq_event, > return 0; > } > > +static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, > + struct kvm_enable_cap *cap) > +{ > + int r; > + > + if (cap->flags) > + return -EINVAL; > + > + switch (cap->cap) { > + case KVM_CAP_DISABLE_QUIRKS: > + kvm->arch.disabled_quirks = cap->args[0]; > + r = 0; > + break; > + default: > + r = -EINVAL; > + break; > + } > + return r; > +} > + > long kvm_arch_vm_ioctl(struct file *filp, > unsigned int ioctl, unsigned long arg) > { > @@ -4077,7 +4098,15 @@ long kvm_arch_vm_ioctl(struct file *filp, > r = 0; > break; > } > + case KVM_ENABLE_CAP: { > + struct kvm_enable_cap cap; > > + r = -EFAULT; > + if (copy_from_user(&cap, argp, sizeof(cap))) > + goto out; > + r = kvm_vm_ioctl_enable_cap(kvm, &cap); > + break; > + } > default: > r = kvm_vm_ioctl_assigned_device(kvm, ioctl, arg); > } > diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h > index f574d7b..01c0a8e 100644 > --- a/include/uapi/linux/kvm.h > +++ b/include/uapi/linux/kvm.h > @@ -813,6 +813,7 @@ struct kvm_ppc_smmu_info { > #define KVM_CAP_MIPS_MSA 112 > #define KVM_CAP_S390_INJECT_IRQ 113 > #define KVM_CAP_S390_IRQ_STATE 114 > +#define KVM_CAP_DISABLE_QUIRKS 115 > > #ifdef KVM_CAP_IRQ_ROUTING > > Applied (locally) for 4.2. Paolo