Thread (46 messages) 46 messages, 8 authors, 2024-02-03

Re: [PATCH v3 1/2] x86/sev: enforce RIP-relative accesses in early SEV/SME code

From: Kevin Loughlin <hidden>
Date: 2024-02-03 00:11:49
Also in: lkml, llvm

On Fri, Feb 2, 2024 at 2:47 PM Ard Biesheuvel [off-list ref] wrote:
On Fri, 2 Feb 2024 at 23:00, Kevin Loughlin [off-list ref] wrote:
quoted
On Wed, Jan 31, 2024 at 12:20 AM Kirill A. Shutemov
[off-list ref] wrote:
quoted
On Tue, Jan 30, 2024 at 10:08:44PM +0000, Kevin Loughlin wrote:
quoted
diff --git a/arch/x86/include/asm/mem_encrypt.h b/arch/x86/include/asm/mem_encrypt.h
index 359ada486fa9..b65e66ee79c4 100644
--- a/arch/x86/include/asm/mem_encrypt.h
+++ b/arch/x86/include/asm/mem_encrypt.h
@@ -17,6 +17,20 @@

 #include <asm/bootparam.h>

+/*
+ * Like the address operator "&", evaluates to the address of a LHS variable
+ * "var", but also enforces the use of RIP-relative logic. This macro can be
+ * used to safely access global data variables prior to kernel relocation.
+ */
+#define RIP_RELATIVE_ADDR(var)               \
+({                                   \
+     void *rip_rel_ptr;              \
+     asm ("lea "#var"(%%rip), %0"    \
+             : "=r" (rip_rel_ptr)    \
+             : "p" (&var));          \
+     rip_rel_ptr;                    \
+})
+
I don't think it is the right place for the macro. The next patch uses for
things unrelated to memory encryption.
You're right; with the cleanup, I agree it becomes more general. We
can move it to arch/x86/include/asm/asm.h.
quoted
quoted
@@ -239,14 +244,14 @@ unsigned long __head __startup_64(unsigned long physaddr,
       */

      next_pgt_ptr = fixup_pointer(&next_early_pgt, physaddr);
-     pud = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr);
-     pmd = fixup_pointer(early_dynamic_pgts[(*next_pgt_ptr)++], physaddr);
+     early_dynamic_pgts_ptr = fixup_pointer(early_dynamic_pgts, physaddr);
+     pud = (pudval_t *) early_dynamic_pgts_ptr[(*next_pgt_ptr)++];
+     pmd = (pmdval_t *) early_dynamic_pgts_ptr[(*next_pgt_ptr)++];
This change doesn't belong to this patch. Maybe move it into the next
patch and combine with removing fixup_pointer().
I'll put it in a separate commit even preceding this one, as it's
actually a bug in the existing fixup pointer logic that I noticed when
transitioning to the use of the RIP-relative macro. Specifically,
early_dynamic_pgts is a global variable just like next_early_pgt and
thus also needs to be fixed up to guarantee the correct address is
used across toolchains.
No, this is not a bug.

early_dynamic_pgts is a two dimensional array

extern pmd_t early_dynamic_pgts[EARLY_DYNAMIC_PAGE_TABLES][PTRS_PER_PMD];

and so this expression

early_dynamic_pgts[(*next_pgt_ptr)++]

produces the kernel virtual address of one of the top level elements,
which itself is an array, and so this can be fixed up as usual.
IOW, the [] operation does not result in pointer dereference here,
only in pointer arithmetic.
Ah, yes, you're right. Thanks for the correction! I will just drop it then.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help