Re: [PATCH] KVM: x86: Support for disabling quirks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




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 <namit@xxxxxxxxxxxxxxxxx>
> ---
>  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
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux