EFI fixes for v6.14 #2
- Fix CPER error record parsing bugs
- Fix a couple of efivarfs issues that were introduced in the merge
window
- Fix an issue in the early remapping code of the MOKvar table
-----BEGIN PGP SIGNATURE-----
iHUEABYIAB0WIQQQm/3uucuRGn1Dmh0wbglWLn0tXAUCZ8G8cgAKCRAwbglWLn0t
XMQDAQDNgLENwTSbVZlJaXqc3EEb0hTeV1Rg1WG9gB5DJg5bFgD/ZoWxbY6um/Pn
Pa7jg3tCR4bINq7WRVbMAocORGN8ZAY=
=HbXA
-----END PGP SIGNATURE-----
Merge tag 'efi-fixes-for-v6.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI fixes from Ard Biesheuvel:
"Another couple of EFI fixes for v6.14.
Only James's patch stands out, as it implements a workaround for odd
behavior in fwupd in user space, which creates EFI variables by
touching a file in efivarfs, clearing the immutable bit (which gets
set automatically for $reasons) and then opening it again for writing,
none of which is really necessary.
The fwupd author and LVFS maintainer is already rolling out a fix for
this on the fwupd side, and suggested that the workaround in this PR
could be backed out again during the next cycle.
(There is a semantic mismatch in efivarfs where some essential
variable attributes are stored in the first 4 bytes of the file, and
so zero length files cannot exist, as they cannot be written back to
the underlying variable store. So now, they are dropped once the last
reference is released.)
Summary:
- Fix CPER error record parsing bugs
- Fix a couple of efivarfs issues that were introduced in the merge
window
- Fix an issue in the early remapping code of the MOKvar table"
* tag 'efi-fixes-for-v6.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
efi/mokvar-table: Avoid repeated map/unmap of the same page
efi: Don't map the entire mokvar table to determine its size
efivarfs: allow creation of zero length files
efivarfs: Defer PM notifier registration until .fill_super
efi/cper: Fix cper_arm_ctx_info alignment
efi/cper: Fix cper_ia_proc_ctx alignment
pull/1161/merge
commit
ea185bdedb
|
|
@ -311,7 +311,7 @@ void cper_print_proc_arm(const char *pfx,
|
|||
ctx_info = (struct cper_arm_ctx_info *)err_info;
|
||||
max_ctx_type = ARRAY_SIZE(arm_reg_ctx_strs) - 1;
|
||||
for (i = 0; i < proc->context_info_num; i++) {
|
||||
int size = sizeof(*ctx_info) + ctx_info->size;
|
||||
int size = ALIGN(sizeof(*ctx_info) + ctx_info->size, 16);
|
||||
|
||||
printk("%sContext info structure %d:\n", pfx, i);
|
||||
if (len < size) {
|
||||
|
|
|
|||
|
|
@ -325,7 +325,7 @@ void cper_print_proc_ia(const char *pfx, const struct cper_sec_proc_ia *proc)
|
|||
|
||||
ctx_info = (struct cper_ia_proc_ctx *)err_info;
|
||||
for (i = 0; i < VALID_PROC_CXT_INFO_NUM(proc->validation_bits); i++) {
|
||||
int size = sizeof(*ctx_info) + ctx_info->reg_arr_size;
|
||||
int size = ALIGN(sizeof(*ctx_info) + ctx_info->reg_arr_size, 16);
|
||||
int groupsize = 4;
|
||||
|
||||
printk("%sContext Information Structure %d:\n", pfx, i);
|
||||
|
|
|
|||
|
|
@ -99,14 +99,13 @@ static struct kobject *mokvar_kobj;
|
|||
*/
|
||||
void __init efi_mokvar_table_init(void)
|
||||
{
|
||||
struct efi_mokvar_table_entry __aligned(1) *mokvar_entry, *next_entry;
|
||||
efi_memory_desc_t md;
|
||||
void *va = NULL;
|
||||
unsigned long cur_offset = 0;
|
||||
unsigned long offset_limit;
|
||||
unsigned long map_size = 0;
|
||||
unsigned long map_size_needed = 0;
|
||||
unsigned long size;
|
||||
struct efi_mokvar_table_entry *mokvar_entry;
|
||||
int err;
|
||||
|
||||
if (!efi_enabled(EFI_MEMMAP))
|
||||
|
|
@ -134,48 +133,46 @@ void __init efi_mokvar_table_init(void)
|
|||
*/
|
||||
err = -EINVAL;
|
||||
while (cur_offset + sizeof(*mokvar_entry) <= offset_limit) {
|
||||
mokvar_entry = va + cur_offset;
|
||||
map_size_needed = cur_offset + sizeof(*mokvar_entry);
|
||||
if (map_size_needed > map_size) {
|
||||
if (va)
|
||||
early_memunmap(va, map_size);
|
||||
/*
|
||||
* Map a little more than the fixed size entry
|
||||
* header, anticipating some data. It's safe to
|
||||
* do so as long as we stay within current memory
|
||||
* descriptor.
|
||||
*/
|
||||
map_size = min(map_size_needed + 2*EFI_PAGE_SIZE,
|
||||
offset_limit);
|
||||
va = early_memremap(efi.mokvar_table, map_size);
|
||||
if (!va) {
|
||||
pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%lu.\n",
|
||||
efi.mokvar_table, map_size);
|
||||
return;
|
||||
}
|
||||
mokvar_entry = va + cur_offset;
|
||||
if (va)
|
||||
early_memunmap(va, sizeof(*mokvar_entry));
|
||||
va = early_memremap(efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
|
||||
if (!va) {
|
||||
pr_err("Failed to map EFI MOKvar config table pa=0x%lx, size=%zu.\n",
|
||||
efi.mokvar_table + cur_offset, sizeof(*mokvar_entry));
|
||||
return;
|
||||
}
|
||||
|
||||
mokvar_entry = va;
|
||||
next:
|
||||
/* Check for last sentinel entry */
|
||||
if (mokvar_entry->name[0] == '\0') {
|
||||
if (mokvar_entry->data_size != 0)
|
||||
break;
|
||||
err = 0;
|
||||
map_size_needed = cur_offset + sizeof(*mokvar_entry);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sanity check that the name is null terminated */
|
||||
size = strnlen(mokvar_entry->name,
|
||||
sizeof(mokvar_entry->name));
|
||||
if (size >= sizeof(mokvar_entry->name))
|
||||
break;
|
||||
/* Enforce that the name is NUL terminated */
|
||||
mokvar_entry->name[sizeof(mokvar_entry->name) - 1] = '\0';
|
||||
|
||||
/* Advance to the next entry */
|
||||
cur_offset = map_size_needed + mokvar_entry->data_size;
|
||||
size = sizeof(*mokvar_entry) + mokvar_entry->data_size;
|
||||
cur_offset += size;
|
||||
|
||||
/*
|
||||
* Don't bother remapping if the current entry header and the
|
||||
* next one end on the same page.
|
||||
*/
|
||||
next_entry = (void *)((unsigned long)mokvar_entry + size);
|
||||
if (((((unsigned long)(mokvar_entry + 1) - 1) ^
|
||||
((unsigned long)(next_entry + 1) - 1)) & PAGE_MASK) == 0) {
|
||||
mokvar_entry = next_entry;
|
||||
goto next;
|
||||
}
|
||||
}
|
||||
|
||||
if (va)
|
||||
early_memunmap(va, map_size);
|
||||
early_memunmap(va, sizeof(*mokvar_entry));
|
||||
if (err) {
|
||||
pr_err("EFI MOKvar config table is not valid\n");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -57,10 +57,11 @@ static ssize_t efivarfs_file_write(struct file *file,
|
|||
|
||||
if (bytes == -ENOENT) {
|
||||
/*
|
||||
* zero size signals to release that the write deleted
|
||||
* the variable
|
||||
* FIXME: temporary workaround for fwupdate, signal
|
||||
* failed write with a 1 to keep created but not
|
||||
* written files
|
||||
*/
|
||||
i_size_write(inode, 0);
|
||||
i_size_write(inode, 1);
|
||||
} else {
|
||||
i_size_write(inode, datasize + sizeof(attributes));
|
||||
inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
|
||||
|
|
@ -124,7 +125,8 @@ static int efivarfs_file_release(struct inode *inode, struct file *file)
|
|||
struct efivar_entry *var = inode->i_private;
|
||||
|
||||
inode_lock(inode);
|
||||
var->removed = (--var->open_count == 0 && i_size_read(inode) == 0);
|
||||
/* FIXME: temporary work around for fwupdate */
|
||||
var->removed = (--var->open_count == 0 && i_size_read(inode) == 1);
|
||||
inode_unlock(inode);
|
||||
|
||||
if (var->removed)
|
||||
|
|
|
|||
|
|
@ -367,6 +367,8 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc)
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
register_pm_notifier(&sfi->pm_nb);
|
||||
|
||||
return efivar_init(efivarfs_callback, sb, true);
|
||||
}
|
||||
|
||||
|
|
@ -552,7 +554,6 @@ static int efivarfs_init_fs_context(struct fs_context *fc)
|
|||
|
||||
sfi->pm_nb.notifier_call = efivarfs_pm_notify;
|
||||
sfi->pm_nb.priority = 0;
|
||||
register_pm_notifier(&sfi->pm_nb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue