[v4,07/11] efi/libstub: Add generic support for parsing mem_encrypt=

Message ID 20240213124143.1484862-20-ardb+git@google.com
State New
Headers
Series x86: Confine early 1:1 mapped startup code |

Commit Message

Ard Biesheuvel Feb. 13, 2024, 12:41 p.m. UTC
  From: Ard Biesheuvel <ardb@kernel.org>

Parse the mem_encrypt= command line parameter from the EFI stub if
CONFIG_ARCH_HAS_MEM_ENCRYPT=y, so that it can be passed to the early
boot code by the arch code in the stub.

This avoids the need for the core kernel to do any string parsing very
early in the boot.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
---
 drivers/firmware/efi/libstub/efi-stub-helper.c | 8 ++++++++
 drivers/firmware/efi/libstub/efistub.h         | 2 +-
 2 files changed, 9 insertions(+), 1 deletion(-)
  

Comments

Tom Lendacky Feb. 19, 2024, 5 p.m. UTC | #1
On 2/13/24 06:41, Ard Biesheuvel wrote:
> From: Ard Biesheuvel <ardb@kernel.org>
> 
> Parse the mem_encrypt= command line parameter from the EFI stub if
> CONFIG_ARCH_HAS_MEM_ENCRYPT=y, so that it can be passed to the early
> boot code by the arch code in the stub.
> 
> This avoids the need for the core kernel to do any string parsing very
> early in the boot.
> 
> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> ---
>   drivers/firmware/efi/libstub/efi-stub-helper.c | 8 ++++++++
>   drivers/firmware/efi/libstub/efistub.h         | 2 +-
>   2 files changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
> index bfa30625f5d0..3dc2f9aaf08d 100644
> --- a/drivers/firmware/efi/libstub/efi-stub-helper.c
> +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
> @@ -24,6 +24,8 @@ static bool efi_noinitrd;
>   static bool efi_nosoftreserve;
>   static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
>   
> +int efi_mem_encrypt;
> +
>   bool __pure __efi_soft_reserve_enabled(void)
>   {
>   	return !efi_nosoftreserve;
> @@ -75,6 +77,12 @@ efi_status_t efi_parse_options(char const *cmdline)
>   			efi_noinitrd = true;
>   		} else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
>   			efi_no5lvl = true;
> +		} else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
> +			   !strcmp(param, "mem_encrypt") && val) {
> +			if (parse_option_str(val, "on"))
> +				efi_mem_encrypt = 1;
> +			else if (parse_option_str(val, "off"))
> +				efi_mem_encrypt = -1;

With CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT having recently been 
removed, I'm not sure what parsing for mem_encrypt=off does.

(Same thing in the next patch.)

Thanks,
Tom

>   		} else if (!strcmp(param, "efi") && val) {
>   			efi_nochunk = parse_option_str(val, "nochunk");
>   			efi_novamap |= parse_option_str(val, "novamap");
> diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
> index 212687c30d79..a1c6ab24cd99 100644
> --- a/drivers/firmware/efi/libstub/efistub.h
> +++ b/drivers/firmware/efi/libstub/efistub.h
> @@ -37,8 +37,8 @@ extern bool efi_no5lvl;
>   extern bool efi_nochunk;
>   extern bool efi_nokaslr;
>   extern int efi_loglevel;
> +extern int efi_mem_encrypt;
>   extern bool efi_novamap;
> -
>   extern const efi_system_table_t *efi_system_table;
>   
>   typedef union efi_dxe_services_table efi_dxe_services_table_t;
  
Ard Biesheuvel Feb. 19, 2024, 5:06 p.m. UTC | #2
On Mon, 19 Feb 2024 at 18:00, Tom Lendacky <thomas.lendacky@amd.com> wrote:
>
> On 2/13/24 06:41, Ard Biesheuvel wrote:
> > From: Ard Biesheuvel <ardb@kernel.org>
> >
> > Parse the mem_encrypt= command line parameter from the EFI stub if
> > CONFIG_ARCH_HAS_MEM_ENCRYPT=y, so that it can be passed to the early
> > boot code by the arch code in the stub.
> >
> > This avoids the need for the core kernel to do any string parsing very
> > early in the boot.
> >
> > Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
> > ---
> >   drivers/firmware/efi/libstub/efi-stub-helper.c | 8 ++++++++
> >   drivers/firmware/efi/libstub/efistub.h         | 2 +-
> >   2 files changed, 9 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
> > index bfa30625f5d0..3dc2f9aaf08d 100644
> > --- a/drivers/firmware/efi/libstub/efi-stub-helper.c
> > +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
> > @@ -24,6 +24,8 @@ static bool efi_noinitrd;
> >   static bool efi_nosoftreserve;
> >   static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
> >
> > +int efi_mem_encrypt;
> > +
> >   bool __pure __efi_soft_reserve_enabled(void)
> >   {
> >       return !efi_nosoftreserve;
> > @@ -75,6 +77,12 @@ efi_status_t efi_parse_options(char const *cmdline)
> >                       efi_noinitrd = true;
> >               } else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
> >                       efi_no5lvl = true;
> > +             } else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
> > +                        !strcmp(param, "mem_encrypt") && val) {
> > +                     if (parse_option_str(val, "on"))
> > +                             efi_mem_encrypt = 1;
> > +                     else if (parse_option_str(val, "off"))
> > +                             efi_mem_encrypt = -1;
>
> With CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT having recently been
> removed, I'm not sure what parsing for mem_encrypt=off does.
>
> (Same thing in the next patch.)
>

We have to deal with both mem_encrypt=on and mem_encrypt=off occurring
on the command line. efi_parse_options() may be called more than once,
i.e., when there is a default command line baked into the image that
can be overridden at runtime. So if the baked in one has
mem_encrypt=on, mem_encrypt=off appearing later should counter that.

The same applies to the next patch, although the decompressor appears
to ignore the built-in command line entirely (I made a note of that in
the commit log)
  
Tom Lendacky Feb. 20, 2024, 7:28 p.m. UTC | #3
On 2/19/24 11:06, Ard Biesheuvel wrote:
> On Mon, 19 Feb 2024 at 18:00, Tom Lendacky <thomas.lendacky@amd.com> wrote:
>>
>> On 2/13/24 06:41, Ard Biesheuvel wrote:
>>> From: Ard Biesheuvel <ardb@kernel.org>
>>>
>>> Parse the mem_encrypt= command line parameter from the EFI stub if
>>> CONFIG_ARCH_HAS_MEM_ENCRYPT=y, so that it can be passed to the early
>>> boot code by the arch code in the stub.
>>>
>>> This avoids the need for the core kernel to do any string parsing very
>>> early in the boot.
>>>
>>> Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
>>> ---
>>>    drivers/firmware/efi/libstub/efi-stub-helper.c | 8 ++++++++
>>>    drivers/firmware/efi/libstub/efistub.h         | 2 +-
>>>    2 files changed, 9 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
>>> index bfa30625f5d0..3dc2f9aaf08d 100644
>>> --- a/drivers/firmware/efi/libstub/efi-stub-helper.c
>>> +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
>>> @@ -24,6 +24,8 @@ static bool efi_noinitrd;
>>>    static bool efi_nosoftreserve;
>>>    static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
>>>
>>> +int efi_mem_encrypt;
>>> +
>>>    bool __pure __efi_soft_reserve_enabled(void)
>>>    {
>>>        return !efi_nosoftreserve;
>>> @@ -75,6 +77,12 @@ efi_status_t efi_parse_options(char const *cmdline)
>>>                        efi_noinitrd = true;
>>>                } else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
>>>                        efi_no5lvl = true;
>>> +             } else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
>>> +                        !strcmp(param, "mem_encrypt") && val) {
>>> +                     if (parse_option_str(val, "on"))
>>> +                             efi_mem_encrypt = 1;
>>> +                     else if (parse_option_str(val, "off"))
>>> +                             efi_mem_encrypt = -1;
>>
>> With CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT having recently been
>> removed, I'm not sure what parsing for mem_encrypt=off does.
>>
>> (Same thing in the next patch.)
>>
> 
> We have to deal with both mem_encrypt=on and mem_encrypt=off occurring
> on the command line. efi_parse_options() may be called more than once,
> i.e., when there is a default command line baked into the image that
> can be overridden at runtime. So if the baked in one has
> mem_encrypt=on, mem_encrypt=off appearing later should counter that.
> 
> The same applies to the next patch, although the decompressor appears
> to ignore the built-in command line entirely (I made a note of that in
> the commit log)

Ah, makes sense.

Thanks,
Tom
  

Patch

diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index bfa30625f5d0..3dc2f9aaf08d 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -24,6 +24,8 @@  static bool efi_noinitrd;
 static bool efi_nosoftreserve;
 static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA);
 
