LKML Archive mirror
 help / color / mirror / Atom feed
From: Ashish Kalra <ashish.kalra@amd.com>
To: Sean Christopherson <seanjc@google.com>
Cc: pbonzini@redhat.com, tglx@linutronix.de, mingo@redhat.com,
	hpa@zytor.com, joro@8bytes.org, bp@suse.de,
	thomas.lendacky@amd.com, x86@kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, srutherford@google.com,
	venu.busireddy@oracle.com, brijesh.singh@amd.com,
	will@kernel.org, maz@kernel.org, qperret@google.com
Subject: Re: [PATCH v11 08/13] KVM: X86: Introduce KVM_HC_PAGE_ENC_STATUS hypercall
Date: Wed, 7 Apr 2021 14:01:01 +0000	[thread overview]
Message-ID: <20210407140044.GA25499@ashkalra_ubuntu_server> (raw)
In-Reply-To: <YGyCxGsC2+GAtJxy@google.com>

On Tue, Apr 06, 2021 at 03:48:20PM +0000, Sean Christopherson wrote:
> On Mon, Apr 05, 2021, Ashish Kalra wrote:
> > From: Ashish Kalra <ashish.kalra@amd.com>
> 
> ...
> 
> > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> > index 3768819693e5..78284ebbbee7 100644
> > --- a/arch/x86/include/asm/kvm_host.h
> > +++ b/arch/x86/include/asm/kvm_host.h
> > @@ -1352,6 +1352,8 @@ struct kvm_x86_ops {
> >  	int (*complete_emulated_msr)(struct kvm_vcpu *vcpu, int err);
> >  
> >  	void (*vcpu_deliver_sipi_vector)(struct kvm_vcpu *vcpu, u8 vector);
> > +	int (*page_enc_status_hc)(struct kvm_vcpu *vcpu, unsigned long gpa,
> > +				  unsigned long sz, unsigned long mode);
> >  };
> >  
> >  struct kvm_x86_nested_ops {
> > diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
> > index c9795a22e502..fb3a315e5827 100644
> > --- a/arch/x86/kvm/svm/sev.c
> > +++ b/arch/x86/kvm/svm/sev.c
> > @@ -1544,6 +1544,67 @@ static int sev_receive_finish(struct kvm *kvm, struct kvm_sev_cmd *argp)
> >  	return ret;
> >  }
> >  
> > +static int sev_complete_userspace_page_enc_status_hc(struct kvm_vcpu *vcpu)
> > +{
> > +	vcpu->run->exit_reason = 0;
> > +	kvm_rax_write(vcpu, vcpu->run->dma_sharing.ret);
> > +	++vcpu->stat.hypercalls;
> > +	return kvm_skip_emulated_instruction(vcpu);
> > +}
> > +
> > +int svm_page_enc_status_hc(struct kvm_vcpu *vcpu, unsigned long gpa,
> > +			   unsigned long npages, unsigned long enc)
> > +{
> > +	kvm_pfn_t pfn_start, pfn_end;
> > +	struct kvm *kvm = vcpu->kvm;
> > +	gfn_t gfn_start, gfn_end;
> > +
> > +	if (!sev_guest(kvm))
> > +		return -EINVAL;
> > +
> > +	if (!npages)
> > +		return 0;
> 
> Parth of me thinks passing a zero size should be an error not a nop.  Either way
> works, just feels a bit weird to allow this to be a nop.
> 
> > +
> > +	gfn_start = gpa_to_gfn(gpa);
> 
> This should check that @gpa is aligned.
> 
> > +	gfn_end = gfn_start + npages;
> > +
> > +	/* out of bound access error check */
> > +	if (gfn_end <= gfn_start)
> > +		return -EINVAL;
> > +
> > +	/* lets make sure that gpa exist in our memslot */
> > +	pfn_start = gfn_to_pfn(kvm, gfn_start);
> > +	pfn_end = gfn_to_pfn(kvm, gfn_end);
> > +
> > +	if (is_error_noslot_pfn(pfn_start) && !is_noslot_pfn(pfn_start)) {
> > +		/*
> > +		 * Allow guest MMIO range(s) to be added
> > +		 * to the shared pages list.
> > +		 */
> > +		return -EINVAL;
> > +	}
> > +
> > +	if (is_error_noslot_pfn(pfn_end) && !is_noslot_pfn(pfn_end)) {
> > +		/*
> > +		 * Allow guest MMIO range(s) to be added
> > +		 * to the shared pages list.
> > +		 */
> > +		return -EINVAL;
> > +	}
> 
> I don't think KVM should do any checks beyond gfn_end <= gfn_start.  Just punt
> to userspace and give userspace full say over what is/isn't legal.
> 
> > +
> > +	if (enc)
> > +		vcpu->run->exit_reason = KVM_EXIT_DMA_UNSHARE;
> > +	else
> > +		vcpu->run->exit_reason = KVM_EXIT_DMA_SHARE;
> 
> Use a single exit and pass "enc" via kvm_run.  I also strongly dislike "DMA",
> there's no guarantee the guest is sharing memory for DMA.
> 
> I think we can usurp KVM_EXIT_HYPERCALL for this?  E.g.
> 
> 	vcpu->run->exit_reason        = KVM_EXIT_HYPERCALL;
> 	vcpu->run->hypercall.nr       = KVM_HC_PAGE_ENC_STATUS;
> 	vcpu->run->hypercall.args[0]  = gfn_start << PAGE_SHIFT;
> 	vcpu->run->hypercall.args[1]  = npages * PAGE_SIZE;
> 	vcpu->run->hypercall.args[2]  = enc;
> 	vcpu->run->hypercall.longmode = is_64_bit_mode(vcpu);
> 
> > +
> > +	vcpu->run->dma_sharing.addr = gfn_start;
> 
> Addresses and pfns are not the same thing.  If you're passing the size in bytes,
> then it's probably best to pass the gpa, not the gfn.  Same for the params from
> the guest, they should be in the same "domain".
> 
> > +	vcpu->run->dma_sharing.len = npages * PAGE_SIZE;
> > +	vcpu->arch.complete_userspace_io =
> > +		sev_complete_userspace_page_enc_status_hc;
> 
> I vote to drop the "userspace" part, it's already quite verbose.
> 
> 	vcpu->arch.complete_userspace_io = sev_complete_page_enc_status_hc;
> 
> > +
> > +	return 0;
> > +}
> > +
> 
> ..
> 
> > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
> > index f7d12fca397b..ef5c77d59651 100644
> > --- a/arch/x86/kvm/x86.c
> > +++ b/arch/x86/kvm/x86.c
> > @@ -8273,6 +8273,18 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
> >  		kvm_sched_yield(vcpu->kvm, a0);
> >  		ret = 0;
> >  		break;
> > +	case KVM_HC_PAGE_ENC_STATUS: {
> > +		int r;
> > +
> > +		ret = -KVM_ENOSYS;
> > +		if (kvm_x86_ops.page_enc_status_hc) {
> > +			r = kvm_x86_ops.page_enc_status_hc(vcpu, a0, a1, a2);
> 
> Use static_call().
> 
> > +			if (r >= 0)
> > +				return r;
> > +			ret = r;
> > +		}
> 
> Hmm, an alternative to adding a kvm_x86_ops hook would be to tag the VM as
> supporting/allowing the hypercall.  That would clean up this code, ensure VMX
> and SVM don't end up creating a different userspace ABI, and make it easier to
> reuse the hypercall in the future (I'm still hopeful :-) ).  E.g.
> 
> 	case KVM_HC_PAGE_ENC_STATUS: {
> 		u64 gpa = a0, nr_bytes = a1;
> 
> 		if (!vcpu->kvm->arch.page_enc_hc_enable)
> 			break;
> 
> 		if (!PAGE_ALIGNED(gpa) || !PAGE_ALIGNED(nr_bytes) ||
> 		    !nr_bytes || gpa + nr_bytes <= gpa)) {
> 			ret = -EINVAL;
> 			break;
> 		}
> 
> 	        vcpu->run->exit_reason        = KVM_EXIT_HYPERCALL; 
>         	vcpu->run->hypercall.nr       = KVM_HC_PAGE_ENC_STATUS; 
> 	        vcpu->run->hypercall.args[0]  = gpa;
>         	vcpu->run->hypercall.args[1]  = nr_bytes;
> 	        vcpu->run->hypercall.args[2]  = enc;                                    
>         	vcpu->run->hypercall.longmode = op_64_bit;
> 		vcpu->arch.complete_userspace_io = complete_page_enc_hc;
> 		return 0;
> 	}

I really like the above approach, but one thing that concerns me above
is the addition of architecture specific code, for example, the page
encryption stuff as part of the generic x86 KVM code ? 

Especially bits like the page enc hypercall completion callback and
testing the architecture specific page encryption hypercall enabled
flag, probably the hypercall completion callback can be named
something as complete_userspace_hypercall(), as anyway what it does
inside the callback is all very generic.

The above naming may also go well with KVM_EXIT_HYPERCALL exitcode 
interface.

Thanks,
Ashish

> 
> 
> > +		break;
> > +	}
> >  	default:
> >  		ret = -KVM_ENOSYS;
> >  		break;

  parent reply	other threads:[~2021-04-07 14:01 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-05 14:20 [PATCH v11 00/13] Add AMD SEV guest live migration support Ashish Kalra
2021-04-05 14:21 ` [PATCH v11 01/13] KVM: SVM: Add KVM_SEV SEND_START command Ashish Kalra
2021-04-05 14:23 ` [PATCH v11 02/13] KVM: SVM: Add KVM_SEND_UPDATE_DATA command Ashish Kalra
2021-04-05 14:23 ` [PATCH v11 03/13] KVM: SVM: Add KVM_SEV_SEND_FINISH command Ashish Kalra
2021-04-05 14:24 ` [PATCH v11 04/13] KVM: SVM: Add support for KVM_SEV_RECEIVE_START command Ashish Kalra
2021-04-05 14:24 ` [PATCH v11 05/13] KVM: SVM: Add KVM_SEV_RECEIVE_UPDATE_DATA command Ashish Kalra
2021-04-05 14:25 ` [PATCH v11 06/13] KVM: SVM: Add KVM_SEV_RECEIVE_FINISH command Ashish Kalra
2021-04-05 14:26 ` [PATCH v11 07/13] KVM: x86: Add AMD SEV specific Hypercall3 Ashish Kalra
2021-04-05 14:28 ` [PATCH v11 08/13] KVM: X86: Introduce KVM_HC_PAGE_ENC_STATUS hypercall Ashish Kalra
2021-04-05 20:42   ` Steve Rutherford
2021-04-06  6:22     ` Ashish Kalra
2021-04-06 15:11       ` Sean Christopherson
2021-04-06 15:20         ` Sean Christopherson
2021-04-06 18:14       ` Ashish Kalra
2021-04-06 15:48   ` Sean Christopherson
2021-04-06 16:07     ` Ashish Kalra
2021-04-06 20:14       ` Steve Rutherford
2021-04-06 20:27         ` Sean Christopherson
2021-04-07 14:01     ` Ashish Kalra [this message]
2021-04-05 14:29 ` [PATCH v11 09/13] mm: x86: Invoke hypercall when page encryption status is changed Ashish Kalra
2021-04-05 14:30 ` [PATCH v11 10/13] KVM: x86: Introduce new KVM_FEATURE_SEV_LIVE_MIGRATION feature & Custom MSR Ashish Kalra
2021-04-06  1:39   ` Steve Rutherford
2021-04-06 13:26     ` Ashish Kalra
2021-04-06 13:47       ` Paolo Bonzini
2021-04-06 13:59         ` Ashish Kalra
2021-04-06 19:41           ` Steve Rutherford
2021-04-05 14:30 ` [PATCH v11 11/13] EFI: Introduce the new AMD Memory Encryption GUID Ashish Kalra
2021-04-05 14:31 ` [PATCH v11 12/13] x86/kvm: Add guest support for detecting and enabling SEV Live Migration feature Ashish Kalra
2021-04-05 14:35 ` [PATCH v11 13/13] x86/kvm: Add kexec support for SEV Live Migration Ashish Kalra
2021-04-05 15:17 ` [PATCH v11 00/13] Add AMD SEV guest live migration support Peter Gonda
2021-04-05 18:27   ` Steve Rutherford
2021-04-06 13:48     ` Paolo Bonzini
2021-04-06  1:43 ` Steve Rutherford

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210407140044.GA25499@ashkalra_ubuntu_server \
    --to=ashish.kalra@amd.com \
    --cc=bp@suse.de \
    --cc=brijesh.singh@amd.com \
    --cc=hpa@zytor.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qperret@google.com \
    --cc=seanjc@google.com \
    --cc=srutherford@google.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=venu.busireddy@oracle.com \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).