From: Ard Biesheuvel <ardb+git@google.com>
To: linux-kernel@google.com
Cc: Ard Biesheuvel <ardb@kernel.org>,
Kevin Loughlin <kevinloughlin@google.com>,
Tom Lendacky <thomas.lendacky@amd.com>,
Dionna Glaze <dionnaglaze@google.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>,
linux-kernel@vger.kernel.org
Subject: [RFC PATCH v6.10 3/4] x86/boot/64: Determine VA/PA offset before entering C code
Date: Thu, 7 Mar 2024 15:30:31 +0100 [thread overview]
Message-ID: <20240307143027.206179-9-ardb+git@google.com> (raw)
In-Reply-To: <20240307143027.206179-6-ardb+git@google.com>
From: Ard Biesheuvel <ardb@kernel.org>
We will start using an explicit virtual-to-physical offset in the early
1:1 mapped C code to derive the kernel virtual addresses of _text and
_end without having to rely on absolute symbol references, which should
be avoided in such code.
Currently, phys_base is used for this purpose, which is derived from the
kernel virtual address of _text, and this would lead to a circular
dependency. So instead, derive virtual-to-physical offset in asm code,
using the kernel VA of common_startup_64, which we already keep in a
global variable for other reasons.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
arch/x86/include/asm/setup.h | 3 ++-
arch/x86/kernel/head64.c | 8 +++++---
arch/x86/kernel/head_64.S | 2 ++
3 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index e61e68d71cba..cc1994516af2 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -47,7 +47,8 @@ extern unsigned long saved_video_mode;
extern void reserve_standard_io_resources(void);
extern void i386_reserve_resources(void);
-extern unsigned long __startup_64(unsigned long physaddr, struct boot_params *bp);
+extern unsigned long __startup_64(unsigned long physaddr, struct boot_params *bp,
+ unsigned long va_offset);
extern void startup_64_setup_gdt_idt(void);
extern void early_setup_idt(void);
extern void __init do_early_exception(struct pt_regs *regs, int trapnr);
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index 212e8e06aeba..8fd80cf07691 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -131,10 +131,12 @@ static unsigned long __head sme_postprocess_startup(struct boot_params *bp, pmdv
* doesn't have to generate PC-relative relocations when accessing globals from
* that function. Clang actually does not generate them, which leads to
* boot-time crashes. To work around this problem, every global pointer must
- * be accessed using RIP_REL_REF().
+ * be accessed using RIP_REL_REF(). Kernel virtual addresses can be determined
+ * by subtracting va_offset from the RIP-relative address.
*/
unsigned long __head __startup_64(unsigned long physaddr,
- struct boot_params *bp)
+ struct boot_params *bp,
+ unsigned long va_offset)
{
pmd_t (*early_pgts)[PTRS_PER_PMD] = RIP_REL_REF(early_dynamic_pgts);
unsigned long pgtable_flags;
@@ -156,7 +158,7 @@ unsigned long __head __startup_64(unsigned long physaddr,
* Compute the delta between the address I am compiled to run at
* and the address I am actually running at.
*/
- load_delta = physaddr - (unsigned long)(_text - __START_KERNEL_map);
+ load_delta = __START_KERNEL_map + va_offset;
RIP_REL_REF(phys_base) = load_delta;
/* Is the address not 2M aligned? */
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 79f7c342e3da..3622744349d1 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -107,6 +107,8 @@ SYM_CODE_START_NOALIGN(startup_64)
*/
leaq _text(%rip), %rdi
movq %r15, %rsi
+ leaq common_startup_64(%rip), %rdx
+ subq 0f(%rip), %rdx
call __startup_64
/* Form the CR3 value being sure to include the CR3 modifier */
--
2.44.0.278.ge034bb2e1d-goog
next prev parent reply other threads:[~2024-03-07 14:30 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-07 14:30 [RFC PATCH v6.10 0/4] x86: Rid .head.text of all abs references Ard Biesheuvel
2024-03-07 14:30 ` [RFC PATCH v6.10 1/4] x86/sev: Avoid WARN()s in early boot code Ard Biesheuvel
2024-03-07 14:30 ` [RFC PATCH v6.10 2/4] x86/xen/pvh: Move startup code into .ref.text Ard Biesheuvel
2024-03-07 14:30 ` Ard Biesheuvel [this message]
2024-03-07 14:30 ` [RFC PATCH v6.10 4/4] x86/boot/64: Avoid intentional absolute symbol references in .head.text Ard Biesheuvel
2024-03-07 14:42 ` [RFC PATCH v6.10 0/4] x86: Rid .head.text of all abs references Ard Biesheuvel
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=20240307143027.206179-9-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=dionnaglaze@google.com \
--cc=keescook@chromium.org \
--cc=kevinloughlin@google.com \
--cc=linux-kernel@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 \
/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