diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-05 11:59:05 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-09-05 11:59:05 -0700 |
| commit | 9f0346dcbea363787186c94ef94dd01aaa215afa (patch) | |
| tree | b81c168f4d0dbe4c7f4750f4598d48a6deb72094 /drivers/firmware/efi/efibc.c | |
| download | linux-stable-9f0346dcbea363787186c94ef94dd01aaa215afa.tar.gz linux-stable-9f0346dcbea363787186c94ef94dd01aaa215afa.zip | |
Merge tag 'driver-core-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-coregrafted
Pull driver core fixes from Danilo Krummrich:
- Fix kernfs listxattr() not returning security xattr names (e.g.
SELinux labels) when the kernfs node has no allocated kernfs_iattrs
- Fix silent truncation of IRQ vector indices in the Rust PCI
abstractions
- Don't select OF from DRIVER_PE_KUNIT_TEST; skip the test when OF is
disabled instead of silently enabling extra kernel functionality
- Russ Weight is retiring from kernel development; update the Firmware
Loader sysfs contact to the driver-core mailing list, add a CREDITS
entry for Firmware Upload, and update MAINTAINERS accordingly
* tag 'driver-core-7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core:
MAINTAINERS: Remove Russ Weight from Firmware Loader
CREDITS: Add CREDITS entry for Firmware Upload
firmware_loader: Change contact for sysfs nodes
rust: pci: reject IRQ vector indices that do not fit in u32
kernfs: preserve security xattrs without allocating iattrs
drivers: base: test: DRIVER_PE_KUNIT_TEST should not select OF
Diffstat (limited to 'drivers/firmware/efi/efibc.c')
| -rw-r--r-- | drivers/firmware/efi/efibc.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/drivers/firmware/efi/efibc.c b/drivers/firmware/efi/efibc.c new file mode 100644 index 000000000..345a10aa7 --- /dev/null +++ b/drivers/firmware/efi/efibc.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * efibc: control EFI bootloaders which obey LoaderEntryOneShot var + * Copyright (c) 2013-2016, Intel Corporation. + */ + +#define pr_fmt(fmt) "efibc: " fmt + +#include <linux/efi.h> +#include <linux/module.h> +#include <linux/reboot.h> +#include <linux/slab.h> +#include <linux/ucs2_string.h> + +#define MAX_DATA_LEN 512 + +static int efibc_set_variable(efi_char16_t *name, efi_char16_t *value, + unsigned long len) +{ + efi_status_t status; + + status = efi.set_variable(name, &LINUX_EFI_LOADER_ENTRY_GUID, + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS, + len * sizeof(efi_char16_t), value); + + if (status != EFI_SUCCESS) { + pr_err("failed to set EFI variable: 0x%lx\n", status); + return -EIO; + } + return 0; +} + +static int efibc_reboot_notifier_call(struct notifier_block *notifier, + unsigned long event, void *data) +{ + efi_char16_t *reason = event == SYS_RESTART ? L"reboot" + : L"shutdown"; + const u8 *str = data; + efi_char16_t *wdata; + unsigned long l; + int ret; + + ret = efibc_set_variable(L"LoaderEntryRebootReason", reason, + ucs2_strlen(reason)); + if (ret || !data) + return NOTIFY_DONE; + + wdata = kmalloc_objs(efi_char16_t, MAX_DATA_LEN); + if (!wdata) + return NOTIFY_DONE; + + for (l = 0; l < MAX_DATA_LEN - 1 && str[l] != '\0'; l++) + wdata[l] = str[l]; + wdata[l] = L'\0'; + + efibc_set_variable(L"LoaderEntryOneShot", wdata, l); + + kfree(wdata); + return NOTIFY_DONE; +} + +static struct notifier_block efibc_reboot_notifier = { + .notifier_call = efibc_reboot_notifier_call, +}; + +static int __init efibc_init(void) +{ + int ret; + + if (!efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) + return -ENODEV; + + ret = register_reboot_notifier(&efibc_reboot_notifier); + if (ret) + pr_err("unable to register reboot notifier\n"); + + return ret; +} +module_init(efibc_init); + +static void __exit efibc_exit(void) +{ + unregister_reboot_notifier(&efibc_reboot_notifier); +} +module_exit(efibc_exit); + +MODULE_AUTHOR("Jeremy Compostella <jeremy.compostella@intel.com>"); +MODULE_AUTHOR("Matt Gumbel <matthew.k.gumbel@intel.com"); +MODULE_DESCRIPTION("EFI Bootloader Control"); +MODULE_LICENSE("GPL v2"); |
