Skip to content

Commit 937d96d

Browse files
committed
Merge tag 'efi-next-for-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI updates from Ard Biesheuvel: "Although some more stuff is brewing, the EFI changes that are ready for mainline are few this cycle: - improve the PCI DMA paranoia logic in the EFI stub - some constification changes - add statfs support to efivarfs - allow user space to enumerate updatable firmware resources without CAP_SYS_ADMIN" * tag 'efi-next-for-v6.5' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: efi/libstub: Disable PCI DMA before grabbing the EFI memory map efi/esrt: Allow ESRT access without CAP_SYS_ADMIN efivarfs: expose used and total size efi: make kobj_type structure constant efi: x86: make kobj_type structure constant
2 parents 5d95ff8 + 2e28a79 commit 937d96d

File tree

8 files changed

+75
-10
lines changed

8 files changed

+75
-10
lines changed

arch/x86/platform/efi/quirks.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ void efi_delete_dummy_variable(void)
114114
EFI_VARIABLE_RUNTIME_ACCESS, 0, NULL);
115115
}
116116

117+
u64 efivar_reserved_space(void)
118+
{
119+
if (efi_no_storage_paranoia)
120+
return 0;
121+
return EFI_MIN_RESERVE;
122+
}
123+
EXPORT_SYMBOL_GPL(efivar_reserved_space);
124+
117125
/*
118126
* In the nonblocking case we do not attempt to perform garbage
119127
* collection if we do not have enough free space. Rather, we do the

arch/x86/platform/efi/runtime-map.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static void map_release(struct kobject *kobj)
9393
kfree(entry);
9494
}
9595

96-
static struct kobj_type __refdata map_ktype = {
96+
static const struct kobj_type __refconst map_ktype = {
9797
.sysfs_ops = &map_attr_ops,
9898
.default_groups = def_groups,
9999
.release = map_release,

drivers/firmware/efi/efi.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ static int generic_ops_register(void)
214214
generic_ops.get_variable = efi.get_variable;
215215
generic_ops.get_next_variable = efi.get_next_variable;
216216
generic_ops.query_variable_store = efi_query_variable_store;
217+
generic_ops.query_variable_info = efi.query_variable_info;
217218

218219
if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) {
219220
generic_ops.set_variable = efi.set_variable;

drivers/firmware/efi/esrt.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ static ssize_t esre_attr_show(struct kobject *kobj,
9595
struct esre_entry *entry = to_entry(kobj);
9696
struct esre_attribute *attr = to_attr(_attr);
9797

98-
/* Don't tell normal users what firmware versions we've got... */
99-
if (!capable(CAP_SYS_ADMIN))
100-
return -EACCES;
101-
10298
return attr->show(entry, buf);
10399
}
104100

@@ -156,7 +152,7 @@ static void esre_release(struct kobject *kobj)
156152
kfree(entry);
157153
}
158154

