linux-coco.lists.linux.dev archive mirror
 help / color / mirror / Atom feed
From: Borislav Petkov <bp@alien8.de>
To: Brijesh Singh <brijesh.singh@amd.com>
Cc: x86@kernel.org, linux-kernel@vger.kernel.org,
	kvm@vger.kernel.org, linux-efi@vger.kernel.org,
	platform-driver-x86@vger.kernel.org, linux-coco@lists.linux.dev,
	linux-mm@kvack.org, Thomas Gleixner <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, Joerg Roedel <jroedel@suse.de>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	"H. Peter Anvin" <hpa@zytor.com>,
	Ard Biesheuvel <ardb@kernel.org>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Sean Christopherson <seanjc@google.com>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	Jim Mattson <jmattson@google.com>,
	Andy Lutomirski <luto@kernel.org>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	Sergio Lopez <slp@redhat.com>, Peter Gonda <pgonda@google.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>,
	David Rientjes <rientjes@google.com>,
	Dov Murik <dovmurik@linux.ibm.com>,
	Tobin Feldman-Fitzthum <tobin@ibm.com>,
	Michael Roth <michael.roth@amd.com>,
	Vlastimil Babka <vbabka@suse.cz>,
	"Kirill A . Shutemov" <kirill@shutemov.name>,
	Andi Kleen <ak@linux.intel.com>,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
	tony.luck@intel.com, marcorr@google.com,
	sathyanarayanan.kuppuswamy@linux.intel.com
Subject: Re: [PATCH v6 19/42] x86/mm: Add support to validate memory when changing C-bit
Date: Tue, 9 Nov 2021 20:34:07 +0100	[thread overview]
Message-ID: <YYrNL7U07SxeUQ3E@zn.tnic> (raw)
In-Reply-To: <20211008180453.462291-20-brijesh.singh@amd.com>

