aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/apei/erst.c20
-rw-r--r--drivers/firmware/efi/efi-pstore.c9
-rw-r--r--fs/pstore/inode.c2
-rw-r--r--fs/pstore/platform.c11
-rw-r--r--fs/pstore/ram.c2
-rw-r--r--fs/pstore/ram_core.c54
6 files changed, 80 insertions, 18 deletions
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c
index 6d894bfd8b8f..f7b3b39e94fc 100644
--- a/drivers/acpi/apei/erst.c
+++ b/drivers/acpi/apei/erst.c
@@ -1180,20 +1180,28 @@ static int __init erst_init(void)
1180 if (!erst_erange.vaddr) 1180 if (!erst_erange.vaddr)
1181 goto err_release_erange; 1181 goto err_release_erange;
1182 1182
1183 pr_info(ERST_PFX
1184 "Error Record Serialization Table (ERST) support is initialized.\n");
1185
1183 buf = kmalloc(erst_erange.size, GFP_KERNEL); 1186 buf = kmalloc(erst_erange.size, GFP_KERNEL);
1184 spin_lock_init(&erst_info.buf_lock); 1187 spin_lock_init(&erst_info.buf_lock);
1185 if (buf) { 1188 if (buf) {
1186 erst_info.buf = buf + sizeof(struct cper_pstore_record); 1189 erst_info.buf = buf + sizeof(struct cper_pstore_record);
1187 erst_info.bufsize = erst_erange.size - 1190 erst_info.bufsize = erst_erange.size -
1188 sizeof(struct cper_pstore_record); 1191 sizeof(struct cper_pstore_record);
1189 if (pstore_register(&erst_info)) { 1192 rc = pstore_register(&erst_info);
1190 pr_info(ERST_PFX "Could not register with persistent store\n"); 1193 if (rc) {
1194 if (rc != -EPERM)
1195 pr_info(ERST_PFX
1196 "Could not register with persistent store\n");
1197 erst_info.buf = NULL;
1198 erst_info.bufsize = 0;
1191 kfree(buf); 1199 kfree(buf);
1192 } 1200 }
1193 } 1201 } else
1194 1202 pr_err(ERST_PFX
1195 pr_info(ERST_PFX 1203 "Failed to allocate %lld bytes for persistent store error log\n",
1196 "Error Record Serialization Table (ERST) support is initialized.\n"); 1204 erst_erange.size);
1197 1205
1198 return 0; 1206 return 0;
1199 1207
diff --git a/drivers/firmware/efi/efi-pstore.c b/drivers/firmware/efi/efi-pstore.c
index 202d2c85ba2e..91864ad200ff 100644
--- a/drivers/firmware/efi/efi-pstore.c
+++ b/drivers/firmware/efi/efi-pstore.c
@@ -79,10 +79,9 @@ static int efi_pstore_read_func(struct efivar_entry *entry, void *data)
79 &entry->var.DataSize, entry->var.Data); 79 &entry->var.DataSize, entry->var.Data);
80 size = entry->var.DataSize; 80 size = entry->var.DataSize;
81 81
82 *cb_data->buf = kmalloc(size, GFP_KERNEL); 82 *cb_data->buf = kmemdup(entry->var.Data, size, GFP_KERNEL);
83 if (*cb_data->buf == NULL) 83 if (*cb_data->buf == NULL)
84 return -ENOMEM; 84 return -ENOMEM;
85 memcpy(*cb_data->buf, entry->var.Data, size);
86 return size; 85 return size;
87} 86}
88 87
@@ -236,7 +235,11 @@ static __init int efivars_pstore_init(void)
236 efi_pstore_info.bufsize = 1024; 235 efi_pstore_info.bufsize = 1024;
237 spin_lock_init(&efi_pstore_info.buf_lock); 236 spin_lock_init(&efi_pstore_info.buf_lock);
238 237
239 pstore_register(&efi_pstore_info); 238 if (pstore_register(&efi_pstore_info)) {
239 kfree(efi_pstore_info.buf);
240 efi_pstore_info.buf = NULL;
241 efi_pstore_info.bufsize = 0;
242 }
240 243
241 return 0; 244 return 0;
242} 245}
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index e4bcb2cf055a..bfd95bf38005 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -178,6 +178,8 @@ static int pstore_unlink(struct inode *dir, struct dentry *dentry)
178 if (p->psi->erase) 178 if (p->psi->erase)
179 p->psi->erase(p->type, p->id, p->count, 179 p->psi->erase(p->type, p->id, p->count,
180 dentry->d_inode->i_ctime, p->psi); 180 dentry->d_inode->i_ctime, p->psi);
181 else
182 return -EPERM;
181 183
182 return simple_unlink(dir, dentry); 184 return simple_unlink(dir, dentry);
183} 185}
diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c
index 86d1038b5a12..b7ffe2bcd9c4 100644
--- a/fs/pstore/platform.c
+++ b/fs/pstore/platform.c
@@ -239,17 +239,15 @@ int pstore_register(struct pstore_info *psi)
239{ 239{
240 struct module *owner = psi->owner; 240 struct module *owner = psi->owner;
241 241
242 if (backend && strcmp(backend, psi->name))
243 return -EPERM;
244
242 spin_lock(&pstore_lock); 245 spin_lock(&pstore_lock);
243 if (psinfo) { 246 if (psinfo) {
244 spin_unlock(&pstore_lock); 247 spin_unlock(&pstore_lock);
245 return -EBUSY; 248 return -EBUSY;
246 } 249 }
247 250
248 if (backend && strcmp(backend, psi->name)) {
249 spin_unlock(&pstore_lock);
250 return -EINVAL;
251 }
252
253 if (!psi->write) 251 if (!psi->write)
254 psi->write = pstore_write_compat; 252 psi->write = pstore_write_compat;
255 psinfo = psi; 253 psinfo = psi;
@@ -274,6 +272,9 @@ int pstore_register(struct pstore_info *psi)
274 add_timer(&pstore_timer); 272 add_timer(&pstore_timer);
275 } 273 }
276 274
275 pr_info("pstore: Registered %s as persistent store backend\n",
276 psi->name);
277
277 return 0; 278 return 0;
278} 279}
279EXPORT_SYMBOL_GPL(pstore_register); 280EXPORT_SYMBOL_GPL(pstore_register);
diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
index 1376e5a8f0d6..43abee2c6cb9 100644
--- a/fs/pstore/ram.c
+++ b/fs/pstore/ram.c
@@ -399,8 +399,6 @@ static int ramoops_probe(struct platform_device *pdev)
399 goto fail_out; 399 goto fail_out;
400 } 400 }
401 401
402 if (!is_power_of_2(pdata->mem_size))
403 pdata->mem_size = rounddown_pow_of_two(pdata->mem_size);
404 if (!is_power_of_2(pdata->record_size)) 402 if (!is_power_of_2(pdata->record_size))
405 pdata->record_size = rounddown_pow_of_two(pdata->record_size); 403 pdata->record_size = rounddown_pow_of_two(pdata->record_size);
406 if (!is_power_of_2(pdata->console_size)) 404 if (!is_power_of_2(pdata->console_size))
diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
index 59337326e288..de272d426763 100644
--- a/fs/pstore/ram_core.c
+++ b/fs/pstore/ram_core.c
@@ -46,7 +46,7 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz)
46} 46}
47 47
48/* increase and wrap the start pointer, returning the old value */ 48/* increase and wrap the start pointer, returning the old value */
49static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) 49static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
50{ 50{
51 int old; 51 int old;
52 int new; 52 int new;
@@ -62,7 +62,7 @@ static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
62} 62}
63 63
64/* increase the size counter until it hits the max size */ 64/* increase the size counter until it hits the max size */
65static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) 65static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a)
66{ 66{
67 size_t old; 67 size_t old;
68 size_t new; 68 size_t new;
@@ -78,6 +78,53 @@ static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
78 } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); 78 } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old);
79} 79}
80 80
81static DEFINE_RAW_SPINLOCK(buffer_lock);
82
83/* increase and wrap the start pointer, returning the old value */
84static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
85{
86 int old;
87 int new;
88 unsigned long flags;
89
90 raw_spin_lock_irqsave(&buffer_lock, flags);
91
92 old = atomic_read(&prz->buffer->start);
93 new = old + a;
94 while (unlikely(new > prz->buffer_size))
95 new -= prz->buffer_size;
96 atomic_set(&prz->buffer->start, new);
97
98 raw_spin_unlock_irqrestore(&buffer_lock, flags);
99
100 return old;
101}
102
103/* increase the size counter until it hits the max size */
104static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a)
105{
106 size_t old;
107 size_t new;
108 unsigned long flags;
109
110 raw_spin_lock_irqsave(&buffer_lock, flags);
111
112 old = atomic_read(&prz->buffer->size);
113 if (old == prz->buffer_size)
114 goto exit;
115
116 new = old + a;
117 if (new > prz->buffer_size)
118 new = prz->buffer_size;
119 atomic_set(&prz->buffer->size, new);
120
121exit:
122 raw_spin_unlock_irqrestore(&buffer_lock, flags);
123}
124
125static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic;
126static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic;
127
81static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, 128static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
82 uint8_t *data, size_t len, uint8_t *ecc) 129 uint8_t *data, size_t len, uint8_t *ecc)
83{ 130{
@@ -372,6 +419,9 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size)
372 return NULL; 419 return NULL;
373 } 420 }
374 421
422 buffer_start_add = buffer_start_add_locked;
423 buffer_size_add = buffer_size_add_locked;
424
375 return ioremap(start, size); 425 return ioremap(start, size);
376} 426}
377 427