From nobody Fri Dec 19 04:09:15 2025 Received: from mail-wm1-f74.google.com (mail-wm1-f74.google.com [209.85.128.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1744F2857F7 for ; Thu, 10 Apr 2025 13:41:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744292506; cv=none; b=akTQwxtBWKbFsGmcOpdzcpEKx4/wXkp/UldzJ8tF7Y0dLuUOFS1jxn8RGcnbXtTqfnmJzIhWzQg577c3J+opPcs5xwjf7tfRabS5FWjtMQjul+OhF5YM1lj6ORLkgT3wqJdkGESQ/q4H3T1HfO03opT9qJuZRUb7fqB3KAPgZuA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1744292506; c=relaxed/simple; bh=t76Wg9mCJpGbQFO226Opa35P1ZmW8qq3cQ+2zwr1lR0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=D6OGoRvkzzZsd9ykLVltDsv0ZEheJNIMtSyRr/7MgNvaB0m7e7LLHiZhkt5eAehH92gyqTi0EDN8nlj6CoYvZf5VLRuBZwfb5m0XX6dy4C1OgLttRuD+ZgC+qMNRfBl+NQbPkMI73SItB1ftQigfjNeNdTNQCBIRAWkOkxl4MTA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=EwLhVq5u; arc=none smtp.client-ip=209.85.128.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--ardb.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="EwLhVq5u" Received: by mail-wm1-f74.google.com with SMTP id 5b1f17b1804b1-43947a0919aso6420225e9.0 for ; Thu, 10 Apr 2025 06:41:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1744292502; x=1744897302; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=gXw/UaNA/8PDNEKLJNHvZMJeXVXKbmGygtg1CpsGD6E=; b=EwLhVq5u/iw0xHCjxn5XexRQscw4vllX0kVfja2j2xe66Wt4Li4SPcMybLhk8YlW2P KW2raYoQzJaCDXzS4FIJpFrboen6d/u3DcrYWrvzcT4FiPIKV2XVkR4/Q94hf7PP23h9 AgjaIN0CFUpJhzxwRQbuXzIzRvJi5tjZmiAkfVXpOpcGaBeRtV7UYAfbxi+GD+MUGHfK 9fKdbsk6jZuxwdYMns8XGO3fVwytMAjasA5SctevO7nNA7GKCxOylVIwRrra5OBJIR4i cfLKoG/cvLFAvGo/ZzEaxtCPM2w7KTXeZMdc/ywyRVch5iNbrTcQ9QjUWLo/hiubWgLa dkeg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1744292502; x=1744897302; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=gXw/UaNA/8PDNEKLJNHvZMJeXVXKbmGygtg1CpsGD6E=; b=bnx75e8Hy8UfnCknLtDlNjXoNVG/UhGRKOgZzt/sWxr+zC+HqDHQIo/nNnLt5SoKW5 hT+J/k6+ZgG/hXCYf3RCkB32vBv9xJnvB5UXDIykv7WYG0se2dgnsz9PI3WZEXoJ7lSp 2kz+szLgCZDFDTzf5eedMVWwD1t1s+c3aan/zUQyXsBjYDNPrmJHr8rNbGqMjik23c5W ZKRSKjxXslc5k3ClaWlc9MhW/e5QJ6dARZfMIrRqSaQXpnSkFatIRZtsu+btwobIf/Xz n38tqfBgO/XATSa+o21uzY+pI6JYn8fvvcjVamOQ0ysgUCKW7/kqowIaz4zMSZNDrj1r lQrg== X-Forwarded-Encrypted: i=1; AJvYcCWxFiz1x0hlLjVYDGmaNvcZ12Khy2dm4pdJkDc7XDycbC/47ZzyYLZMKR5v+iHJgKzz1JFsTWX/3uttqMo=@vger.kernel.org X-Gm-Message-State: AOJu0YxGXkA77ZvCNT28/XaY/YtytN++IQhEX+4DKswMzX5gDwV8D3YH MLNF5EVqkpbPSYnycmdPVuZUtma7YICIiPF+7k2FJg00i67jgyeAyMRYu1UuYpvJx4Gtog== X-Google-Smtp-Source: AGHT+IEbBK7uSrQvOLZ1dSP0sU6X384GpC8H66VqBJri1LGrN5IkBkYGIS0pLmbALgbYAMDD1f3a53yZ X-Received: from wmcn12.prod.google.com ([2002:a05:600c:c0cc:b0:43c:f60a:4c59]) (user=ardb job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:3b97:b0:43c:fc00:f94f with SMTP id 5b1f17b1804b1-43f2d95ebf4mr26942655e9.23.1744292502500; Thu, 10 Apr 2025 06:41:42 -0700 (PDT) Date: Thu, 10 Apr 2025 15:41:19 +0200 In-Reply-To: <20250410134117.3713574-13-ardb+git@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250410134117.3713574-13-ardb+git@google.com> X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Developer-Signature: v=1; a=openpgp-sha256; l=8366; i=ardb@kernel.org; h=from:subject; bh=niWmrBdmld5Ut46NlyltJZwh2miFi8PLlQF/GqLQX1A=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JIf37qYatm4Sv1eo+PbiM8x+Hz899TWpBtxJTlwfO02qcm nniq4hkRykLgxgHg6yYIovA7L/vdp6eKFXrPEsWZg4rE8gQBi5OAZhITSLDf0frAGdhzqwPLl3O bz2UZl6IfSoYcNauXPHgRPPWiDW7nzEynLQ+b2t0N/gIjwu37MuLH4QPxJgfffp/l61F3vMnlks 2swIA X-Mailer: git-send-email 2.49.0.504.g3bcea36a83-goog Message-ID: <20250410134117.3713574-14-ardb+git@google.com> Subject: [PATCH v4 01/11] x86/asm: Make rip_rel_ptr() usable from fPIC code From: Ard Biesheuvel To: linux-efi@vger.kernel.org Cc: x86@kernel.org, mingo@kernel.org, linux-kernel@vger.kernel.org, Ard Biesheuvel , Tom Lendacky , Dionna Amalie Glaze , Kevin Loughlin Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Ard Biesheuvel RIP_REL_REF() is used in non-PIC C code that is called very early, before the kernel virtual mapping is up, which is the mapping that the linker expects. It is currently used in two different ways: - to refer to the value of a global variable, including as an lvalue in assignments; - to take the address of a global variable via the mapping that the code currently executes at. The former case is only needed in non-PIC code, as PIC code will never use absolute symbol references when the address of the symbol is not being used. But taking the address of a variable in PIC code may still require extra care, as a stack allocated struct assignment may be emitted as a memcpy() from a statically allocated copy in .rodata. For instance, this void startup_64_setup_gdt_idt(void) { struct desc_ptr startup_gdt_descr =3D { .address =3D (__force unsigned long)gdt_page.gdt, .size =3D GDT_SIZE - 1, }; may result in an absolute symbol reference in PIC code, even though the struct is allocated on the stack and populated at runtime. To address this case, make rip_rel_ptr() accessible in PIC code, and update any existing uses where the address of a global variable is taken using RIP_REL_REF. Once all code of this nature has been moved into arch/x86/boot/startup and built with -fPIC, RIP_REL_REF() can be retired, and only rip_rel_ptr() will remain. Signed-off-by: Ard Biesheuvel --- arch/x86/coco/sev/core.c | 2 +- arch/x86/coco/sev/shared.c | 4 ++-- arch/x86/include/asm/asm.h | 2 +- arch/x86/kernel/head64.c | 24 ++++++++++---------- arch/x86/mm/mem_encrypt_identity.c | 6 ++--- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c index b0c1a7a57497..832f7a7b10b2 100644 --- a/arch/x86/coco/sev/core.c +++ b/arch/x86/coco/sev/core.c @@ -2400,7 +2400,7 @@ static __head void svsm_setup(struct cc_blob_sev_info= *cc_info) * kernel was loaded (physbase), so the get the CA address using * RIP-relative addressing. */ - pa =3D (u64)&RIP_REL_REF(boot_svsm_ca_page); + pa =3D (u64)rip_rel_ptr(&boot_svsm_ca_page); =20 /* * Switch over to the boot SVSM CA while the current CA is still diff --git a/arch/x86/coco/sev/shared.c b/arch/x86/coco/sev/shared.c index 2e4122f8aa6b..04982d356803 100644 --- a/arch/x86/coco/sev/shared.c +++ b/arch/x86/coco/sev/shared.c @@ -475,7 +475,7 @@ static int sev_cpuid_hv(struct ghcb *ghcb, struct es_em= _ctxt *ctxt, struct cpuid */ static const struct snp_cpuid_table *snp_cpuid_get_table(void) { - return &RIP_REL_REF(cpuid_table_copy); + return rip_rel_ptr(&cpuid_table_copy); } =20 /* @@ -1681,7 +1681,7 @@ static bool __head svsm_setup_ca(const struct cc_blob= _sev_info *cc_info) * routine is running identity mapped when called, both by the decompress= or * code and the early kernel code. */ - if (!rmpadjust((unsigned long)&RIP_REL_REF(boot_ghcb_page), RMP_PG_SIZE_4= K, 1)) + if (!rmpadjust((unsigned long)rip_rel_ptr(&boot_ghcb_page), RMP_PG_SIZE_4= K, 1)) return false; =20 /* diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index cc2881576c2c..a9f07799e337 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -114,13 +114,13 @@ #endif =20 #ifndef __ASSEMBLER__ -#ifndef __pic__ static __always_inline __pure void *rip_rel_ptr(void *p) { asm("leaq %c1(%%rip), %0" : "=3Dr"(p) : "i"(p)); =20 return p; } +#ifndef __pic__ #define RIP_REL_REF(var) (*(typeof(&(var)))rip_rel_ptr(&(var))) #else #define RIP_REL_REF(var) (var) diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index fa9b6339975f..954d093f187b 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c @@ -106,8 +106,8 @@ static unsigned long __head sme_postprocess_startup(str= uct boot_params *bp, * attribute. */ if (sme_get_me_mask()) { - paddr =3D (unsigned long)&RIP_REL_REF(__start_bss_decrypted); - paddr_end =3D (unsigned long)&RIP_REL_REF(__end_bss_decrypted); + paddr =3D (unsigned long)rip_rel_ptr(__start_bss_decrypted); + paddr_end =3D (unsigned long)rip_rel_ptr(__end_bss_decrypted); =20 for (; paddr < paddr_end; paddr +=3D PMD_SIZE) { /* @@ -144,8 +144,8 @@ static unsigned long __head sme_postprocess_startup(str= uct boot_params *bp, unsigned long __head __startup_64(unsigned long p2v_offset, struct boot_params *bp) { - pmd_t (*early_pgts)[PTRS_PER_PMD] =3D RIP_REL_REF(early_dynamic_pgts); - unsigned long physaddr =3D (unsigned long)&RIP_REL_REF(_text); + pmd_t (*early_pgts)[PTRS_PER_PMD] =3D rip_rel_ptr(early_dynamic_pgts); + unsigned long physaddr =3D (unsigned long)rip_rel_ptr(_text); unsigned long va_text, va_end; unsigned long pgtable_flags; unsigned long load_delta; @@ -174,18 +174,18 @@ unsigned long __head __startup_64(unsigned long p2v_o= ffset, for (;;); =20 va_text =3D physaddr - p2v_offset; - va_end =3D (unsigned long)&RIP_REL_REF(_end) - p2v_offset; + va_end =3D (unsigned long)rip_rel_ptr(_end) - p2v_offset; =20 /* Include the SME encryption mask in the fixup value */ load_delta +=3D sme_get_me_mask(); =20 /* Fixup the physical addresses in the page table */ =20 - pgd =3D &RIP_REL_REF(early_top_pgt)->pgd; + pgd =3D rip_rel_ptr(early_top_pgt); pgd[pgd_index(__START_KERNEL_map)] +=3D load_delta; =20 if (IS_ENABLED(CONFIG_X86_5LEVEL) && la57) { - p4d =3D (p4dval_t *)&RIP_REL_REF(level4_kernel_pgt); + p4d =3D (p4dval_t *)rip_rel_ptr(level4_kernel_pgt); p4d[MAX_PTRS_PER_P4D - 1] +=3D load_delta; =20 pgd[pgd_index(__START_KERNEL_map)] =3D (pgdval_t)p4d | _PAGE_TABLE; @@ -258,7 +258,7 @@ unsigned long __head __startup_64(unsigned long p2v_off= set, * error, causing the BIOS to halt the system. */ =20 - pmd =3D &RIP_REL_REF(level2_kernel_pgt)->pmd; + pmd =3D rip_rel_ptr(level2_kernel_pgt); =20 /* invalidate pages before the kernel image */ for (i =3D 0; i < pmd_index(va_text); i++) @@ -531,7 +531,7 @@ static gate_desc bringup_idt_table[NUM_EXCEPTION_VECTOR= S] __page_aligned_data; static void __head startup_64_load_idt(void *vc_handler) { struct desc_ptr desc =3D { - .address =3D (unsigned long)&RIP_REL_REF(bringup_idt_table), + .address =3D (unsigned long)rip_rel_ptr(bringup_idt_table), .size =3D sizeof(bringup_idt_table) - 1, }; struct idt_data data; @@ -565,11 +565,11 @@ void early_setup_idt(void) */ void __head startup_64_setup_gdt_idt(void) { - struct desc_struct *gdt =3D (void *)(__force unsigned long)gdt_page.gdt; + struct gdt_page *gp =3D rip_rel_ptr((void *)(__force unsigned long)&gdt_p= age); void *handler =3D NULL; =20 struct desc_ptr startup_gdt_descr =3D { - .address =3D (unsigned long)&RIP_REL_REF(*gdt), + .address =3D (unsigned long)gp->gdt, .size =3D GDT_SIZE - 1, }; =20 @@ -582,7 +582,7 @@ void __head startup_64_setup_gdt_idt(void) "movl %%eax, %%es\n" : : "a"(__KERNEL_DS) : "memory"); =20 if (IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT)) - handler =3D &RIP_REL_REF(vc_no_ghcb); + handler =3D rip_rel_ptr(vc_no_ghcb); =20 startup_64_load_idt(handler); } diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_i= dentity.c index 5eecdd92da10..e7fb3779b35f 100644 --- a/arch/x86/mm/mem_encrypt_identity.c +++ b/arch/x86/mm/mem_encrypt_identity.c @@ -318,8 +318,8 @@ void __head sme_encrypt_kernel(struct boot_params *bp) * memory from being cached. */ =20 - kernel_start =3D (unsigned long)RIP_REL_REF(_text); - kernel_end =3D ALIGN((unsigned long)RIP_REL_REF(_end), PMD_SIZE); + kernel_start =3D (unsigned long)rip_rel_ptr(_text); + kernel_end =3D ALIGN((unsigned long)rip_rel_ptr(_end), PMD_SIZE); kernel_len =3D kernel_end - kernel_start; =20 initrd_start =3D 0; @@ -345,7 +345,7 @@ void __head sme_encrypt_kernel(struct boot_params *bp) * pagetable structures for the encryption of the kernel * pagetable structures for workarea (in case not currently mapped) */ - execute_start =3D workarea_start =3D (unsigned long)RIP_REL_REF(sme_worka= rea); + execute_start =3D workarea_start =3D (unsigned long)rip_rel_ptr(sme_worka= rea); execute_end =3D execute_start + (PAGE_SIZE * 2) + PMD_SIZE; execute_len =3D execute_end - execute_start; =20 --=20 2.49.0.504.g3bcea36a83-goog