From: Rick Edgecombe <rick.p.edgecombe@intel.com>
To: x86@kernel.org, tglx@linutronix.de, mingo@redhat.com,
bp@alien8.de, dave.hansen@linux.intel.com, hpa@zytor.com,
luto@kernel.org, peterz@infradead.org,
kirill.shutemov@linux.intel.com, elena.reshetova@intel.com,
isaku.yamahata@intel.com, seanjc@google.com,
Michael Kelley <mikelley@microsoft.com>,
thomas.lendacky@amd.com, decui@microsoft.com,
sathyanarayanan.kuppuswamy@linux.intel.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Cc: rick.p.edgecombe@intel.com
Subject: [PATCH 02/10] x86/mm/cpa: Reject incorrect encryption change requests
Date: Tue, 17 Oct 2023 13:24:57 -0700 [thread overview]
Message-ID: <20231017202505.340906-3-rick.p.edgecombe@intel.com> (raw)
In-Reply-To: <20231017202505.340906-1-rick.p.edgecombe@intel.com>
Kernel memory is "encrypted" by default. Some callers may "decrypt" it
in order to share it with things outside the kernel like a device or an
untrusted VMM.
There is nothing to stop set_memory_encrypted() from being passed memory
that is already "encrypted" (aka. "private" on TDX). In fact, some
callers do this because ... $REASONS. Unfortunately, part of the TDX
decrypted=>encrypted transition is truly one way*. It can't handle
being asked to encrypt an already encrypted page
Allow __set_memory_enc_pgtable() to detect already-encrypted memory
before it hits the TDX code.
* The one way part is "page acceptance"
[commit log written by Dave Hansen]
Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
---
arch/x86/mm/pat/set_memory.c | 41 +++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
index bda9f129835e..1238b0db3e33 100644
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -2122,6 +2122,21 @@ int set_memory_global(unsigned long addr, int numpages)
__pgprot(_PAGE_GLOBAL), 0);
}
+static bool kernel_vaddr_encryped(unsigned long addr, bool enc)
+{
+ unsigned int level;
+ pte_t *pte;
+
+ pte = lookup_address(addr, &level);
+ if (!pte)
+ return false;
+
+ if (enc)
+ return pte_val(*pte) == cc_mkenc(pte_val(*pte));
+
+ return pte_val(*pte) == cc_mkdec(pte_val(*pte));
+}
+
/*
* __set_memory_enc_pgtable() is used for the hypervisors that get
* informed about "encryption" status via page tables.
@@ -2130,7 +2145,7 @@ static int __set_memory_enc_pgtable(unsigned long addr, int numpages, bool enc)
{
pgprot_t empty = __pgprot(0);
struct cpa_data cpa;
- int ret;
+ int ret, numpages_in_state = 0;
/* Should not be working on unaligned addresses */
if (WARN_ONCE(addr & ~PAGE_MASK, "misaligned address: %#lx\n", addr))
@@ -2143,6 +2158,30 @@ 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;
+ /*
+ * If any page is already in the right state, bail with an error
+ * because the code doesn't handled it. This is likely because
+ * something has gone wrong and isn't worth optimizing for.
+ *
+ * If all the memory pages are already in the desired state return
+ * success.
+ *
+ * kernel_vaddr_encryped() does not synchronize against huge page
+ * splits so take pgd_lock. A caller doing strange things could
+ * get a new PMD mid level PTE confused with a huge PMD entry. Just
+ * lock to tie up loose ends.
+ */
+ spin_lock(&pgd_lock);
+ for (int i = 0; i < numpages; i++) {
+ if (kernel_vaddr_encryped(addr + (PAGE_SIZE * i), enc))
+ numpages_in_state++;
+ }
+ spin_unlock(&pgd_lock);
+ if (numpages_in_state == numpages)
+ return 0;
+ else if (numpages_in_state)
+ return 1;
+
/* Must avoid aliasing mappings in the highmem code */
kmap_flush_unused();
vm_unmap_aliases();
--
2.34.1
next prev parent reply other threads:[~2023-10-17 20:25 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-17 20:24 [PATCH 00/10] Handle set_memory_XXcrypted() errors Rick Edgecombe
2023-10-17 20:24 ` [PATCH 01/10] mm: Add helper for freeing decrypted memory Rick Edgecombe
2023-10-17 20:24 ` Rick Edgecombe [this message]
2023-10-18 8:44 ` [PATCH 02/10] x86/mm/cpa: Reject incorrect encryption change requests Ingo Molnar
2023-10-18 15:53 ` Edgecombe, Rick P
2023-10-17 20:24 ` [PATCH 03/10] kvmclock: Use free_decrypted_pages() Rick Edgecombe
2023-10-18 5:20 ` Kuppuswamy Sathyanarayanan
2023-10-18 15:57 ` Edgecombe, Rick P
2023-10-17 20:24 ` [PATCH 04/10] swiotlb: " Rick Edgecombe
2023-10-18 4:43 ` Christoph Hellwig
2023-10-18 15:55 ` Edgecombe, Rick P
2023-10-31 10:43 ` Petr Tesařík
2023-10-31 15:54 ` Edgecombe, Rick P
2023-10-31 17:13 ` Petr Tesařík
2023-10-31 17:29 ` Edgecombe, Rick P
2023-11-01 6:27 ` Petr Tesařík
2023-11-01 14:40 ` Edgecombe, Rick P
2023-10-17 20:25 ` [PATCH 05/10] ptp: " Rick Edgecombe
2023-10-17 20:25 ` [PATCH 06/10] dma: " Rick Edgecombe
2023-10-18 6:24 ` Christoph Hellwig
2023-10-18 17:09 ` Edgecombe, Rick P
2023-10-18 17:42 ` Robin Murphy
2023-10-23 16:46 ` Edgecombe, Rick P
2023-10-23 17:22 ` Robin Murphy
2023-10-23 17:27 ` Edgecombe, Rick P
2023-10-17 20:25 ` [RFC 07/10] hv: " Rick Edgecombe
2023-10-17 20:25 ` [RFC 08/10] hv: Track decrypted status in vmbus_gpadl Rick Edgecombe
2023-10-17 20:25 ` [RFC 09/10] hv_nstvsc: Don't free decrypted memory Rick Edgecombe
2023-10-17 20:25 ` [RFC 10/10] uio_hv_generic: " Rick Edgecombe
2023-10-19 17:05 ` [PATCH 00/10] Handle set_memory_XXcrypted() errors Michael Kelley (LINUX)
2023-10-19 19:13 ` Dave Hansen
2023-10-23 16:47 ` Michael Kelley (LINUX)
2023-10-23 16:57 ` Dave Hansen
2023-10-23 17:01 ` Edgecombe, Rick P
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=20231017202505.340906-3-rick.p.edgecombe@intel.com \
--to=rick.p.edgecombe@intel.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=decui@microsoft.com \
--cc=elena.reshetova@intel.com \
--cc=hpa@zytor.com \
--cc=isaku.yamahata@intel.com \
--cc=kirill.shutemov@linux.intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux-s390@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mikelley@microsoft.com \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=sathyanarayanan.kuppuswamy@linux.intel.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--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