From 244b2c5ca8b14627e4a17755e5922221e121c771 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Wed, 09 Oct 2024 06:15:07 +0000
Subject: [PATCH] change system file
---
kernel/drivers/firmware/efi/efi-pstore.c | 90 ++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 80 insertions(+), 10 deletions(-)
diff --git a/kernel/drivers/firmware/efi/efi-pstore.c b/kernel/drivers/firmware/efi/efi-pstore.c
index 0f7d979..0ef086e 100644
--- a/kernel/drivers/firmware/efi/efi-pstore.c
+++ b/kernel/drivers/firmware/efi/efi-pstore.c
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0+
+
#include <linux/efi.h>
#include <linux/module.h>
#include <linux/pstore.h>
@@ -5,6 +7,8 @@
#include <linux/ucs2_string.h>
#define DUMP_NAME_LEN 66
+
+#define EFIVARS_DATA_SIZE_MAX 1024
static bool efivars_pstore_disable =
IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
@@ -15,6 +19,9 @@
(EFI_VARIABLE_NON_VOLATILE | \
EFI_VARIABLE_BOOTSERVICE_ACCESS | \
EFI_VARIABLE_RUNTIME_ACCESS)
+
+static LIST_HEAD(efi_pstore_list);
+static DECLARE_WORK(efivar_work, NULL);
static int efi_pstore_open(struct pstore_info *psi)
{
@@ -124,7 +131,7 @@
if (entry->deleting) {
list_del(&entry->list);
efivar_entry_iter_end();
- efivar_unregister(entry);
+ kfree(entry);
if (efivar_entry_iter_begin())
return -EINTR;
} else if (turn_off_scanning)
@@ -159,7 +166,7 @@
*
* @record: pstore record to pass to callback
*
- * You MUST call efivar_enter_iter_begin() before this function, and
+ * You MUST call efivar_entry_iter_begin() before this function, and
* efivar_entry_iter_end() afterwards.
*
*/
@@ -167,7 +174,7 @@
{
struct efivar_entry **pos = (struct efivar_entry **)&record->psi->data;
struct efivar_entry *entry, *n;
- struct list_head *head = &efivar_sysfs_list;
+ struct list_head *head = &efi_pstore_list;
int size = 0;
int ret;
@@ -261,8 +268,9 @@
ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
preemptible(), record->size, record->psi->buf);
- if (record->reason == KMSG_DUMP_OOPS)
- efivar_run_worker();
+ if (record->reason == KMSG_DUMP_OOPS && try_module_get(THIS_MODULE))
+ if (!schedule_work(&efivar_work))
+ module_put(THIS_MODULE);
return ret;
};
@@ -312,12 +320,12 @@
if (efivar_entry_iter_begin())
return -EINTR;
- found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list,
+ found = __efivar_entry_iter(efi_pstore_erase_func, &efi_pstore_list,
efi_name, &entry);
efivar_entry_iter_end();
if (found && !entry->scanning)
- efivar_unregister(entry);
+ kfree(entry);
return found ? 0 : -ENOENT;
}
@@ -352,16 +360,76 @@
.erase = efi_pstore_erase,
};
-static __init int efivars_pstore_init(void)
+static int efi_pstore_callback(efi_char16_t *name, efi_guid_t vendor,
+ unsigned long name_size, void *data)
{
- if (!efi_enabled(EFI_RUNTIME_SERVICES))
+ struct efivar_entry *entry;
+ int ret;
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return -ENOMEM;
+
+ memcpy(entry->var.VariableName, name, name_size);
+ entry->var.VendorGuid = vendor;
+
+ ret = efivar_entry_add(entry, &efi_pstore_list);
+ if (ret)
+ kfree(entry);
+
+ return ret;
+}
+
+static int efi_pstore_update_entry(efi_char16_t *name, efi_guid_t vendor,
+ unsigned long name_size, void *data)
+{
+ struct efivar_entry *entry = data;
+
+ if (efivar_entry_find(name, vendor, &efi_pstore_list, false))
return 0;
- if (!efivars_kobject())
+ memcpy(entry->var.VariableName, name, name_size);
+ memcpy(&(entry->var.VendorGuid), &vendor, sizeof(efi_guid_t));
+
+ return 1;
+}
+
+static void efi_pstore_update_entries(struct work_struct *work)
+{
+ struct efivar_entry *entry;
+ int err;
+
+ /* Add new sysfs entries */
+ while (1) {
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return;
+
+ err = efivar_init(efi_pstore_update_entry, entry,
+ false, &efi_pstore_list);
+ if (!err)
+ break;
+
+ efivar_entry_add(entry, &efi_pstore_list);
+ }
+
+ kfree(entry);
+ module_put(THIS_MODULE);
+}
+
+static __init int efivars_pstore_init(void)
+{
+ int ret;
+
+ if (!efivars_kobject() || !efivar_supports_writes())
return 0;
if (efivars_pstore_disable)
return 0;
+
+ ret = efivar_init(efi_pstore_callback, NULL, true, &efi_pstore_list);
+ if (ret)
+ return ret;
efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
if (!efi_pstore_info.buf)
@@ -375,6 +443,8 @@
efi_pstore_info.bufsize = 0;
}
+ INIT_WORK(&efivar_work, efi_pstore_update_entries);
+
return 0;
}
--
Gitblit v1.6.2