Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp1126851ybb; Fri, 20 Mar 2020 13:55:22 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvSH1w8Q0D1LqmP7KySur4UZkvmodTKsS1GnKqzEA4qW2fqCAVdnI2MHWoFspVNAA1474Qr X-Received: by 2002:a9d:6457:: with SMTP id m23mr8697412otl.162.1584737722053; Fri, 20 Mar 2020 13:55:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584737722; cv=none; d=google.com; s=arc-20160816; b=uYsrHcoycYShThXlOfZhaqXwmvF4CvEkpwRChC3jyCJvA8N6U+qg3OvjO5zc8eU+HV pPr0Unw9Ke5HAvAcRicN7JJsPQ1DzS6zrzFBvS0dhTL+cI4MR9HRs8E+Yl9vHXx99QjB SS/Jy1xhWWm6HLT6fAvJS5jDaqE2GPpWUD/usQrWK7JXXeN+ajLgI40Lm/CIQcQZoe3u LyOgHYnrHobIUyZPnBCfX6ZUx8U3/ynoqbmGH0R6m2E9rwPH2tVdsw1r8fYcMNZEHkWP 89i7y7rujjqD6Vd3ssyh2JTIVYem+nx1hSJvKwNLusbi3p+S99ymFn4kjhFHay/nzYLo +z8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:user-agent:references :message-id:in-reply-to:subject:cc:to:from:date:dkim-signature; bh=J/8p3UslkfxkazuuIhw9AGyhLcWU24JMkJmDvprnAhY=; b=F5+A5h44jnAp4VSxPu+BykN8Ss6hDCKhEDKcmWbvCs5oCKpJ85nIuZr84btuYwtNoE nu0jq/ZkYKOpMqeXMRuFi5nt1Lpbt28x/vRqJq+Pooh8OuhUtApt8eQbm5gSCW2qN2R2 dTbhX3knzHGtXYI08esc8c3s0GIXdPQxms24nl2hfPfWW9v39ZsYM64BKoEqv9H1NZw8 u/dtDqVAj96FE+lBqyL3AuJjxRkg73MgeiRkjlHQ1jDFu5DoOn5i3X9siIeA3EXvTqG0 4tLwinNckyt26SyRfxCIaMoRZgBTEN9EWOiMlcGL5ULeMCv5WLE0htjvc3flWWy9iSLn wPAw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=nOwZCr2i; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 2si3308408ois.104.2020.03.20.13.55.10; Fri, 20 Mar 2020 13:55:22 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=nOwZCr2i; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726912AbgCTUxO (ORCPT + 99 others); Fri, 20 Mar 2020 16:53:14 -0400 Received: from mail-pj1-f66.google.com ([209.85.216.66]:40832 "EHLO mail-pj1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726783AbgCTUxN (ORCPT ); Fri, 20 Mar 2020 16:53:13 -0400 Received: by mail-pj1-f66.google.com with SMTP id bo3so2999089pjb.5 for ; Fri, 20 Mar 2020 13:53:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:from:to:cc:subject:in-reply-to:message-id:references :user-agent:mime-version; bh=J/8p3UslkfxkazuuIhw9AGyhLcWU24JMkJmDvprnAhY=; b=nOwZCr2ivALZt1aDv9YFo6F4kwz4JRZolQqjxNvEdRHdm8SyYBRHW2HIIp6WKHnO02 V1Y9ERrmONv+hlcSM+SoFxnCtjFOffoFK88FB5ActwZ7Ly1gS6nkKs85c2DZcXEf7Sji ohs+9aoo5+rurAFbIdYMY74Mb3i+hj2DcEq0Pf1YemnM98/uyDAnZUsYfzG8X1IhIXrq C1bUti2JiW0WDPgSlWk1p/Cp9MDjnyfPD+/jc0zUymBi8yQNYSBn68WSCtHz6Fdy36TU HfR71t5JNxGtAdGySpJw8rKPjkwFBKyb3pBQ5IutgR5ECR6FWy+QmVxhgzJevlb5FiDh oVIg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:in-reply-to:message-id :references:user-agent:mime-version; bh=J/8p3UslkfxkazuuIhw9AGyhLcWU24JMkJmDvprnAhY=; b=LnY1ARM7P5GL4Iv03/ozEi5Yr6uCbXR7qYvRlcfpTdm76Ogn8ENSx3hQysAdRpfVaK PShoGpYwVmV5sF+UULdgHpPJRfjbLTHPeyfuN1aj2uQAgufk4d5UnJM8W9E11jAUxaMP kBZlpTW4v59qPyQ2TNPaQnYcLkAQvomH68M3M+FitOe3k7pDemm8o0hmP7X7hx488Wc1 1jpLXQFhAp+8HgYs63kbpPNGMsImTWHd3Q7geuuMoERZN1Nb9gzpiXs1/k48vfCW06Mn IGeDaj0j4UciNyw06x2Ws0N4Rr9EDAWS9Huwx6Le4T8pfuv+/ADXisK77/BTIRmbYQ4X A+oQ== X-Gm-Message-State: ANhLgQ0br0yI0nvKGtoY1yM7Uejjr50DGRE5gZDd7MB1nO0mESzHL32A meyUqUME8/BZX+Mx129hHaqUMQ== X-Received: by 2002:a17:90b:3613:: with SMTP id ml19mr11555148pjb.71.1584737590060; Fri, 20 Mar 2020 13:53:10 -0700 (PDT) Received: from [2620:15c:17:3:3a5:23a7:5e32:4598] ([2620:15c:17:3:3a5:23a7:5e32:4598]) by smtp.gmail.com with ESMTPSA id u18sm6538998pfl.40.2020.03.20.13.53.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 20 Mar 2020 13:53:09 -0700 (PDT) Date: Fri, 20 Mar 2020 13:53:08 -0700 (PDT) From: David Rientjes X-X-Sender: rientjes@chino.kir.corp.google.com To: Joerg Roedel cc: x86@kernel.org, hpa@zytor.com, Andy Lutomirski , Dave Hansen , Peter Zijlstra , Thomas Hellstrom , Jiri Slaby , Dan Williams , Tom Lendacky , Juergen Gross , Kees Cook , linux-kernel@vger.kernel.org, kvm@vger.kernel.org, virtualization@lists.linux-foundation.org, Joerg Roedel Subject: Re: [PATCH 21/70] x86/boot/compressed/64: Add function to map a page unencrypted In-Reply-To: <20200319091407.1481-22-joro@8bytes.org> Message-ID: References: <20200319091407.1481-1-joro@8bytes.org> <20200319091407.1481-22-joro@8bytes.org> User-Agent: Alpine 2.21 (DEB 202 2017-01-01) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 19 Mar 2020, Joerg Roedel wrote: > From: Joerg Roedel > > This function is needed to map the GHCB for SEV-ES guests. The GHCB is > used for communication with the hypervisor, so its content must not be > encrypted. > > Signed-off-by: Joerg Roedel > --- > arch/x86/boot/compressed/ident_map_64.c | 125 ++++++++++++++++++++++++ > arch/x86/boot/compressed/misc.h | 1 + > 2 files changed, 126 insertions(+) > > diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c > index feb180cced28..04a5ff4bda66 100644 > --- a/arch/x86/boot/compressed/ident_map_64.c > +++ b/arch/x86/boot/compressed/ident_map_64.c > @@ -26,6 +26,7 @@ > #include > #include > #include > +#include > /* Use the static base for this part of the boot process */ > #undef __PAGE_OFFSET > #define __PAGE_OFFSET __PAGE_OFFSET_BASE > @@ -157,6 +158,130 @@ void initialize_identity_maps(void) > write_cr3(top_level_pgt); > } > > +static pte_t *split_large_pmd(struct x86_mapping_info *info, > + pmd_t *pmdp, unsigned long __address) > +{ > + unsigned long page_flags; > + unsigned long address; > + pte_t *pte; > + pmd_t pmd; > + int i; > + > + pte = (pte_t *)info->alloc_pgt_page(info->context); > + if (!pte) > + return NULL; > + > + address = __address & PMD_MASK; > + /* No large page - clear PSE flag */ > + page_flags = info->page_flag & ~_PAGE_PSE; > + > + /* Populate the PTEs */ > + for (i = 0; i < PTRS_PER_PMD; i++) { > + set_pte(&pte[i], __pte(address | page_flags)); > + address += PAGE_SIZE; > + } > + > + /* > + * Ideally we need to clear the large PMD first and do a TLB > + * flush before we write the new PMD. But the 2M range of the > + * PMD might contain the code we execute and/or the stack > + * we are on, so we can't do that. But that should be safe here > + * because we are going from large to small mappings and we are > + * also the only user of the page-table, so there is no chance > + * of a TLB multihit. > + */ > + pmd = __pmd((unsigned long)pte | info->kernpg_flag); > + set_pmd(pmdp, pmd); > + /* Flush TLB to establish the new PMD */ > + write_cr3(top_level_pgt); > + > + return pte + pte_index(__address); > +} > + > +static void clflush_page(unsigned long address) > +{ > + unsigned int flush_size; > + char *cl, *start, *end; > + > + /* > + * Hardcode cl-size to 64 - CPUID can't be used here because that might > + * cause another #VC exception and the GHCB is not ready to use yet. > + */ > + flush_size = 64; > + start = (char *)(address & PAGE_MASK); > + end = start + PAGE_SIZE; > + > + /* > + * First make sure there are no pending writes on the cache-lines to > + * flush. > + */ > + asm volatile("mfence" : : : "memory"); > + > + for (cl = start; cl != end; cl += flush_size) > + clflush(cl); > +} > + > +static int __set_page_decrypted(struct x86_mapping_info *info, > + unsigned long address) > +{ > + unsigned long scratch, *target; > + pgd_t *pgdp = (pgd_t *)top_level_pgt; > + p4d_t *p4dp; > + pud_t *pudp; > + pmd_t *pmdp; > + pte_t *ptep, pte; > + > + /* > + * First make sure there is a PMD mapping for 'address'. > + * It should already exist, but keep things generic. > + * > + * To map the page just read from it and fault it in if there is no > + * mapping yet. add_identity_map() can't be called here because that > + * would unconditionally map the address on PMD level, destroying any > + * PTE-level mappings that might already exist. Also do something > + * useless with 'scratch' so the access won't be optimized away. > + */ > + target = (unsigned long *)address; > + scratch = *target; > + arch_cmpxchg(target, scratch, scratch); > + > + /* > + * The page is mapped at least with PMD size - so skip checks and walk > + * directly to the PMD. > + */ > + p4dp = p4d_offset(pgdp, address); > + pudp = pud_offset(p4dp, address); > + pmdp = pmd_offset(pudp, address); > + > + if (pmd_large(*pmdp)) > + ptep = split_large_pmd(info, pmdp, address); > + else > + ptep = pte_offset_kernel(pmdp, address); > + > + if (!ptep) > + return -ENOMEM; > + > + /* Clear encryption flag and write new pte */ > + pte = pte_clear_flags(*ptep, _PAGE_ENC); > + set_pte(ptep, pte); > + > + /* Flush TLB to map the page unencrypted */ > + write_cr3(top_level_pgt); > + Is there a guarantee that this flushes the tlb if cr3 == top_level_pgt alrady without an invlpg? > + /* > + * Changing encryption attributes of a page requires to flush it from > + * the caches. > + */ > + clflush_page(address); > + > + return 0; > +} > + > +int set_page_decrypted(unsigned long address) > +{ > + return __set_page_decrypted(&mapping_info, address); > +} > + > static void pf_error(unsigned long error_code, unsigned long address, > struct pt_regs *regs) > { > diff --git a/arch/x86/boot/compressed/misc.h b/arch/x86/boot/compressed/misc.h > index 0e3508c5c15c..42f68a858a35 100644 > --- a/arch/x86/boot/compressed/misc.h > +++ b/arch/x86/boot/compressed/misc.h > @@ -98,6 +98,7 @@ static inline void choose_random_location(unsigned long input, > #endif > > #ifdef CONFIG_X86_64 > +extern int set_page_decrypted(unsigned long address); > extern unsigned char _pgtable[]; > #endif >