Re: [PATCH 1/5] x86/sme: Clear decrypted BSS separately
From: Tom Lendacky
Date: Fri Jul 24 2026 - 15:57:11 EST
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.
> 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.
Thanks,
Tom