Re: [PATCH 1/5] x86/sme: Clear decrypted BSS separately
From: Brian Gerst
Date: Fri Jul 24 2026 - 17:07:13 EST
On Fri, Jul 24, 2026 at 3:57 PM Tom Lendacky <thomas.lendacky@xxxxxxx> wrote:
>
> On 7/24/26 13:57, Brian Gerst wrote:
> > On Fri, Jul 24, 2026 at 12:42 PM Tom Lendacky <thomas.lendacky@xxxxxxx> wrote:
> >>
> >> On 7/23/26 22:02, Brian Gerst wrote:
> >>> The decrypted BSS section needs to be cleared after it is remapped as
> >>> decrypted memory. Separate it so that the normal BSS section can be
> >>> cleared earlier.
> >>>
> >>> Signed-off-by: Brian Gerst <brgerst@xxxxxxxxx>
> >>> ---
> >>> arch/x86/kernel/vmlinux.lds.S | 2 +-
> >>> arch/x86/mm/mem_encrypt_amd.c | 3 +++
> >>> 2 files changed, 4 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
> >>> index 2438b89a4620..e64c797e06c7 100644
> >>> --- a/arch/x86/kernel/vmlinux.lds.S
> >>> +++ b/arch/x86/kernel/vmlinux.lds.S
> >>> @@ -365,9 +365,9 @@ SECTIONS
> >>> *(.bss..page_aligned)
> >>> . = ALIGN(PAGE_SIZE);
> >>> *(BSS_MAIN)
> >>> - BSS_DECRYPTED
> >>> . = ALIGN(PAGE_SIZE);
> >>> __bss_stop = .;
> >>> + BSS_DECRYPTED
> >>> }
> >>>
> >>> /*
> >>> diff --git a/arch/x86/mm/mem_encrypt_amd.c b/arch/x86/mm/mem_encrypt_amd.c
> >>> index 2f8c32173972..d39e1e29bcb9 100644
> >>> --- a/arch/x86/mm/mem_encrypt_amd.c
> >>> +++ b/arch/x86/mm/mem_encrypt_amd.c
> >>> @@ -479,6 +479,9 @@ void __init sme_early_init(void)
> >>> if (!sme_me_mask)
> >>> return;
> >>>
> >>> + memset(__start_bss_decrypted, 0,
> >>> + (unsigned long) __end_bss_decrypted - (unsigned long) __start_bss_decrypted);
> >>> +
> >>
> >> I think this section needs to be cleared to zero regardless of whether SME
> >> or SEV (this section is mainly used for SEV) is active. For example KVM
> >> clock makes use of this section even if SEV is not active. So this should
> >> probably live in clear_bss(), no?
> >
> > This is how I understand the current order:
> > - The bss_decrypted section gets encrypted in sme_encrypt_kernel()
>
> That is true for SME, yes, for SEV it is already encrypted so
> sme_encrypt_kernel() returns without doing anything.
Thanks for the clarification.
> > because it's part of the final BSS section.
> > - It is then remapped as unencrypted in sme_postprocess_startup().
> > - clear_bss() then clears it
>
> Yes.
>
> >
> > When clear_bss() is called first, remapping it as unencrypted
> > scrambles that memory so it needs to be cleared again after remapping.
> > I could unconditionally clear it in the same place clear_bss() is
> > called now and not have it depend on encryption being enabled The
> > other alternative would be for sme_encrypt_kernel() to skip it and
> > leave it as unencrypted from the beginning.
>
> The __bss_decrypted attribute will cause a variable to be put in the
> bss_decrypted section. The KVM clock support puts a structure in that
> section. If we look at a non-SEV guest with this patch, that means that
> the bss_decrypted section is not cleared at all and KVM clock is valid for
> a non-SEV guest.
>
> If you add clearing the bss_decrypted section in patch #1 and #2, then the
> change the change you make in patch #1 to sme_early_init() should actually
> be put in #2.
>
> In other words, you can make #1 a "no functional change" patch by just
> updating clear_bss() to clear both bss and bss_decrypted. When you move
> clear_bss() in patch #2, you can add the memset() in sme_early_init() you
> originally added in #1 to cover the case of the mapping change for SME and
> SEV. A comment above it along the lines of indicating that bss_decrypted
> is cleared before the actual mapping was updated to make it
> decrypted/shared, so clear it now.
I think just moving the memset() to the start of sme_early_init) so
that it always runs will be sufficient. Since bss_decrypted section
only exists when CONFIG_AMD_MEM_ENCRYPT is enabled, keeping it with
related code avoids another #ifdef.