On Fri, Oct 08, 2021 at 01:04:30PM -0500, Brijesh Singh wrote:
> +static int vmgexit_psc(struct snp_psc_desc *desc)
> +{
> +	int cur_entry, end_entry, ret;
> +	struct snp_psc_desc *data;
> +	struct ghcb_state state;
> +	struct ghcb *ghcb;
> +	struct psc_hdr *hdr;
> +	unsigned long flags;

        int cur_entry, end_entry, ret;
        struct snp_psc_desc *data;
        struct ghcb_state state;
        struct psc_hdr *hdr;
        unsigned long flags;
        struct ghcb *ghcb;

that's properly sorted.

> +
> +	local_irq_save(flags);

What is that protecting against? Comment about it?

Aha, __sev_get_ghcb() needs to run with IRQs disabled because it is
using the per-CPU GHCB.

> +
> +	ghcb = __sev_get_ghcb(&state);
> +	if (unlikely(!ghcb))
> +		panic("SEV-SNP: Failed to get GHCB\n");
> +
> +	/* Copy the input desc into GHCB shared buffer */
> +	data = (struct snp_psc_desc *)ghcb->shared_buffer;
> +	memcpy(ghcb->shared_buffer, desc, sizeof(*desc));

That shared buffer has a size - check it vs the size of the desc thing.

> +
> +	hdr = &data->hdr;

Why do you need this and why can't you use data->hdr simply?

/me continues reading and realizes why

Oh no, this is tricky. The HV call will modify what @data points to and
thus @hdr will point to new contents. Only then your backwards processing
check below makes sense.

So then you *absoulutely* want to use data->hdr everywhere and then also
write why in the comment above the check that data gets updated by the
HV call.

> +	cur_entry = hdr->cur_entry;
> +	end_entry = hdr->end_entry;
> +
> +	/*
> +	 * As per the GHCB specification, the hypervisor can resume the guest
> +	 * before processing all the entries. Checks whether all the entries

					      Check

> +	 * are processed. If not, then keep retrying.
> +	 *
> +	 * The stragtegy here is to wait for the hypervisor to change the page
> +	 * state in the RMP table before guest access the memory pages. If the

					       accesses

> +	 * page state was not successful, then later memory access will result

"If the page state *change* was not ..."

> +	 * in the crash.

	"in a crash."

> +	 */
> +	while (hdr->cur_entry <= hdr->end_entry) {
> +		ghcb_set_sw_scratch(ghcb, (u64)__pa(data));
> +
> +		ret = sev_es_ghcb_hv_call(ghcb, NULL, SVM_VMGEXIT_PSC, 0, 0);

This should be

		ret = sev_es_ghcb_hv_call(ghcb, true, NULL, SVM_VMGEXIT_PSC, 0, 0);

as we changed it in the meantime to accomodate HyperV isolation VMs.

> +
> +		/*
> +		 * Page State Change VMGEXIT can pass error code through
> +		 * exit_info_2.
> +		 */
> +		if (WARN(ret || ghcb->save.sw_exit_info_2,
> +			 "SEV-SNP: PSC failed ret=%d exit_info_2=%llx\n",
> +			 ret, ghcb->save.sw_exit_info_2)) {
> +			ret = 1;

That ret = 1 goes unused with that "return 0" at the end. It should be
"return ret" at the end.. Ditto for the others. Audit all your exit
paths in this function.

> +			goto out;
> +		}
> +
> +		/*
> +		 * Sanity check that entry processing is not going backward.
> +		 * This will happen only if hypervisor is tricking us.
> +		 */
> +		if (WARN(hdr->end_entry > end_entry || cur_entry > hdr->cur_entry,
> +"SEV-SNP:  PSC processing going backward, end_entry %d (got %d) cur_entry %d (got %d)\n",
> +			 end_entry, hdr->end_entry, cur_entry, hdr->cur_entry)) {
> +			ret = 1;
> +			goto out;
> +		}
> +
> +		/* Verify that reserved bit is not set */
> +		if (WARN(hdr->reserved, "Reserved bit is set in the PSC header\n")) {

Shouldn't that thing happen first after the HV call?

> +			ret = 1;
> +			goto out;
> +		}
> +	}
> +
> +out:
> +	__sev_put_ghcb(&state);
> +	local_irq_restore(flags);
> +
> +	return 0;
> +}
> +
> +static void __set_page_state(struct snp_psc_desc *data, unsigned long vaddr,
> +			     unsigned long vaddr_end, int op)
> +{
> +	struct psc_hdr *hdr;
> +	struct psc_entry *e;
> +	unsigned long pfn;
> +	int i;
> +
> +	hdr = &data->hdr;
> +	e = data->entries;
> +
> +	memset(data, 0, sizeof(*data));
> +	i = 0;
> +
> +	while (vaddr < vaddr_end) {
> +		if (is_vmalloc_addr((void *)vaddr))
> +			pfn = vmalloc_to_pfn((void *)vaddr);
> +		else
> +			pfn = __pa(vaddr) >> PAGE_SHIFT;
> +
> +		e->gfn = pfn;
> +		e->operation = op;
> +		hdr->end_entry = i;
> +
> +		/*
> +		 * The GHCB specification provides the flexibility to
> +		 * use either 4K or 2MB page size in the RMP table.
> +		 * The current SNP support does not keep track of the
> +		 * page size used in the RMP table. To avoid the
> +		 * overlap request,

"avoid overlap request"?

No clue what that means. In general, that comment is talking about
something in the future and is more confusing than explaining stuff.

> use the 4K page size in the RMP
> +		 * table.
> +		 */
> +		e->pagesize = RMP_PG_SIZE_4K;
> +
> +		vaddr = vaddr + PAGE_SIZE;
> +		e++;
> +		i++;
> +	}
> +
> +	if (vmgexit_psc(data))
> +		sev_es_terminate(SEV_TERM_SET_LINUX, GHCB_TERM_PSC);
> +}
> +
> +static void set_page_state(unsigned long vaddr, unsigned int npages, int op)

Yeah, so this should be named

set_pages_state - notice the plural "pages"

because it works on multiple pages, @npages exactly.

