Subject: Re: linux-next: manual merge of the kvm tree with Linus' tree

From: Paolo Bonzini <[email-masked]>
Date: Thu, 2 Apr 2020 12:44:43 +0200

On 02/04/20 04:36, Stephen Rothwell wrote:
> Hi all,
> 
> Today's linux-next merge of the kvm tree got a conflict in:
> 
>   arch/x86/kvm/svm/svm.c
> 
> between commits:
> 
>   aaca21007ba1 ("KVM: SVM: Fix the svm vmexit code for WRMSR")
>   2da1ed62d55c ("KVM: SVM: document KVM_MEM_ENCRYPT_OP, let userspace detect if SEV is available")
>   2e2409afe5f0 ("KVM: SVM: Issue WBINVD after deactivating an SEV guest")
> 
> from Linus' tree and commits:
> 
>   83a2c705f002 ("kVM SVM: Move SVM related files to own sub-directory")
>   41f08f0506c0 ("KVM: SVM: Move SEV code to separate file")
> 
> (at least)
> 
> from the kvm tree.
> 
> Its a bit of a pain this code movement appearing during the merge
> window.  Is it really intended for v5.7?

I'll send two separate pull requests to Linus so that he doesn't see the
issues introduced by the code movement.

Paolo

> I fixed it up (see below) and can carry the fix as necessary. This
> is now fixed as far as linux-next is concerned, but any non trivial
> conflicts should be mentioned to your upstream maintainer when your tree
> is submitted for merging.  You may also want to consider cooperating
> with the maintainer of the conflicting tree to minimise any particularly
> complex conflicts.
> 
> diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
> index 621a36702636..2be5bbae3a40 100644
> --- a/arch/x86/kvm/svm/svm.c
> +++ b/arch/x86/kvm/svm/svm.c
> @@ -34,6 +34,7 @@
>  #include <asm/kvm_para.h>
>  #include <asm/irq_remapping.h>
>  #include <asm/spec-ctrl.h>
> +#include <asm/cpu_device_id.h>
>  
>  #include <asm/virtext.h>
>  #include "trace.h"
> @@ -47,7 +48,7 @@ MODULE_LICENSE("GPL");
>  
>  #ifdef MODULE
>  static const struct x86_cpu_id svm_cpu_id[] = {
> -	X86_FEATURE_MATCH(X86_FEATURE_SVM),
> +	X86_MATCH_FEATURE(X86_FEATURE_SVM, NULL),
>  	{}
>  };
>  MODULE_DEVICE_TABLE(x86cpu, svm_cpu_id);
> @@ -3715,7 +3716,8 @@ static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu,
>  	enum exit_fastpath_completion *exit_fastpath)
>  {
>  	if (!is_guest_mode(vcpu) &&
> -		to_svm(vcpu)->vmcb->control.exit_code == EXIT_REASON_MSR_WRITE)
> +	    to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_MSR &&
> +	    to_svm(vcpu)->vmcb->control.exit_info_1)
>  		*exit_fastpath = handle_fastpath_set_msr_irqoff(vcpu);
>  }
> 
> diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> index 3ef57dee48cc..0e3fc311d7da 100644
> --- a/arch/x86/kvm/svm/sev.c
> +++ b/arch/x86/kvm/svm/sev.c
> @@ -920,6 +920,9 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp)
>  	if (!svm_sev_enabled())
>  		return -ENOTTY;
>  
> +	if (!argp)
> +		return 0;
> +
>  	if (copy_from_user(&sev_cmd, argp, sizeof(struct kvm_sev_cmd)))
>  		return -EFAULT;
>  
> @@ -1030,14 +1033,6 @@ find_enc_region(struct kvm *kvm, struct kvm_enc_region *range)
>  static void __unregister_enc_region_locked(struct kvm *kvm,
>  					   struct enc_region *region)
>  {
> -	/*
> -	 * The guest may change the memory encryption attribute from C=0 -> C=1
> -	 * or vice versa for this memory range. Lets make sure caches are
> -	 * flushed to ensure that guest data gets written into memory with
> -	 * correct C-bit.
> -	 */
> -	sev_clflush_pages(region->pages, region->npages);
> -
>  	sev_unpin_memory(kvm, region->pages, region->npages);
>  	list_del(&region->list);
>  	kfree(region);
> @@ -1062,6 +1057,13 @@ int svm_unregister_enc_region(struct kvm *kvm,
>  		goto failed;
>  	}
>  
> +	/*
> +	 * Ensure that all guest tagged cache entries are flushed before
> +	 * releasing the pages back to the system for use. CLFLUSH will
> +	 * not do this, so issue a WBINVD.
> +	 */
> +	wbinvd_on_all_cpus();
> +
>  	__unregister_enc_region_locked(kvm, region);
>  
>  	mutex_unlock(&kvm->lock);
> @@ -1083,6 +1085,13 @@ void sev_vm_destroy(struct kvm *kvm)
>  
>  	mutex_lock(&kvm->lock);
>  
> +	/*
> +	 * Ensure that all guest tagged cache entries are flushed before
> +	 * releasing the pages back to the system for use. CLFLUSH will
> +	 * not do this, so issue a WBINVD.
> +	 */
> +	wbinvd_on_all_cpus();
> +
>  	/*
>  	 * if userspace was terminated before unregistering the memory regions
>  	 * then lets unpin all the registered memory.
>