From: Ross Lagerwall <ross.lagerwall@citrix.com>
Also cache it to avoid needing to repeatedly ask the firmware.
Signed-off-by: Ross Lagerwall <ross.lagerwall@citrix.com>
Signed-off-by: Gerald Elder-Vass <gerald.elder-vass@cloud.com>
---
CC: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
CC: "Daniel P. Smith" <dpsmith@apertussolutions.com>
CC: Jan Beulich <jbeulich@suse.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: Anthony PERARD <anthony.perard@vates.tech>
CC: Michal Orzel <michal.orzel@amd.com>
CC: Julien Grall <julien@xen.org>
CC: "Roger Pau Monné" <roger.pau@citrix.com>
CC: Stefano Stabellini <sstabellini@kernel.org>
v3:
- Fix build on ARM
---
xen/common/efi/boot.c | 24 ++++++++++++++++++++++++
xen/common/efi/runtime.c | 1 +
xen/include/xen/efi.h | 2 ++
3 files changed, 27 insertions(+)
diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
index e12fa1a7ec04..e7e3dffa7ddc 100644
--- a/xen/common/efi/boot.c
+++ b/xen/common/efi/boot.c
@@ -901,6 +901,28 @@ static void __init pre_parse(const struct file *file)
" last line will be ignored.\r\n");
}
+static void __init init_secure_boot_mode(void)
+{
+ static EFI_GUID __initdata gv_uuid = EFI_GLOBAL_VARIABLE;
+ EFI_STATUS status;
+ uint8_t data = 0;
+ UINTN size = sizeof(data);
+ UINT32 attr = 0;
+
+ status = efi_rs->GetVariable((CHAR16 *)L"SecureBoot", &gv_uuid, &attr,
+ &size, &data);
+
+ if ( status == EFI_NOT_FOUND ||
+ (status == EFI_SUCCESS &&
+ attr == (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS) &&
+ size == 1 && data == 0) )
+ /* Platform does not support Secure Boot or it's disabled. */
+ efi_secure_boot = false;
+ else
+ /* Everything else play it safe and assume enabled. */
+ efi_secure_boot = true;
+}
+
static void __init efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
{
efi_ih = ImageHandle;
@@ -915,6 +937,8 @@ static void __init efi_init(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTabl
StdOut = SystemTable->ConOut;
StdErr = SystemTable->StdErr ?: StdOut;
+
+ init_secure_boot_mode();
}
static void __init efi_console_set_mode(void)
diff --git a/xen/common/efi/runtime.c b/xen/common/efi/runtime.c
index 42386c6bde42..30d649ca5c1b 100644
--- a/xen/common/efi/runtime.c
+++ b/xen/common/efi/runtime.c
@@ -41,6 +41,7 @@ void efi_rs_leave(struct efi_rs_state *state);
unsigned int __read_mostly efi_num_ct;
const EFI_CONFIGURATION_TABLE *__read_mostly efi_ct;
+bool __ro_after_init efi_secure_boot;
unsigned int __read_mostly efi_version;
unsigned int __read_mostly efi_fw_revision;
const CHAR16 *__read_mostly efi_fw_vendor;
diff --git a/xen/include/xen/efi.h b/xen/include/xen/efi.h
index 623ed2ccdf31..723cb8085270 100644
--- a/xen/include/xen/efi.h
+++ b/xen/include/xen/efi.h
@@ -36,6 +36,8 @@ static inline bool efi_enabled(unsigned int feature)
}
#endif
+extern bool efi_secure_boot;
+
void efi_init_memory(void);
bool efi_boot_mem_unused(unsigned long *start, unsigned long *end);
bool efi_rs_using_pgtables(void);
--
2.47.3
On 05/09/2025 11:05 am, Gerald Elder-Vass wrote:
> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c
> index e12fa1a7ec04..e7e3dffa7ddc 100644
> --- a/xen/common/efi/boot.c
> +++ b/xen/common/efi/boot.c
> @@ -901,6 +901,28 @@ static void __init pre_parse(const struct file *file)
> " last line will be ignored.\r\n");
> }
>
> +static void __init init_secure_boot_mode(void)
> +{
> + static EFI_GUID __initdata gv_uuid = EFI_GLOBAL_VARIABLE;
> + EFI_STATUS status;
> + uint8_t data = 0;
> + UINTN size = sizeof(data);
> + UINT32 attr = 0;
> +
> + status = efi_rs->GetVariable((CHAR16 *)L"SecureBoot", &gv_uuid, &attr,
> + &size, &data);
This turns out to be a MISRA R7.4 violation, complaining about casing a
string literal to a non-const pointer.
The real problem here is that the EFI spec. GetVariable() ought to take
a const CHAR16 *, but doesn't.
We could fix this with:
diff --git a/xen/include/efi/efiapi.h b/xen/include/efi/efiapi.h
index a616d1238aa4..56775d553109 100644
--- a/xen/include/efi/efiapi.h
+++ b/xen/include/efi/efiapi.h
@@ -224,7 +224,7 @@ VOID
typedef
EFI_STATUS
(EFIAPI *EFI_GET_VARIABLE) (
- IN CHAR16 *VariableName,
+ IN const CHAR16 *VariableName,
IN EFI_GUID *VendorGuid,
OUT UINT32 *Attributes OPTIONAL,
IN OUT UINTN *DataSize,
but I fear this might get some objections.
I don't think we want to be deviating every use of GetVariable() for a
problem ultimately outside of our control.
Another option would be to have a wrapper for GetVariable() which does
the cast once, which lets us deviate in one place only.
Thoughts?
~Andrew
On 05.09.2025 12:36, Andrew Cooper wrote: > On 05/09/2025 11:05 am, Gerald Elder-Vass wrote: >> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c >> index e12fa1a7ec04..e7e3dffa7ddc 100644 >> --- a/xen/common/efi/boot.c >> +++ b/xen/common/efi/boot.c >> @@ -901,6 +901,28 @@ static void __init pre_parse(const struct file *file) >> " last line will be ignored.\r\n"); >> } >> >> +static void __init init_secure_boot_mode(void) >> +{ >> + static EFI_GUID __initdata gv_uuid = EFI_GLOBAL_VARIABLE; >> + EFI_STATUS status; >> + uint8_t data = 0; >> + UINTN size = sizeof(data); >> + UINT32 attr = 0; >> + >> + status = efi_rs->GetVariable((CHAR16 *)L"SecureBoot", &gv_uuid, &attr, >> + &size, &data); > > This turns out to be a MISRA R7.4 violation, complaining about casing a > string literal to a non-const pointer. > > The real problem here is that the EFI spec. GetVariable() ought to take > a const CHAR16 *, but doesn't. > > We could fix this with: > > diff --git a/xen/include/efi/efiapi.h b/xen/include/efi/efiapi.h > index a616d1238aa4..56775d553109 100644 > --- a/xen/include/efi/efiapi.h > +++ b/xen/include/efi/efiapi.h > @@ -224,7 +224,7 @@ VOID > typedef > EFI_STATUS > (EFIAPI *EFI_GET_VARIABLE) ( > - IN CHAR16 *VariableName, > + IN const CHAR16 *VariableName, > IN EFI_GUID *VendorGuid, > OUT UINT32 *Attributes OPTIONAL, > IN OUT UINTN *DataSize, > > but I fear this might get some objections. The interface lacking the const in principle means that we can't rely on there being implementations which actually do fiddle with the string. Hence ... > I don't think we want to be deviating every use of GetVariable() for a > problem ultimately outside of our control. > > Another option would be to have a wrapper for GetVariable() which does > the cast once, which lets us deviate in one place only. ... this doesn't look like a viable route to me. (Nor a scalable one, as down the road we then may need more such wrappers.) > Thoughts? Why not instead use static CHAR16 __initdata str_SecureBoot[] = L"SecureBoot"; and be done? Jan
On 05/09/2025 11:44 am, Jan Beulich wrote: > On 05.09.2025 12:36, Andrew Cooper wrote: >> On 05/09/2025 11:05 am, Gerald Elder-Vass wrote: >>> diff --git a/xen/common/efi/boot.c b/xen/common/efi/boot.c >>> index e12fa1a7ec04..e7e3dffa7ddc 100644 >>> --- a/xen/common/efi/boot.c >>> +++ b/xen/common/efi/boot.c >>> @@ -901,6 +901,28 @@ static void __init pre_parse(const struct file *file) >>> " last line will be ignored.\r\n"); >>> } >>> >>> +static void __init init_secure_boot_mode(void) >>> +{ >>> + static EFI_GUID __initdata gv_uuid = EFI_GLOBAL_VARIABLE; >>> + EFI_STATUS status; >>> + uint8_t data = 0; >>> + UINTN size = sizeof(data); >>> + UINT32 attr = 0; >>> + >>> + status = efi_rs->GetVariable((CHAR16 *)L"SecureBoot", &gv_uuid, &attr, >>> + &size, &data); >> This turns out to be a MISRA R7.4 violation, complaining about casing a >> string literal to a non-const pointer. >> >> The real problem here is that the EFI spec. GetVariable() ought to take >> a const CHAR16 *, but doesn't. >> >> We could fix this with: >> >> diff --git a/xen/include/efi/efiapi.h b/xen/include/efi/efiapi.h >> index a616d1238aa4..56775d553109 100644 >> --- a/xen/include/efi/efiapi.h >> +++ b/xen/include/efi/efiapi.h >> @@ -224,7 +224,7 @@ VOID >> typedef >> EFI_STATUS >> (EFIAPI *EFI_GET_VARIABLE) ( >> - IN CHAR16 *VariableName, >> + IN const CHAR16 *VariableName, >> IN EFI_GUID *VendorGuid, >> OUT UINT32 *Attributes OPTIONAL, >> IN OUT UINTN *DataSize, >> >> but I fear this might get some objections. > The interface lacking the const in principle means that we can't rely on > there being implementations which actually do fiddle with the string. Well, the IN and absence of OUT does mean this in practice. > Hence ... > >> I don't think we want to be deviating every use of GetVariable() for a >> problem ultimately outside of our control. >> >> Another option would be to have a wrapper for GetVariable() which does >> the cast once, which lets us deviate in one place only. > ... this doesn't look like a viable route to me. (Nor a scalable one, > as down the road we then may need more such wrappers.) > >> Thoughts? > Why not instead use > > static CHAR16 __initdata str_SecureBoot[] = L"SecureBoot"; > > and be done? I suppose, but that's still awkward to use. ~Andrew
© 2016 - 2025 Red Hat, Inc.