lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <BYAPR21MB168831FA522835E074565FF8D70EA@BYAPR21MB1688.namprd21.prod.outlook.com>
Date:   Sat, 5 Aug 2023 14:38:52 +0000
From:   "Michael Kelley (LINUX)" <mikelley@...rosoft.com>
To:     Tom Lendacky <thomas.lendacky@....com>,
        KY Srinivasan <kys@...rosoft.com>,
        Haiyang Zhang <haiyangz@...rosoft.com>,
        "wei.liu@...nel.org" <wei.liu@...nel.org>,
        Dexuan Cui <decui@...rosoft.com>,
        "tglx@...utronix.de" <tglx@...utronix.de>,
        "mingo@...hat.com" <mingo@...hat.com>,
        "bp@...en8.de" <bp@...en8.de>,
        "dave.hansen@...ux.intel.com" <dave.hansen@...ux.intel.com>,
        "hpa@...or.com" <hpa@...or.com>,
        "luto@...nel.org" <luto@...nel.org>,
        "peterz@...radead.org" <peterz@...radead.org>,
        "sathyanarayanan.kuppuswamy@...ux.intel.com" 
        <sathyanarayanan.kuppuswamy@...ux.intel.com>,
        "kirill.shutemov@...ux.intel.com" <kirill.shutemov@...ux.intel.com>,
        "seanjc@...gle.com" <seanjc@...gle.com>,
        "rick.p.edgecombe@...el.com" <rick.p.edgecombe@...el.com>,
        "linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
        "linux-hyperv@...r.kernel.org" <linux-hyperv@...r.kernel.org>,
        "x86@...nel.org" <x86@...nel.org>
Subject: RE: [RFC PATCH 1/1] x86/mm: Mark CoCo VM pages invalid while moving
 between private and shared

From: Tom Lendacky <thomas.lendacky@....com> Sent: Wednesday, August 2, 2023 2:58 PM
> 

[snip]

> >
> > diff --git a/arch/x86/hyperv/ivm.c b/arch/x86/hyperv/ivm.c
> > index 28be6df..2859ec3 100644
> > --- a/arch/x86/hyperv/ivm.c
> > +++ b/arch/x86/hyperv/ivm.c
> > @@ -308,7 +308,8 @@ static bool hv_vtom_set_host_visibility(unsigned long kbuffer, int pagecount, bo
> >   		return false;
> >
> >   	for (i = 0, pfn = 0; i < pagecount; i++) {
> > -		pfn_array[pfn] = virt_to_hvpfn((void *)kbuffer + i * HV_HYP_PAGE_SIZE);
> > +		pfn_array[pfn] = slow_virt_to_phys((void *)kbuffer +
> > +					i * HV_HYP_PAGE_SIZE) >> HV_HYP_PAGE_SHIFT;
> 
> Definitely needs a comment here (and below) that slow_virt_to_phys() is
> being used because of making the page not present.

Agreed.

> 
> >   		pfn++;
> >
> >   		if (pfn == HV_MAX_MODIFY_GPA_REP_COUNT || i == pagecount - 1) {
> > diff --git a/arch/x86/kernel/sev.c b/arch/x86/kernel/sev.c
> > index 1ee7bed..59db55e 100644
> > --- a/arch/x86/kernel/sev.c
> > +++ b/arch/x86/kernel/sev.c
> > @@ -784,7 +784,7 @@ static unsigned long __set_pages_state(struct snp_psc_desc *data, unsigned long
> >   		hdr->end_entry = i;
> >
> >   		if (is_vmalloc_addr((void *)vaddr)) {
> > -			pfn = vmalloc_to_pfn((void *)vaddr);
> > +			pfn = slow_virt_to_phys((void *)vaddr) >> PAGE_SHIFT;
> >   			use_large_entry = false;
> >   		} else {
> >   			pfn = __pa(vaddr) >> PAGE_SHIFT;
> > diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> > index bda9f12..8a194c7 100644
> > --- a/arch/x86/mm/pat/set_memory.c
> > +++ b/arch/x86/mm/pat/set_memory.c
> > @@ -2136,6 +2136,11 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
> >   	if (WARN_ONCE(addr & ~PAGE_MASK, "misaligned address: %#lx\n", addr))
> >   		addr &= PAGE_MASK;
> >
> > +	/* set_memory_np() removes aliasing mappings and flushes the TLB */
> 
> Is there any case where the TLB wouldn't be flushed when it should? Since,
> for SEV at least, the TLB flush being removed below was always performed.

The TLB is flushed as long as set_memory_np() actually changes some
PTEs.  It doesn’t make any sense to be doing a private<->shared transition
on pages that aren't marked PRESENT, so clearing the PRESENT bit will
always change the PTEs and cause the TLB to be flushed.  The decision is
made several levels down in __change_page_attr() where the CPA_FLUSHTLB
flag is set.  The flush is done in change_page_attr_set_clr() based on that
flag.  The data cache is *not* flushed.

Also, even if the memory *was* already not PRESENT, then the PTEs
would not be cached in the TLB anyway, and the TLB would not need
to be flushed.

Michael

> 
> > +	ret = set_memory_np(addr, numpages);
> > +	if (ret)
> > +		return ret;
> > +
> >   	memset(&cpa, 0, sizeof(cpa));
> >   	cpa.vaddr = &addr;
> >   	cpa.numpages = numpages;
> > @@ -2143,36 +2148,23 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
> >   	cpa.mask_clr = enc ? pgprot_decrypted(empty) : pgprot_encrypted(empty);
> >   	cpa.pgd = init_mm.pgd;
> >
> > -	/* Must avoid aliasing mappings in the highmem code */
> > -	kmap_flush_unused();
> > -	vm_unmap_aliases();
> > -
> >   	/* Flush the caches as needed before changing the encryption attribute. */
> > -	if (x86_platform.guest.enc_tlb_flush_required(enc))
> > -		cpa_flush(&cpa, x86_platform.guest.enc_cache_flush_required());
> > +	if (x86_platform.guest.enc_cache_flush_required())
> > +		cpa_flush(&cpa, 1);
> >
> >   	/* Notify hypervisor that we are about to set/clr encryption attribute. */
> >   	if (!x86_platform.guest.enc_status_change_prepare(addr, numpages, enc))
> >   		return -EIO;
> >
> >   	ret = __change_page_attr_set_clr(&cpa, 1);
> > -
> > -	/*
> > -	 * After changing the encryption attribute, we need to flush TLBs again
> > -	 * in case any speculative TLB caching occurred (but no need to flush
> > -	 * caches again).  We could just use cpa_flush_all(), but in case TLB
> > -	 * flushing gets optimized in the cpa_flush() path use the same logic
> > -	 * as above.
> > -	 */
> > -	cpa_flush(&cpa, 0);
> > +	if (ret)
> > +		return ret;
> >
> >   	/* Notify hypervisor that we have successfully set/clr encryption attribute. */
> > -	if (!ret) {
> > -		if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
> > -			ret = -EIO;
> > -	}
> > +	if (!x86_platform.guest.enc_status_change_finish(addr, numpages, enc))
> > +		return -EIO;
> >
> > -	return ret;
> > +	return set_memory_p(&addr, numpages);
> >   }
> >
> >   static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