> +{
> +	unsigned long vaddr_end, next_vaddr;
> +	struct snp_psc_desc *desc;
> +
> +	vaddr = vaddr & PAGE_MASK;
> +	vaddr_end = vaddr + (npages << PAGE_SHIFT);

Take those two...

> +
> +	desc = kmalloc(sizeof(*desc), GFP_KERNEL_ACCOUNT);
> +	if (!desc)
> +		panic("SEV-SNP: failed to allocate memory for PSC descriptor\n");


... and put them here.

<--- 

> +
> +	while (vaddr < vaddr_end) {
> +		/*
> +		 * Calculate the last vaddr that can be fit in one
> +		 * struct snp_psc_desc.
> +		 */
> +		next_vaddr = min_t(unsigned long, vaddr_end,
> +				   (VMGEXIT_PSC_MAX_ENTRY * PAGE_SIZE) + vaddr);
> +
> +		__set_page_state(desc, vaddr, next_vaddr, op);
> +
> +		vaddr = next_vaddr;
> +	}
> +
> +	kfree(desc);
> +}
> +
> +void snp_set_memory_shared(unsigned long vaddr, unsigned int npages)
> +{
> +	if (!cc_platform_has(CC_ATTR_SEV_SNP))
> +		return;
> +
> +	pvalidate_pages(vaddr, npages, 0);
> +
> +	set_page_state(vaddr, npages, SNP_PAGE_STATE_SHARED);
> +}
> +
> +void snp_set_memory_private(unsigned long vaddr, unsigned int npages)
> +{
> +	if (!cc_platform_has(CC_ATTR_SEV_SNP))
> +		return;
> +
> +	set_page_state(vaddr, npages, SNP_PAGE_STATE_PRIVATE);
> +
> +	pvalidate_pages(vaddr, npages, 1);
> +}
> +
>  int sev_es_setup_ap_jump_table(struct real_mode_header *rmh)
>  {
>  	u16 startup_cs, startup_ip;
> diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> index 527957586f3c..ffe51944606a 100644
> --- a/arch/x86/mm/pat/set_memory.c
> +++ b/arch/x86/mm/pat/set_memory.c
> @@ -30,6 +30,7 @@
>  #include <asm/proto.h>
>  #include <asm/memtype.h>
>  #include <asm/set_memory.h>
> +#include <asm/sev.h>
>  
>  #include "../mm_internal.h"
>  
> @@ -2010,8 +2011,22 @@ static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
>  	 */
>  	cpa_flush(&cpa, !this_cpu_has(X86_FEATURE_SME_COHERENT));
>  
> +	/*
> +	 * To maintain the security gurantees of SEV-SNP guest invalidate the memory

"guarantees"

Your spellchecker broke again.

> +	 * before clearing the encryption attribute.
> +	 */
> +	if (!enc)
> +		snp_set_memory_shared(addr, numpages);
> +
>  	ret = __change_page_attr_set_clr(&cpa, 1);
>  
> +	/*
> +	 * Now that memory is mapped encrypted in the page table, validate it
> +	 * so that is consistent with the above page state.
> +	 */
> +	if (!ret && enc)
> +		snp_set_memory_private(addr, numpages);
> +
>  	/*
>  	 * After changing the encryption attribute, we need to flush TLBs again
>  	 * in case any speculative TLB caching occurred (but no need to flush
> -- 
> 2.25.1
> 

-- 
Regards/Gruss,
    Boris.

https://people.kernel.org/tglx/notes-about-netiquette

  reply	other threads:[~2021-11-09 19:34 UTC|newest]

Thread overview: 96+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-08 18:04 [PATCH v6 00/42] Add AMD Secure Nested Paging (SEV-SNP) Guest Support Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 01/42] x86/mm: Extend cc_attr to include AMD SEV-SNP Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 02/42] x86/sev: Shorten GHCB terminate macro names Brijesh Singh
2021-10-11 13:15   ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 03/42] x86/sev: Get rid of excessive use of defines Brijesh Singh
2021-10-11  8:48   ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 04/42] x86/head64: Carve out the guest encryption postprocessing into a helper Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 05/42] x86/sev: Define the Linux specific guest termination reasons Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 06/42] x86/sev: Save the negotiated GHCB version Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 07/42] x86/sev: Add support for hypervisor feature VMGEXIT Brijesh Singh
2021-10-13 14:02   ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 08/42] x86/sev-es: initialize sev_status/features within #VC handler Brijesh Singh
2021-10-18 14:29   ` Borislav Petkov
2021-10-18 18:40     ` Michael Roth
2021-10-18 19:18       ` Borislav Petkov
2021-10-20 16:10         ` Michael Roth
2021-10-20 18:01           ` Borislav Petkov
2021-10-21  0:35             ` Michael Roth
2021-10-21 14:28               ` Borislav Petkov
2021-10-20 18:08           ` Borislav Petkov
2021-10-21  2:05             ` Michael Roth
2021-10-21 14:39               ` Borislav Petkov
2021-10-21 23:00                 ` Michael Roth
2021-10-21 14:48           ` Borislav Petkov
2021-10-21 15:56             ` Dr. David Alan Gilbert
2021-10-21 16:55               ` Borislav Petkov
2021-10-21 17:12                 ` Dr. David Alan Gilbert
2021-10-21 17:37                   ` Borislav Petkov
2021-10-21 17:47                     ` Dr. David Alan Gilbert
2021-10-21 18:46                       ` Borislav Petkov
2021-10-21 21:34             ` Michael Roth
2021-10-21 14:51           ` Borislav Petkov
2021-10-21 20:41             ` Michael Roth
2021-10-25 11:04               ` Borislav Petkov
2021-10-25 16:35                 ` Michael Roth
2021-10-27 11:17                   ` Borislav Petkov
2021-10-27 15:13                     ` Michael Roth
2021-10-08 18:04 ` [PATCH v6 09/42] x86/sev: Check SEV-SNP features support Brijesh Singh
2021-10-19 14:47   ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 10/42] x86/sev: Add a helper for the PVALIDATE instruction Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 11/42] x86/sev: Check the vmpl level Brijesh Singh
2021-10-28 15:07   ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 12/42] x86/compressed: Add helper for validating pages in the decompression stage Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 13/42] x86/compressed: Register GHCB memory when SEV-SNP is active Brijesh Singh
2021-11-02 16:33   ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 14/42] x86/sev: " Brijesh Singh
2021-11-02 16:53   ` Borislav Petkov
2021-11-02 18:24     ` Brijesh Singh
2021-11-02 18:44       ` Borislav Petkov
2021-11-03 20:10         ` Brijesh Singh
2021-11-04 13:58           ` Borislav Petkov
2021-11-04 15:26             ` Brijesh Singh
2021-11-04 16:03               ` Boris Petkov
2021-10-08 18:04 ` [PATCH v6 15/42] x86/sev: Remove do_early_exception() forward declarations Brijesh Singh
2021-11-02 16:54   ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 16/42] x86/sev: Add helper for validating pages in early enc attribute changes Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 17/42] x86/kernel: Make the bss.decrypted section shared in RMP table Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 18/42] x86/kernel: Validate rom memory before accessing when SEV-SNP is active Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 19/42] x86/mm: Add support to validate memory when changing C-bit Brijesh Singh
2021-11-09 19:34   ` Borislav Petkov [this message]
2021-11-10 14:21     ` Brijesh Singh
2021-11-10 18:43       ` Borislav Petkov
2021-11-11 14:49         ` Tom Lendacky
2021-11-11 16:01           ` Borislav Petkov
2021-10-08 18:04 ` [PATCH v6 20/42] KVM: SVM: Define sev_features and vmpl field in the VMSA Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 21/42] KVM: SVM: Create a separate mapping for the SEV-ES save area Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 22/42] KVM: SVM: Create a separate mapping for the GHCB " Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 23/42] KVM: SVM: Update the SEV-ES save area mapping Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 24/42] x86/sev: Use SEV-SNP AP creation to start secondary CPUs Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 25/42] x86/head: re-enable stack protection for 32/64-bit builds Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 26/42] x86/sev: move MSR-based VMGEXITs for CPUID to helper Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 27/42] KVM: x86: move lookup of indexed CPUID leafs " Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 28/42] x86/compressed/acpi: move EFI system table lookup " Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 29/42] x86/compressed/acpi: move EFI config " Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 30/42] x86/compressed/acpi: move EFI vendor " Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 31/42] x86/boot: Add Confidential Computing type to setup_data Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 32/42] x86/compressed/64: add support for SEV-SNP CPUID table in #VC handlers Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 33/42] boot/compressed/64: use firmware-validated CPUID for SEV-SNP guests Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 34/42] x86/boot: add a pointer to Confidential Computing blob in bootparams Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 35/42] x86/compressed/64: store Confidential Computing blob address " Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 36/42] x86/compressed/64: add identity mapping for Confidential Computing blob Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 37/42] x86/sev: use firmware-validated CPUID for SEV-SNP guests Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 38/42] x86/sev: Provide support for SNP guest request NAEs Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 39/42] x86/sev: Register SNP guest request platform device Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 40/42] virt: Add SEV-SNP guest driver Brijesh Singh
2021-10-10 17:51   ` Dov Murik
2021-10-13 11:37     ` Brijesh Singh
2021-10-20 21:33   ` Peter Gonda
2021-10-27 16:07     ` Brijesh Singh
2021-10-27 20:10       ` Peter Gonda
2021-10-27 20:47         ` Brijesh Singh
2021-10-27 21:05           ` Peter Gonda
2021-10-27 21:12             ` Brijesh Singh
2021-10-27 21:15               ` Peter Gonda
2021-10-08 18:04 ` [PATCH v6 41/42] virt: sevguest: Add support to derive key Brijesh Singh
2021-10-08 18:04 ` [PATCH v6 42/42] virt: sevguest: Add support to get extended report Brijesh Singh

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=YYrNL7U07SxeUQ3E@zn.tnic \
    --to=bp@alien8.de \
    --cc=ak@linux.intel.com \
    --cc=ardb@kernel.org \
    --cc=brijesh.singh@amd.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dgilbert@redhat.com \
    --cc=dovmurik@linux.ibm.com \
    --cc=hpa@zytor.com \
    --cc=jmattson@google.com \
    --cc=jroedel@suse.de \
    --cc=kirill@shutemov.name \
    --cc=kvm@vger.kernel.org \
    --cc=linux-coco@lists.linux.dev \
    --cc=linux-efi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=luto@kernel.org \
    --cc=marcorr@google.com \
    --cc=michael.roth@amd.com \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=pgonda@google.com \
    --cc=platform-driver-x86@vger.kernel.org \
    --cc=rientjes@google.com \
    --cc=sathyanarayanan.kuppuswamy@linux.intel.com \
    --cc=seanjc@google.com \
    --cc=slp@redhat.com \
    --cc=srinivas.pandruvada@linux.intel.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=tobin@ibm.com \
    --cc=tony.luck@intel.com \
    --cc=vbabka@suse.cz \
    --cc=vkuznets@redhat.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).