+int efi_mem_encrypt;
+
 bool __pure __efi_soft_reserve_enabled(void)
 {
 	return !efi_nosoftreserve;
@@ -75,6 +77,12 @@  efi_status_t efi_parse_options(char const *cmdline)
 			efi_noinitrd = true;
 		} else if (IS_ENABLED(CONFIG_X86_64) && !strcmp(param, "no5lvl")) {
 			efi_no5lvl = true;
+		} else if (IS_ENABLED(CONFIG_ARCH_HAS_MEM_ENCRYPT) &&
+			   !strcmp(param, "mem_encrypt") && val) {
+			if (parse_option_str(val, "on"))
+				efi_mem_encrypt = 1;
+			else if (parse_option_str(val, "off"))
+				efi_mem_encrypt = -1;
 		} else if (!strcmp(param, "efi") && val) {
 			efi_nochunk = parse_option_str(val, "nochunk");
 			efi_novamap |= parse_option_str(val, "novamap");
diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h
index 212687c30d79..a1c6ab24cd99 100644
--- a/drivers/firmware/efi/libstub/efistub.h
+++ b/drivers/firmware/efi/libstub/efistub.h
@@ -37,8 +37,8 @@  extern bool efi_no5lvl;
 extern bool efi_nochunk;
 extern bool efi_nokaslr;
 extern int efi_loglevel;
+extern int efi_mem_encrypt;
 extern bool efi_novamap;
-
 extern const efi_system_table_t *efi_system_table;
 
 typedef union efi_dxe_services_table efi_dxe_services_table_t;