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
This commit is contained in:
commit
ea185bdedb
5 changed files with 37 additions and 37 deletions
|
@ -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…
Add table
Reference in a new issue