From: Ard Biesheuvel <ardb+git@google.com>
To: linux-kernel@vger.kernel.org
Cc: x86@kernel.org, Ard Biesheuvel <ardb@kernel.org>,
Tom Lendacky <thomas.lendacky@amd.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
Andy Lutomirski <luto@kernel.org>, Arnd Bergmann <arnd@arndb.de>,
Kees Cook <keescook@chromium.org>,
Brian Gerst <brgerst@gmail.com>,
Kevin Loughlin <kevinloughlin@google.com>
Subject: [PATCH v4 3/7] x86/boot/64: Avoid intentional absolute symbol references in .head.text
Date: Thu, 5 Dec 2024 12:28:08 +0100 [thread overview]
Message-ID: <20241205112804.3416920-12-ardb+git@google.com> (raw)
In-Reply-To: <20241205112804.3416920-9-ardb+git@google.com>
From: Ard Biesheuvel <ardb@kernel.org>
The code in .head.text executes from a 1:1 mapping and cannot generally
refer to global variables using their kernel virtual addresses. However,
there are some occurrences of such references that are valid: the kernel
virtual addresses of _text and _end are needed to populate the page
tables correctly, and some other section markers are used in a similar
way.
To avoid the need for making exceptions to the rule that .head.text must
not contain any absolute symbol references, derive these addresses from
the RIP-relative 1:1 mapped physical addresses, which can be safely
determined using RIP_REL_REF().
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/kernel/head64.c | 30 ++++++++++++--------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index a7cd4053eeb3..54f9a8faf212 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -91,9 +91,11 @@ static inline bool check_la57_support(void)
return true;
}
-static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdval_t *pmd)
+static unsigned long __head sme_postprocess_startup(struct boot_params *bp,
+ pmdval_t *pmd,
+ unsigned long p2v_offset)
{
- unsigned long vaddr, vaddr_end;
+ unsigned long paddr, paddr_end;
int i;
/* Encrypt the kernel and related (if SME is active) */
@@ -106,10 +108,10 @@ static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdv
* attribute.
*/
if (sme_get_me_mask()) {
- vaddr = (unsigned long)__start_bss_decrypted;
- vaddr_end = (unsigned long)__end_bss_decrypted;
+ paddr = (unsigned long)&RIP_REL_REF(__start_bss_decrypted);
+ paddr_end = (unsigned long)&RIP_REL_REF(__end_bss_decrypted);
- for (; vaddr < vaddr_end; vaddr += PMD_SIZE) {
+ for (; paddr < paddr_end; paddr += PMD_SIZE) {
/*
* On SNP, transition the page to shared in the RMP table so that
* it is consistent with the page table attribute change.
@@ -118,11 +120,11 @@ static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdv
* mapping (kernel .text). PVALIDATE, by way of
* early_snp_set_memory_shared(), requires a valid virtual
* address but the kernel is currently running off of the identity
- * mapping so use __pa() to get a *currently* valid virtual address.
+ * mapping so use the PA to get a *currently* valid virtual address.
*/
- early_snp_set_memory_shared(__pa(vaddr), __pa(vaddr), PTRS_PER_PMD);
+ early_snp_set_memory_shared(paddr, paddr, PTRS_PER_PMD);
- i = pmd_index(vaddr);
+ i = pmd_index(paddr - p2v_offset);
pmd[i] -= sme_get_me_mask();
}
}
@@ -146,6 +148,7 @@ unsigned long __head __startup_64(unsigned long p2v_offset,
{
pmd_t (*early_pgts)[PTRS_PER_PMD] = RIP_REL_REF(early_dynamic_pgts);
unsigned long physaddr = (unsigned long)&RIP_REL_REF(_text);
+ unsigned long va_text, va_end;
unsigned long pgtable_flags;
unsigned long load_delta;
pgdval_t *pgd;
@@ -172,6 +175,9 @@ unsigned long __head __startup_64(unsigned long p2v_offset,
if (load_delta & ~PMD_MASK)
for (;;);
+ va_text = physaddr - p2v_offset;
+ va_end = (unsigned long)&RIP_REL_REF(_end) - p2v_offset;
+
/* Include the SME encryption mask in the fixup value */
load_delta += sme_get_me_mask();
@@ -232,7 +238,7 @@ unsigned long __head __startup_64(unsigned long p2v_offset,
pmd_entry += sme_get_me_mask();
pmd_entry += physaddr;
- for (i = 0; i < DIV_ROUND_UP(_end - _text, PMD_SIZE); i++) {
+ for (i = 0; i < DIV_ROUND_UP(va_end - va_text, PMD_SIZE); i++) {
int idx = i + (physaddr >> PMD_SHIFT);
pmd[idx % PTRS_PER_PMD] = pmd_entry + i * PMD_SIZE;
@@ -257,11 +263,11 @@ unsigned long __head __startup_64(unsigned long p2v_offset,
pmd = &RIP_REL_REF(level2_kernel_pgt)->pmd;
/* invalidate pages before the kernel image */
- for (i = 0; i < pmd_index((unsigned long)_text); i++)
+ for (i = 0; i < pmd_index(va_text); i++)
pmd[i] &= ~_PAGE_PRESENT;
/* fixup pages that are part of the kernel image */
- for (; i <= pmd_index((unsigned long)_end); i++)
+ for (; i <= pmd_index(va_end); i++)
if (pmd[i] & _PAGE_PRESENT)
pmd[i] += load_delta;
@@ -269,7 +275,7 @@ unsigned long __head __startup_64(unsigned long p2v_offset,
for (; i < PTRS_PER_PMD; i++)
pmd[i] &= ~_PAGE_PRESENT;
- return sme_postprocess_startup(bp, pmd);
+ return sme_postprocess_startup(bp, pmd, p2v_offset);
}
/* Wipe all early page tables except for the kernel symbol map */
--
2.47.0.338.g60cca15819-goog
next prev parent reply other threads:[~2024-12-05 11:28 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-05 11:28 [PATCH v4 0/7] x86: Rid .head.text of all abs references Ard Biesheuvel
2024-12-05 11:28 ` [PATCH v4 1/7] x86/sev: Avoid WARN()s and panic()s in early boot code Ard Biesheuvel
2024-12-05 12:28 ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2025-01-06 15:23 ` [PATCH v4 1/7] " Tom Lendacky
2025-01-07 11:12 ` [tip: x86/boot] x86/sev: Don't hang but terminate on failure to remap SVSM CA tip-bot2 for Ard Biesheuvel
2024-12-05 11:28 ` [PATCH v4 2/7] x86/boot/64: Determine VA/PA offset before entering C code Ard Biesheuvel
2024-12-05 12:28 ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2024-12-05 11:28 ` Ard Biesheuvel [this message]
2024-12-05 12:28 ` [tip: x86/boot] x86/boot/64: Avoid intentional absolute symbol references in .head.text tip-bot2 for Ard Biesheuvel
2024-12-05 11:28 ` [PATCH v4 4/7] x86/boot: Disable UBSAN in early boot code Ard Biesheuvel
2024-12-05 12:28 ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2024-12-05 18:21 ` [PATCH v4 4/7] " kernel test robot
2024-12-05 11:28 ` [PATCH v4 5/7] x86/kernel: Move ENTRY_TEXT to the start of the image Ard Biesheuvel
2024-12-05 12:28 ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2024-12-05 11:28 ` [PATCH v4 6/7] x86/boot: Move .head.text into its own output section Ard Biesheuvel
2024-12-05 12:28 ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2024-12-05 11:28 ` [PATCH v4 7/7] x86/boot: Reject absolute references in .head.text Ard Biesheuvel
2024-12-05 12:28 ` [tip: x86/boot] " tip-bot2 for Ard Biesheuvel
2024-12-31 10:01 ` [PATCH v4 0/7] x86: Rid .head.text of all abs references Borislav Petkov
2024-12-31 10:12 ` Ard Biesheuvel
2024-12-31 10:35 ` Borislav Petkov
2024-12-31 19:29 ` Ard Biesheuvel
2025-01-01 2:43 ` Nathan Chancellor
2025-01-01 8:01 ` Ard Biesheuvel
2025-01-01 10:39 ` Borislav Petkov
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=20241205112804.3416920-12-ardb+git@google.com \
--to=ardb+git@google.com \
--cc=ardb@kernel.org \
--cc=arnd@arndb.de \
--cc=bp@alien8.de \
--cc=brgerst@gmail.com \
--cc=dave.hansen@linux.intel.com \
--cc=keescook@chromium.org \
--cc=kevinloughlin@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mingo@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.