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 | ||
