diff options
-rw-r--r-- | drivers/acpi/apei/erst.c | 20 | ||||
-rw-r--r-- | drivers/firmware/efi/efi-pstore.c | 9 | ||||
-rw-r--r-- | fs/pstore/inode.c | 2 | ||||
-rw-r--r-- | fs/pstore/platform.c | 11 | ||||
-rw-r--r-- | fs/pstore/ram.c | 2 | ||||
-rw-r--r-- | fs/pstore/ram_core.c | 54 |
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 | } |
279 | EXPORT_SYMBOL_GPL(pstore_register); | 280 | EXPORT_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 */ |
49 | static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) | 49 | static 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 */ |
65 | static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) | 65 | static 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 | ||
81 | static DEFINE_RAW_SPINLOCK(buffer_lock); | ||
82 | |||
83 | /* increase and wrap the start pointer, returning the old value */ | ||
84 | static 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 */ | ||
104 | static 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 | |||
121 | exit: | ||
122 | raw_spin_unlock_irqrestore(&buffer_lock, flags); | ||
123 | } | ||
124 | |||
125 | static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic; | ||
126 | static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic; | ||
127 | |||
81 | static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, | 128 | static 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 | ||