aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2013-02-08 10:48:51 -0500
committerMatt Fleming <matt.fleming@intel.com>2013-04-17 08:24:01 -0400
commit048517722cde2595a7366d0c3c72b8b1ec142a9c (patch)
tree1f54a4009c3f418285473e56bc930d606116bd11 /drivers/firmware
parente14ab23dde12b80db4c94b684a2e485b72b16af3 (diff)
efivars: Move pstore code into the new EFI directory
efivars.c has grown far too large and needs to be divided up. Create a new directory and move the persistence storage code to efi-pstore.c now that it uses the new efivar API. This helps us to greatly reduce the size of efivars.c and paves the way for moving other code out of efivars.c. Note that because CONFIG_EFI_VARS can be built as a module efi-pstore must also include support for building as a module. Reviewed-by: Tom Gundersen <teg@jklm.no> Tested-by: Tom Gundersen <teg@jklm.no> Cc: Seiji Aguchi <seiji.aguchi@hds.com> Cc: Anton Vorontsov <cbouatmailru@gmail.com> Cc: Colin Cross <ccross@android.com> Cc: Kees Cook <keescook@chromium.org> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Tony Luck <tony.luck@intel.com> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'drivers/firmware')
-rw-r--r--drivers/firmware/Kconfig36
-rw-r--r--drivers/firmware/Makefile1
-rw-r--r--drivers/firmware/efi/Kconfig39
-rw-r--r--drivers/firmware/efi/Makefile4
-rw-r--r--drivers/firmware/efi/efi-pstore.c244
-rw-r--r--drivers/firmware/efivars.c277
6 files changed, 301 insertions, 300 deletions
diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig
index 42c759a4d047..93876302fb2e 100644
--- a/drivers/firmware/Kconfig
+++ b/drivers/firmware/Kconfig
@@ -36,41 +36,6 @@ config FIRMWARE_MEMMAP
36 36
37 See also Documentation/ABI/testing/sysfs-firmware-memmap. 37 See also Documentation/ABI/testing/sysfs-firmware-memmap.
38 38
39config EFI_VARS
40 tristate "EFI Variable Support via sysfs"
41 depends on EFI
42 default n
43 help
44 If you say Y here, you are able to get EFI (Extensible Firmware
45 Interface) variable information via sysfs. You may read,
46 write, create, and destroy EFI variables through this interface.
47
48 Note that using this driver in concert with efibootmgr requires
49 at least test release version 0.5.0-test3 or later, which is
50 available from Matt Domsch's website located at:
51 <http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz>
52
53 Subsequent efibootmgr releases may be found at:
54 <http://linux.dell.com/efibootmgr>
55
56config EFI_VARS_PSTORE
57 bool "Register efivars backend for pstore"
58 depends on EFI_VARS && PSTORE
59 default y
60 help
61 Say Y here to enable use efivars as a backend to pstore. This
62 will allow writing console messages, crash dumps, or anything
63 else supported by pstore to EFI variables.
64
65config EFI_VARS_PSTORE_DEFAULT_DISABLE
66 bool "Disable using efivars as a pstore backend by default"
67 depends on EFI_VARS_PSTORE
68 default n
69 help
70 Saying Y here will disable the use of efivars as a storage
71 backend for pstore by default. This setting can be overridden
72 using the efivars module's pstore_disable parameter.
73
74config EFI_PCDP 39config EFI_PCDP
75 bool "Console device selection via EFI PCDP or HCDP table" 40 bool "Console device selection via EFI PCDP or HCDP table"
76 depends on ACPI && EFI && IA64 41 depends on ACPI && EFI && IA64
@@ -164,5 +129,6 @@ config ISCSI_IBFT
164 Otherwise, say N. 129 Otherwise, say N.
165 130
166source "drivers/firmware/google/Kconfig" 131source "drivers/firmware/google/Kconfig"
132source "drivers/firmware/efi/Kconfig"
167 133
168endmenu 134endmenu
diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile
index 5a7e27399729..31bf68c93593 100644
--- a/drivers/firmware/Makefile
+++ b/drivers/firmware/Makefile
@@ -14,3 +14,4 @@ obj-$(CONFIG_ISCSI_IBFT) += iscsi_ibft.o
14obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o 14obj-$(CONFIG_FIRMWARE_MEMMAP) += memmap.o
15 15
16obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ 16obj-$(CONFIG_GOOGLE_FIRMWARE) += google/
17obj-$(CONFIG_EFI) += efi/
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
new file mode 100644
index 000000000000..b0fc7c79dfbb
--- /dev/null
+++ b/drivers/firmware/efi/Kconfig
@@ -0,0 +1,39 @@
1menu "EFI (Extensible Firmware Interface) Support"
2 depends on EFI
3
4config EFI_VARS
5 tristate "EFI Variable Support via sysfs"
6 depends on EFI
7 default n
8 help
9 If you say Y here, you are able to get EFI (Extensible Firmware
10 Interface) variable information via sysfs. You may read,
11 write, create, and destroy EFI variables through this interface.
12
13 Note that using this driver in concert with efibootmgr requires
14 at least test release version 0.5.0-test3 or later, which is
15 available from Matt Domsch's website located at:
16 <http://linux.dell.com/efibootmgr/testing/efibootmgr-0.5.0-test3.tar.gz>
17
18 Subsequent efibootmgr releases may be found at:
19 <http://linux.dell.com/efibootmgr>
20
21config EFI_VARS_PSTORE
22 tristate "Register efivars backend for pstore"
23 depends on EFI_VARS && PSTORE
24 default y
25 help
26 Say Y here to enable use efivars as a backend to pstore. This
27 will allow writing console messages, crash dumps, or anything
28 else supported by pstore to EFI variables.
29
30config EFI_VARS_PSTORE_DEFAULT_DISABLE
31 bool "Disable using efivars as a pstore backend by default"
32 depends on EFI_VARS_PSTORE
33 default n
34 help
35 Saying Y here will disable the use of efivars as a storage
36 backend for pstore by default. This setting can be overridden
37 using the efivars module's pstore_disable parameter.
38
39endmenu
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile
new file mode 100644
index 000000000000..e03cd51525c2
--- /dev/null
+++ b/drivers/firmware/efi/Makefile
@@ -0,0 +1,4 @@
1#
2# Makefile for linux kernel
3#
4obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
new file mode 100644
index 000000000000..47ae712c9504
--- /dev/null
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -0,0 +1,244 @@
1#include <linux/efi.h>
2#include <linux/module.h>
3#include <linux/pstore.h>
4
5#define DUMP_NAME_LEN 52
6
7static bool efivars_pstore_disable =
8 IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
9
10module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
11
12#define PSTORE_EFI_ATTRIBUTES \
13 (EFI_VARIABLE_NON_VOLATILE | \
14 EFI_VARIABLE_BOOTSERVICE_ACCESS | \
15 EFI_VARIABLE_RUNTIME_ACCESS)
16
17static int efi_pstore_open(struct pstore_info *psi)
18{
19 efivar_entry_iter_begin();
20 psi->data = NULL;
21 return 0;
22}
23
24static int efi_pstore_close(struct pstore_info *psi)
25{
26 efivar_entry_iter_end();
27 psi->data = NULL;
28 return 0;
29}
30
31struct pstore_read_data {
32 u64 *id;
33 enum pstore_type_id *type;
34 int *count;
35 struct timespec *timespec;
36 char **buf;
37};
38
39static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
40{
41 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
42 struct pstore_read_data *cb_data = data;
43 char name[DUMP_NAME_LEN];
44 int i;
45 int cnt;
46 unsigned int part;
47 unsigned long time, size;
48
49 if (efi_guidcmp(entry->var.VendorGuid, vendor))
50 return 0;
51
52 for (i = 0; i < DUMP_NAME_LEN; i++)
53 name[i] = entry->var.VariableName[i];
54
55 if (sscanf(name, "dump-type%u-%u-%d-%lu",
56 cb_data->type, &part, &cnt, &time) == 4) {
57 *cb_data->id = part;
58 *cb_data->count = cnt;
59 cb_data->timespec->tv_sec = time;
60 cb_data->timespec->tv_nsec = 0;
61 } else if (sscanf(name, "dump-type%u-%u-%lu",
62 cb_data->type, &part, &time) == 3) {
63 /*
64 * Check if an old format,
65 * which doesn't support holding
66 * multiple logs, remains.
67 */
68 *cb_data->id = part;
69 *cb_data->count = 0;
70 cb_data->timespec->tv_sec = time;
71 cb_data->timespec->tv_nsec = 0;
72 } else
73 return 0;
74
75 __efivar_entry_size(entry, &size);
76 *cb_data->buf = kmalloc(size, GFP_KERNEL);
77 if (*cb_data->buf == NULL)
78 return -ENOMEM;
79 memcpy(*cb_data->buf, entry->var.Data, size);
80 return size;
81}
82
83static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
84 int *count, struct timespec *timespec,
85 char **buf, struct pstore_info *psi)
86{
87 struct pstore_read_data data;
88
89 data.id = id;
90 data.type = type;
91 data.count = count;
92 data.timespec = timespec;
93 data.buf = buf;
94
95 return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
96 (struct efivar_entry **)&psi->data);
97}
98
99static int efi_pstore_write(enum pstore_type_id type,
100 enum kmsg_dump_reason reason, u64 *id,
101 unsigned int part, int count, size_t size,
102 struct pstore_info *psi)
103{
104 char name[DUMP_NAME_LEN];
105 efi_char16_t efi_name[DUMP_NAME_LEN];
106 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
107 int i, ret = 0;
108
109 sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count,
110 get_seconds());
111
112 for (i = 0; i < DUMP_NAME_LEN; i++)
113 efi_name[i] = name[i];
114
115 efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
116 !pstore_cannot_block_path(reason),
117 size, psi->buf);
118
119 if (reason == KMSG_DUMP_OOPS)
120 efivar_run_worker();
121
122 *id = part;
123 return ret;
124};
125
126struct pstore_erase_data {
127 u64 id;
128 enum pstore_type_id type;
129 int count;
130 struct timespec time;
131 efi_char16_t *name;
132};
133
134/*
135 * Clean up an entry with the same name
136 */
137static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
138{
139 struct pstore_erase_data *ed = data;
140 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
141 efi_char16_t efi_name_old[DUMP_NAME_LEN];
142 efi_char16_t *efi_name = ed->name;
143 unsigned long utf16_len = utf16_strlen(ed->name);
144 char name_old[DUMP_NAME_LEN];
145 int i;
146
147 if (efi_guidcmp(entry->var.VendorGuid, vendor))
148 return 0;
149
150 if (utf16_strncmp(entry->var.VariableName,
151 efi_name, (size_t)utf16_len)) {
152 /*
153 * Check if an old format, which doesn't support
154 * holding multiple logs, remains.
155 */
156 sprintf(name_old, "dump-type%u-%u-%lu", ed->type,
157 (unsigned int)ed->id, ed->time.tv_sec);
158
159 for (i = 0; i < DUMP_NAME_LEN; i++)
160 efi_name_old[i] = name_old[i];
161
162 if (utf16_strncmp(entry->var.VariableName, efi_name_old,
163 utf16_strlen(efi_name_old)))
164 return 0;
165 }
166
167 /* found */
168 __efivar_entry_delete(entry);
169 return 1;
170}
171
172static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
173 struct timespec time, struct pstore_info *psi)
174{
175 struct pstore_erase_data edata;
176 struct efivar_entry *entry;
177 char name[DUMP_NAME_LEN];
178 efi_char16_t efi_name[DUMP_NAME_LEN];
179 int found, i;
180
181 sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
182 time.tv_sec);
183
184 for (i = 0; i < DUMP_NAME_LEN; i++)
185 efi_name[i] = name[i];
186
187 edata.id = id;
188 edata.type = type;
189 edata.count = count;
190 edata.time = time;
191 edata.name = efi_name;
192
193 efivar_entry_iter_begin();
194 found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
195 efivar_entry_iter_end();
196
197 if (found)
198 efivar_unregister(entry);
199
200 return 0;
201}
202
203static struct pstore_info efi_pstore_info = {
204 .owner = THIS_MODULE,
205 .name = "efi",
206 .open = efi_pstore_open,
207 .close = efi_pstore_close,
208 .read = efi_pstore_read,
209 .write = efi_pstore_write,
210 .erase = efi_pstore_erase,
211};
212
213static __init int efivars_pstore_init(void)
214{
215 if (!efi_enabled(EFI_RUNTIME_SERVICES))
216 return 0;
217
218 if (!efivars_kobject())
219 return 0;
220
221 if (efivars_pstore_disable)
222 return 0;
223
224 efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
225 if (!efi_pstore_info.buf)
226 return -ENOMEM;
227
228 efi_pstore_info.bufsize = 1024;
229 spin_lock_init(&efi_pstore_info.buf_lock);
230
231 pstore_register(&efi_pstore_info);
232
233 return 0;
234}
235
236static __exit void efivars_pstore_exit(void)
237{
238}
239
240module_init(efivars_pstore_init);
241module_exit(efivars_pstore_exit);
242
243MODULE_DESCRIPTION("EFI variable backend for pstore");
244MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 82fd145ead3b..5e7c3b1acde9 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -78,7 +78,6 @@
78#include <linux/kobject.h> 78#include <linux/kobject.h>
79#include <linux/device.h> 79#include <linux/device.h>
80#include <linux/slab.h> 80#include <linux/slab.h>
81#include <linux/pstore.h>
82#include <linux/ctype.h> 81#include <linux/ctype.h>
83 82
84#include <linux/fs.h> 83#include <linux/fs.h>
@@ -95,15 +94,9 @@ MODULE_DESCRIPTION("sysfs interface to EFI Variables");
95MODULE_LICENSE("GPL"); 94MODULE_LICENSE("GPL");
96MODULE_VERSION(EFIVARS_VERSION); 95MODULE_VERSION(EFIVARS_VERSION);
97 96
98#define DUMP_NAME_LEN 52
99
100static LIST_HEAD(efivarfs_list); 97static LIST_HEAD(efivarfs_list);
101static LIST_HEAD(efivar_sysfs_list); 98LIST_HEAD(efivar_sysfs_list);
102 99EXPORT_SYMBOL_GPL(efivar_sysfs_list);
103static bool efivars_pstore_disable =
104 IS_ENABLED(CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE);
105
106module_param_named(pstore_disable, efivars_pstore_disable, bool, 0644);
107 100
108struct efivar_attribute { 101struct efivar_attribute {
109 struct attribute attr; 102 struct attribute attr;
@@ -114,11 +107,6 @@ struct efivar_attribute {
114/* Private pointer to registered efivars */ 107/* Private pointer to registered efivars */
115static struct efivars *__efivars; 108static struct efivars *__efivars;
116 109
117#define PSTORE_EFI_ATTRIBUTES \
118 (EFI_VARIABLE_NON_VOLATILE | \
119 EFI_VARIABLE_BOOTSERVICE_ACCESS | \
120 EFI_VARIABLE_RUNTIME_ACCESS)
121
122static struct kset *efivars_kset; 110static struct kset *efivars_kset;
123 111
124static struct bin_attribute *efivars_new_var; 112static struct bin_attribute *efivars_new_var;
@@ -148,34 +136,6 @@ static void efivar_update_sysfs_entries(struct work_struct *);
148static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries); 136static DECLARE_WORK(efivar_work, efivar_update_sysfs_entries);
149static bool efivar_wq_enabled = true; 137static bool efivar_wq_enabled = true;
150 138
151/*
152 * Return the number of bytes is the length of this string
153 * Note: this is NOT the same as the number of unicode characters
154 */
155static inline unsigned long
156utf16_strsize(efi_char16_t *data, unsigned long maxlength)
157{
158 return utf16_strnlen(data, maxlength/sizeof(efi_char16_t)) * sizeof(efi_char16_t);
159}
160
161static inline int
162utf16_strncmp(const efi_char16_t *a, const efi_char16_t *b, size_t len)
163{
164 while (1) {
165 if (len == 0)
166 return 0;
167 if (*a < *b)
168 return -1;
169 if (*a > *b)
170 return 1;
171 if (*a == 0) /* implies *b == 0 */
172 return 0;
173 a++;
174 b++;
175 len--;
176 }
177}
178
179static bool 139static bool
180validate_device_path(struct efi_variable *var, int match, u8 *buffer, 140validate_device_path(struct efi_variable *var, int match, u8 *buffer,
181 unsigned long len) 141 unsigned long len)
@@ -598,12 +558,6 @@ static struct kobj_type efivar_ktype = {
598 .default_attrs = def_attrs, 558 .default_attrs = def_attrs,
599}; 559};
600 560
601static inline void
602efivar_unregister(struct efivar_entry *var)
603{
604 kobject_put(&var->kobj);
605}
606
607static int efivarfs_file_open(struct inode *inode, struct file *file) 561static int efivarfs_file_open(struct inode *inode, struct file *file)
608{ 562{
609 file->private_data = inode->i_private; 563 file->private_data = inode->i_private;
@@ -1130,220 +1084,6 @@ static const struct inode_operations efivarfs_dir_inode_operations = {
1130 .create = efivarfs_create, 1084 .create = efivarfs_create,
1131}; 1085};
1132 1086
1133#ifdef CONFIG_EFI_VARS_PSTORE
1134
1135static int efi_pstore_open(struct pstore_info *psi)
1136{
1137 efivar_entry_iter_begin();
1138 psi->data = NULL;
1139 return 0;
1140}
1141
1142static int efi_pstore_close(struct pstore_info *psi)
1143{
1144 efivar_entry_iter_end();
1145 psi->data = NULL;
1146 return 0;
1147}
1148
1149struct pstore_read_data {
1150 u64 *id;
1151 enum pstore_type_id *type;
1152 int *count;
1153 struct timespec *timespec;
1154 char **buf;
1155};
1156
1157static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
1158{
1159 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1160 struct pstore_read_data *cb_data = data;
1161 char name[DUMP_NAME_LEN];
1162 int i;
1163 int cnt;
1164 unsigned int part;
1165 unsigned long time, size;
1166
1167 if (efi_guidcmp(entry->var.VendorGuid, vendor))
1168 return 0;
1169
1170 for (i = 0; i < DUMP_NAME_LEN; i++)
1171 name[i] = entry->var.VariableName[i];
1172
1173 if (sscanf(name, "dump-type%u-%u-%d-%lu",
1174 cb_data->type, &part, &cnt, &time) == 4) {
1175 *cb_data->id = part;
1176 *cb_data->count = cnt;
1177 cb_data->timespec->tv_sec = time;
1178 cb_data->timespec->tv_nsec = 0;
1179 } else if (sscanf(name, "dump-type%u-%u-%lu",
1180 cb_data->type, &part, &time) == 3) {
1181 /*
1182 * Check if an old format,
1183 * which doesn't support holding
1184 * multiple logs, remains.
1185 */
1186 *cb_data->id = part;
1187 *cb_data->count = 0;
1188 cb_data->timespec->tv_sec = time;
1189 cb_data->timespec->tv_nsec = 0;
1190 } else
1191 return 0;
1192
1193 __efivar_entry_size(entry, &size);
1194 *cb_data->buf = kmalloc(size, GFP_KERNEL);
1195 if (*cb_data->buf == NULL)
1196 return -ENOMEM;
1197 memcpy(*cb_data->buf, entry->var.Data, size);
1198 return size;
1199}
1200
1201static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,
1202 int *count, struct timespec *timespec,
1203 char **buf, struct pstore_info *psi)
1204{
1205 struct pstore_read_data data;
1206
1207 data.id = id;
1208 data.type = type;
1209 data.count = count;
1210 data.timespec = timespec;
1211 data.buf = buf;
1212
1213 return __efivar_entry_iter(efi_pstore_read_func, &efivar_sysfs_list, &data,
1214 (struct efivar_entry **)&psi->data);
1215}
1216
1217static int efi_pstore_write(enum pstore_type_id type,
1218 enum kmsg_dump_reason reason, u64 *id,
1219 unsigned int part, int count, size_t size,
1220 struct pstore_info *psi)
1221{
1222 char name[DUMP_NAME_LEN];
1223 efi_char16_t efi_name[DUMP_NAME_LEN];
1224 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1225 int i, ret = 0;
1226
1227 sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count,
1228 get_seconds());
1229
1230 for (i = 0; i < DUMP_NAME_LEN; i++)
1231 efi_name[i] = name[i];
1232
1233 ret = efivar_entry_set_safe(efi_name, vendor, PSTORE_EFI_ATTRIBUTES,
1234 !pstore_cannot_block_path(reason),
1235 size, psi->buf);
1236
1237 if (reason == KMSG_DUMP_OOPS && efivar_wq_enabled)
1238 schedule_work(&efivar_work);
1239
1240 *id = part;
1241 return ret;
1242};
1243
1244struct pstore_erase_data {
1245 u64 id;
1246 enum pstore_type_id type;
1247 int count;
1248 struct timespec time;
1249 efi_char16_t *name;
1250};
1251
1252/*
1253 * Clean up an entry with the same name
1254 */
1255static int efi_pstore_erase_func(struct efivar_entry *entry, void *data)
1256{
1257 struct pstore_erase_data *ed = data;
1258 efi_guid_t vendor = LINUX_EFI_CRASH_GUID;
1259 efi_char16_t efi_name_old[DUMP_NAME_LEN];
1260 efi_char16_t *efi_name = ed->name;
1261 unsigned long utf16_len = utf16_strlen(ed->name);
1262 char name_old[DUMP_NAME_LEN];
1263 int i;
1264
1265 if (efi_guidcmp(entry->var.VendorGuid, vendor))
1266 return 0;
1267
1268 if (utf16_strncmp(entry->var.VariableName,
1269 efi_name, (size_t)utf16_len)) {
1270 /*
1271 * Check if an old format, which doesn't support
1272 * holding multiple logs, remains.
1273 */
1274 sprintf(name_old, "dump-type%u-%u-%lu", ed->type,
1275 (unsigned int)ed->id, ed->time.tv_sec);
1276
1277 for (i = 0; i < DUMP_NAME_LEN; i++)
1278 efi_name_old[i] = name_old[i];
1279
1280 if (utf16_strncmp(entry->var.VariableName, efi_name_old,
1281 utf16_strlen(efi_name_old)))
1282 return 0;
1283 }
1284
1285 /* found */
1286 __efivar_entry_delete(entry);
1287 return 1;
1288}
1289
1290static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count,
1291 struct timespec time, struct pstore_info *psi)
1292{
1293 struct pstore_erase_data edata;
1294 struct efivar_entry *entry;
1295 char name[DUMP_NAME_LEN];
1296 efi_char16_t efi_name[DUMP_NAME_LEN];
1297 int found, i;
1298
1299 sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count,
1300 time.tv_sec);
1301
1302 for (i = 0; i < DUMP_NAME_LEN; i++)
1303 efi_name[i] = name[i];
1304
1305 edata.id = id;
1306 edata.type = type;
1307 edata.count = count;
1308 edata.time = time;
1309 edata.name = efi_name;
1310
1311 efivar_entry_iter_begin();
1312 found = __efivar_entry_iter(efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);
1313 efivar_entry_iter_end();
1314
1315 if (found)
1316 efivar_unregister(entry);
1317
1318 return 0;
1319}
1320
1321static struct pstore_info efi_pstore_info = {
1322 .owner = THIS_MODULE,
1323 .name = "efi",
1324 .open = efi_pstore_open,
1325 .close = efi_pstore_close,
1326 .read = efi_pstore_read,
1327 .write = efi_pstore_write,
1328 .erase = efi_pstore_erase,
1329};
1330
1331static void efivar_pstore_register(void)
1332{
1333 efi_pstore_info.buf = kmalloc(4096, GFP_KERNEL);
1334 if (efi_pstore_info.buf) {
1335 efi_pstore_info.bufsize = 1024;
1336 spin_lock_init(&efi_pstore_info.buf_lock);
1337 pstore_register(&efi_pstore_info);
1338 }
1339}
1340#else
1341static void efivar_pstore_register(void)
1342{
1343 return;
1344}
1345#endif
1346
1347static ssize_t efivar_create(struct file *filp, struct kobject *kobj, 1087static ssize_t efivar_create(struct file *filp, struct kobject *kobj,
1348 struct bin_attribute *bin_attr, 1088 struct bin_attribute *bin_attr,
1349 char *buf, loff_t pos, size_t count) 1089 char *buf, loff_t pos, size_t count)
@@ -2397,6 +2137,16 @@ struct kobject *efivars_kobject(void)
2397EXPORT_SYMBOL_GPL(efivars_kobject); 2137EXPORT_SYMBOL_GPL(efivars_kobject);
2398 2138
2399/** 2139/**
2140 * efivar_run_worker - schedule the efivar worker thread
2141 */
2142void efivar_run_worker(void)
2143{
2144 if (efivar_wq_enabled)
2145 schedule_work(&efivar_work);
2146}
2147EXPORT_SYMBOL_GPL(efivar_run_worker);
2148
2149/**
2400 * efivars_register - register an efivars 2150 * efivars_register - register an efivars
2401 * @efivars: efivars to register 2151 * @efivars: efivars to register
2402 * @ops: efivars operations 2152 * @ops: efivars operations
@@ -2414,9 +2164,6 @@ int efivars_register(struct efivars *efivars,
2414 2164
2415 __efivars = efivars; 2165 __efivars = efivars;
2416 2166
2417 if (!efivars_pstore_disable)
2418 efivar_pstore_register();
2419
2420 register_filesystem(&efivarfs_type); 2167 register_filesystem(&efivarfs_type);
2421 2168
2422 return 0; 2169 return 0;