159-
static struct kobj_type esre1_ktype = {
155+
static const struct kobj_type esre1_ktype = {
160156
.release = esre_release,
161157
.sysfs_ops = &esre_attr_ops,
162158
.default_groups = esre1_groups,

drivers/firmware/efi/libstub/efi-stub-helper.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,9 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
378378
struct efi_boot_memmap *map;
379379
efi_status_t status;
380380

381+
if (efi_disable_pci_dma)
382+
efi_pci_disable_bridge_busmaster();
383+
381384
status = efi_get_memory_map(&map, true);
382385
if (status != EFI_SUCCESS)
383386
return status;
@@ -388,9 +391,6 @@ efi_status_t efi_exit_boot_services(void *handle, void *priv,
388391
return status;
389392
}
390393

391-
if (efi_disable_pci_dma)
392-
efi_pci_disable_bridge_busmaster();
393-
394394
status = efi_bs_call(exit_boot_services, handle, map->map_key);
395395

396396
if (status == EFI_INVALID_PARAMETER) {

drivers/firmware/efi/vars.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,15 @@ efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
245245
return status;
246246
}
247247
EXPORT_SYMBOL_NS_GPL(efivar_set_variable, EFIVAR);
248+
249+
efi_status_t efivar_query_variable_info(u32 attr,
250+
u64 *storage_space,
251+
u64 *remaining_space,
252+
u64 *max_variable_size)
253+
{
254+
if (!__efivars->ops->query_variable_info)
255+
return EFI_UNSUPPORTED;
256+
return __efivars->ops->query_variable_info(attr, storage_space,
257+
remaining_space, max_variable_size);
258+
}
259+
EXPORT_SYMBOL_NS_GPL(efivar_query_variable_info, EFIVAR);

fs/efivarfs/super.c

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/ucs2_string.h>
1414
#include <linux/slab.h>
1515
#include <linux/magic.h>
16+
#include <linux/statfs.h>
1617

1718
#include "internal.h"
1819

@@ -23,8 +24,44 @@ static void efivarfs_evict_inode(struct inode *inode)
2324
clear_inode(inode);
2425
}
2526

27+
static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
28+
{
29+
const u32 attr = EFI_VARIABLE_NON_VOLATILE |
30+
EFI_VARIABLE_BOOTSERVICE_ACCESS |
31+
EFI_VARIABLE_RUNTIME_ACCESS;
32+
u64 storage_space, remaining_space, max_variable_size;
33+
efi_status_t status;
34+
35+
status = efivar_query_variable_info(attr, &storage_space, &remaining_space,
36+
&max_variable_size);
37+
if (status != EFI_SUCCESS)
38+
return efi_status_to_err(status);
39+
40+
/*
41+
* This is not a normal filesystem, so no point in pretending it has a block
42+
* size; we declare f_bsize to 1, so that we can then report the exact value
43+
* sent by EFI QueryVariableInfo in f_blocks and f_bfree
44+
*/
45+
buf->f_bsize = 1;
46+
buf->f_namelen = NAME_MAX;
47+
buf->f_blocks = storage_space;
48+
buf->f_bfree = remaining_space;
49+
buf->f_type = dentry->d_sb->s_magic;
50+
51+
/*
52+
* In f_bavail we declare the free space that the kernel will allow writing
53+
* when the storage_paranoia x86 quirk is active. To use more, users
54+
* should boot the kernel with efi_no_storage_paranoia.
55+
*/
56+
if (remaining_space > efivar_reserved_space())
57+
buf->f_bavail = remaining_space - efivar_reserved_space();
58+
else
59+
buf->f_bavail = 0;
60+
61+
return 0;
62+
}
2663
static const struct super_operations efivarfs_ops = {
27-
.statfs = simple_statfs,
64+
.statfs = efivarfs_statfs,
2865
.drop_inode = generic_delete_inode,
2966
.evict_inode = efivarfs_evict_inode,
3067
};

include/linux/efi.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,13 +1056,20 @@ struct efivar_operations {
10561056
efi_set_variable_t *set_variable;
10571057
efi_set_variable_t *set_variable_nonblocking;
10581058
efi_query_variable_store_t *query_variable_store;
1059+
efi_query_variable_info_t *query_variable_info;
10591060
};
10601061

10611062
struct efivars {
10621063
struct kset *kset;
10631064
const struct efivar_operations *ops;
10641065
};
10651066

1067+
#ifdef CONFIG_X86
1068+
u64 __attribute_const__ efivar_reserved_space(void);
1069+
#else
1070+
static inline u64 efivar_reserved_space(void) { return 0; }
1071+
#endif
1072+
10661073
/*
10671074
* The maximum size of VariableName + Data = 1024
10681075
* Therefore, it's reasonable to save that much
@@ -1101,6 +1108,10 @@ efi_status_t efivar_set_variable_locked(efi_char16_t *name, efi_guid_t *vendor,
11011108
efi_status_t efivar_set_variable(efi_char16_t *name, efi_guid_t *vendor,
11021109
u32 attr, unsigned long data_size, void *data);
11031110

1111+
efi_status_t efivar_query_variable_info(u32 attr, u64 *storage_space,
1112+
u64 *remaining_space,
1113+
u64 *max_variable_size);
1114+
11041115
#if IS_ENABLED(CONFIG_EFI_CAPSULE_LOADER)
11051116
extern bool efi_capsule_pending(int *reset_type);
11061117

0 commit comments

Comments
 (0)