forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
efi: split efisubsystem from efivars
This registers /sys/firmware/efi/{,systab,efivars/} whenever EFI is enabled and the system is booted with EFI. This allows *) userspace to check for the existence of /sys/firmware/efi as a way to determine whether or it is running on an EFI system. *) 'mount -t efivarfs none /sys/firmware/efi/efivars' without manually loading any modules. [ Also, move the efivar API into vars.c and unconditionally compile it. This allows us to move efivars.c, which now only contains the sysfs variable code, into the firmware/efi directory. Note that the efivars.c filename is kept to maintain backwards compatability with the old efivars.ko module. With this patch it is now possible for efivarfs to be built without CONFIG_EFI_VARS - Matt ] Cc: Seiji Aguchi <seiji.aguchi@hds.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Mike Waychison <mikew@google.com> Cc: Kay Sievers <kay@vrfy.org> Cc: Jeremy Kerr <jk@ozlabs.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Chun-Yi Lee <jlee@suse.com> Cc: Andy Whitcroft <apw@canonical.com> Cc: Tobias Powalowski <tpowa@archlinux.org> Signed-off-by: Tom Gundersen <teg@jklm.no> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
- Loading branch information
Showing
8 changed files
with
769 additions
and
761 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
# | ||
# Makefile for linux kernel | ||
# | ||
obj-y += efi.o vars.o | ||
obj-$(CONFIG_EFI_VARS) += efivars.o | ||
obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
/* | ||
* efi.c - EFI subsystem | ||
* | ||
* Copyright (C) 2001,2003,2004 Dell <Matt_Domsch@dell.com> | ||
* Copyright (C) 2004 Intel Corporation <matthew.e.tolentino@intel.com> | ||
* Copyright (C) 2013 Tom Gundersen <teg@jklm.no> | ||
* | ||
* This code registers /sys/firmware/efi{,/efivars} when EFI is supported, | ||
* allowing the efivarfs to be mounted or the efivars module to be loaded. | ||
* The existance of /sys/firmware/efi may also be used by userspace to | ||
* determine that the system supports EFI. | ||
* | ||
* This file is released under the GPLv2. | ||
*/ | ||
|
||
#include <linux/kobject.h> | ||
#include <linux/module.h> | ||
#include <linux/init.h> | ||
#include <linux/device.h> | ||
#include <linux/efi.h> | ||
|
||
static struct kobject *efi_kobj; | ||
static struct kobject *efivars_kobj; | ||
|
||
/* | ||
* Let's not leave out systab information that snuck into | ||
* the efivars driver | ||
*/ | ||
static ssize_t systab_show(struct kobject *kobj, | ||
struct kobj_attribute *attr, char *buf) | ||
{ | ||
char *str = buf; | ||
|
||
if (!kobj || !buf) | ||
return -EINVAL; | ||
|
||
if (efi.mps != EFI_INVALID_TABLE_ADDR) | ||
str += sprintf(str, "MPS=0x%lx\n", efi.mps); | ||
if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) | ||
str += sprintf(str, "ACPI20=0x%lx\n", efi.acpi20); | ||
if (efi.acpi != EFI_INVALID_TABLE_ADDR) | ||
str += sprintf(str, "ACPI=0x%lx\n", efi.acpi); | ||
if (efi.smbios != EFI_INVALID_TABLE_ADDR) | ||
str += sprintf(str, "SMBIOS=0x%lx\n", efi.smbios); | ||
if (efi.hcdp != EFI_INVALID_TABLE_ADDR) | ||
str += sprintf(str, "HCDP=0x%lx\n", efi.hcdp); | ||
if (efi.boot_info != EFI_INVALID_TABLE_ADDR) | ||
str += sprintf(str, "BOOTINFO=0x%lx\n", efi.boot_info); | ||
if (efi.uga != EFI_INVALID_TABLE_ADDR) | ||
str += sprintf(str, "UGA=0x%lx\n", efi.uga); | ||
|
||
return str - buf; | ||
} | ||
|
||
static struct kobj_attribute efi_attr_systab = | ||
__ATTR(systab, 0400, systab_show, NULL); | ||
|
||
static struct attribute *efi_subsys_attrs[] = { | ||
&efi_attr_systab.attr, | ||
NULL, /* maybe more in the future? */ | ||
}; | ||
|
||
static struct attribute_group efi_subsys_attr_group = { | ||
.attrs = efi_subsys_attrs, | ||
}; | ||
|
||
static struct efivars generic_efivars; | ||
static struct efivar_operations generic_ops; | ||
|
||
static int generic_ops_register(void) | ||
{ | ||
generic_ops.get_variable = efi.get_variable; | ||
generic_ops.set_variable = efi.set_variable; | ||
generic_ops.get_next_variable = efi.get_next_variable; | ||
generic_ops.query_variable_info = efi.query_variable_info; | ||
|
||
return efivars_register(&generic_efivars, &generic_ops, efi_kobj); | ||
} | ||
|
||
static void generic_ops_unregister(void) | ||
{ | ||
efivars_unregister(&generic_efivars); | ||
} | ||
|
||
/* | ||
* We register the efi subsystem with the firmware subsystem and the | ||
* efivars subsystem with the efi subsystem, if the system was booted with | ||
* EFI. | ||
*/ | ||
static int __init efisubsys_init(void) | ||
{ | ||
int error; | ||
|
||
if (!efi_enabled(EFI_BOOT)) | ||
return 0; | ||
|
||
/* We register the efi directory at /sys/firmware/efi */ | ||
efi_kobj = kobject_create_and_add("efi", firmware_kobj); | ||
if (!efi_kobj) { | ||
pr_err("efi: Firmware registration failed.\n"); | ||
return -ENOMEM; | ||
} | ||
|
||
error = generic_ops_register(); | ||
if (error) | ||
goto err_put; | ||
|
||
error = sysfs_create_group(efi_kobj, &efi_subsys_attr_group); | ||
if (error) { | ||
pr_err("efi: Sysfs attribute export failed with error %d.\n", | ||
error); | ||
goto err_unregister; | ||
} | ||
|
||
/* and the standard mountpoint for efivarfs */ | ||
efivars_kobj = kobject_create_and_add("efivars", efi_kobj); | ||
if (!efivars_kobj) { | ||
pr_err("efivars: Subsystem registration failed.\n"); | ||
error = -ENOMEM; | ||
goto err_remove_group; | ||
} | ||
|
||
return 0; | ||
|
||
err_remove_group: | ||
sysfs_remove_group(efi_kobj, &efi_subsys_attr_group); | ||
err_unregister: | ||
generic_ops_unregister(); | ||
err_put: | ||
kobject_put(efi_kobj); | ||
return error; | ||
} | ||
|
||
subsys_initcall(efisubsys_init); |
Oops, something went wrong.