linux-coco.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Michael Roth <michael.roth@amd.com>
Cc: kvm@vger.kernel.org, linux-coco@lists.linux.dev,
	 linux-kernel@vger.kernel.org, x86@kernel.org,
	pbonzini@redhat.com,  jroedel@suse.de, thomas.lendacky@amd.com,
	pgonda@google.com,  ashish.kalra@amd.com, bp@alien8.de,
	pankaj.gupta@amd.com,  liam.merwick@oracle.com,
	Brijesh Singh <brijesh.singh@amd.com>,
	 Alexey Kardashevskiy <aik@amd.com>
Subject: Re: [PATCH v1 1/5] KVM: SEV: Provide support for SNP_GUEST_REQUEST NAE event
Date: Wed, 26 Jun 2024 06:58:09 -0700	[thread overview]
Message-ID: <ZnwecZ5SZ8MrTRRT@google.com> (raw)
In-Reply-To: <20240621134041.3170480-2-michael.roth@amd.com>

On Fri, Jun 21, 2024, Michael Roth wrote:
> @@ -3939,6 +3944,67 @@ static int sev_snp_ap_creation(struct vcpu_svm *svm)
>  	return ret;
>  }
>  
> +static int snp_handle_guest_req(struct vcpu_svm *svm, gpa_t req_gpa, gpa_t resp_gpa)
> +{
> +	struct sev_data_snp_guest_request data = {0};
> +	struct kvm *kvm = svm->vcpu.kvm;
> +	kvm_pfn_t req_pfn, resp_pfn;
> +	sev_ret_code fw_err = 0;
> +	int ret;
> +
> +	if (!sev_snp_guest(kvm) || !PAGE_ALIGNED(req_gpa) || !PAGE_ALIGNED(resp_gpa))
> +		return -EINVAL;
> +
> +	req_pfn = gfn_to_pfn(kvm, gpa_to_gfn(req_gpa));

This is going to sound odd, but I think we should use gfn_to_page(), i.e. require
that the page be a refcounted page so that it can be pinned.  Long story short,
one of my learnings from the whole non-refcounted pages saga is that doing DMA
to unpinned pages outside of mmu_lock is wildly unsafe, and for all intents and
purposes the ASP is a device doing DMA.  I'm also pretty sure KVM should actually
*pin* pages, as in FOLL_PIN, but I'm ok tackling that later.

For now, using gfn_to_pages() would avoid creating ABI (DMA to VM_PFNMAP and/or
VM_MIXEDMAP memory) that KVM probably doesn't want to support in the long term.

[*] https://lore.kernel.org/all/20240229025759.1187910-1-stevensd@google.com

> +	if (is_error_noslot_pfn(req_pfn))
> +		return -EINVAL;
> +
> +	resp_pfn = gfn_to_pfn(kvm, gpa_to_gfn(resp_gpa));
> +	if (is_error_noslot_pfn(resp_pfn)) {
> +		ret = EINVAL;
> +		goto release_req;
> +	}
> +
> +	if (rmp_make_private(resp_pfn, 0, PG_LEVEL_4K, 0, true)) {
> +		ret = -EINVAL;
> +		kvm_release_pfn_clean(resp_pfn);
> +		goto release_req;
> +	}

I don't see how this is safe.  KVM holds no locks, i.e. can't guarantee that the
resp_pfn stays private for the duration of the operation.  And on the opposite
side, KVM can't guarantee that resp_pfn isn't being actively used by something
in the kernel, e.g. KVM might induce an unexpected #PF(RMP).

Why can't KVM require that the response/destination page already be private?  I'm
also somewhat confused by the reclaim below.  If KVM converts the response page
back to shared, doesn't that clobber the data?  If so, how does the guest actually
get the response?  I feel like I'm missing something.

Regardless of whether or not I'm missing something, this needs comments, and the
changelog needs to be rewritten with --verbose to explain what's going on.  

> +	data.gctx_paddr = __psp_pa(to_kvm_sev_info(kvm)->snp_context);
> +	data.req_paddr = __sme_set(req_pfn << PAGE_SHIFT);
> +	data.res_paddr = __sme_set(resp_pfn << PAGE_SHIFT);
> +
> +	ret = sev_issue_cmd(kvm, SEV_CMD_SNP_GUEST_REQUEST, &data, &fw_err);
> +	if (ret)
> +		return ret;

This leaks both req_pfn and resp_pfn.

> +
> +	/*
> +	 * If reclaim fails then there's a good chance the guest will no longer
> +	 * be runnable so just let userspace terminate the guest.
> +	 */
> +	if (snp_page_reclaim(kvm, resp_pfn)) {
> +		return -EIO;
> +		goto release_req;
> +	}
> +
> +	/*
> +	 * As per GHCB spec, firmware failures should be communicated back to
> +	 * the guest via SW_EXITINFO2 rather than be treated as immediately
> +	 * fatal.
> +	 */
> +	ghcb_set_sw_exit_info_2(svm->sev_es.ghcb,
> +				SNP_GUEST_ERR(ret ? SNP_GUEST_VMM_ERR_GENERIC : 0,
> +					      fw_err));
> +
> +	ret = 1; /* resume guest */
> +	kvm_release_pfn_dirty(resp_pfn);
> +
> +release_req:
> +	kvm_release_pfn_clean(req_pfn);
> +	return ret;
> +}

  parent reply	other threads:[~2024-06-26 13:58 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-21 13:40 [PATCH v1 0/5] SEV-SNP: Add KVM support for attestation and KVM_EXIT_COCO Michael Roth
2024-06-21 13:40 ` [PATCH v1 1/5] KVM: SEV: Provide support for SNP_GUEST_REQUEST NAE event Michael Roth
2024-06-21 15:52   ` Liam Merwick
2024-06-21 16:17     ` Michael Roth
2024-06-21 17:15   ` [PATCH v1-revised " Michael Roth
2024-06-22  0:13     ` Liam Merwick
2024-06-26 14:32     ` Sean Christopherson
2024-06-26 13:58   ` Sean Christopherson [this message]
2024-06-26 15:45     ` [PATCH v1 " Michael Roth
2024-06-26 17:13       ` Sean Christopherson
2024-06-26 17:42         ` Michael Roth
2024-06-26 19:54           ` Sean Christopherson
2024-06-27 14:48             ` Tom Lendacky
2024-06-27 15:35               ` Sean Christopherson
2024-06-27 16:23                 ` Peter Gonda
2024-06-27 17:13                 ` Tom Lendacky
2024-06-27 18:07                   ` Sean Christopherson
2024-06-21 13:40 ` [PATCH v1 2/5] x86/sev: Move sev_guest.h into common SEV header Michael Roth
2024-06-21 16:42   ` Liam Merwick
2024-06-21 18:07   ` Tom Lendacky
2024-06-21 13:40 ` [PATCH v1 3/5] KVM: SEV: Provide support for SNP_EXTENDED_GUEST_REQUEST NAE event Michael Roth
2024-06-21 16:45   ` Liam Merwick
2024-06-21 19:21   ` Tom Lendacky
2024-06-22 20:28   ` Carlos Bilbao
2024-06-24 13:05     ` Tom Lendacky
2024-06-24 15:02       ` Sean Christopherson
2024-06-21 13:40 ` [PATCH v1 4/5] KVM: Introduce KVM_EXIT_COCO exit type Michael Roth
2024-06-26 14:22   ` Sean Christopherson
2024-06-26 17:30     ` Michael Roth
2024-06-28 20:08       ` Sean Christopherson
2024-06-29  0:36         ` Michael Roth
2024-07-26  7:15           ` Binbin Wu
2024-09-13 16:29             ` Dionna Amalie Glaze
2024-10-28 18:20               ` Sean Christopherson
2024-11-01 20:53                 ` Dionna Amalie Glaze
2024-11-01 21:52                   ` Michael Roth
2024-11-01 23:54                     ` Dionna Amalie Glaze
2024-11-19 13:53             ` Michael Roth
2024-11-20  4:03               ` Binbin Wu
2024-06-21 13:40 ` [PATCH v1 5/5] KVM: SEV: Add certificate support for SNP_EXTENDED_GUEST_REQUEST events Michael Roth

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=ZnwecZ5SZ8MrTRRT@google.com \
    --to=seanjc@google.com \
    --cc=aik@amd.com \
    --cc=ashish.kalra@amd.com \
    --cc=bp@alien8.de \
    --cc=brijesh.singh@amd.com \
    --cc=jroedel@suse.de \
    --cc=kvm@vger.kernel.org \
    --cc=liam.merwick@oracle.com \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael.roth@amd.com \
    --cc=pankaj.gupta@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=pgonda@google.com \
    --cc=thomas.lendacky@amd.com \
    --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 NNTP newsgroup(s).