From a157029e1c7999d2bafd789ade8c39c3b14bf4ef Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 2 Feb 2015 19:53:16 -0800 Subject: [PATCH] 3.10-stable patches added patches: efi-pstore-make-efi-pstore-return-a-unique-id.patch pstore-clarify-clearing-of-_read_cnt-in-ramoops_context.patch pstore-d_alloc_name-doesn-t-return-an-err_ptr.patch pstore-fail-to-unlink-if-a-driver-has-not-defined.patch pstore-fix-null-pointer-fault-if-get-null-prz-in-ramoops_get_next_prz.patch pstore-ram-avoid-atomic-accesses-for-ioremapped-regions.patch pstore-skip-zero-size-persistent-ram-buffer-in-traverse.patch --- ...e-make-efi-pstore-return-a-unique-id.patch | 78 +++++++++++++ ...ring-of-_read_cnt-in-ramoops_context.patch | 52 +++++++++ ...alloc_name-doesn-t-return-an-err_ptr.patch | 36 ++++++ ...o-unlink-if-a-driver-has-not-defined.patch | 37 ++++++ ...get-null-prz-in-ramoops_get_next_prz.patch | 37 ++++++ ...omic-accesses-for-ioremapped-regions.patch | 109 ++++++++++++++++++ ...ze-persistent-ram-buffer-in-traverse.patch | 46 ++++++++ queue-3.10/series | 7 ++ 8 files changed, 402 insertions(+) create mode 100644 queue-3.10/efi-pstore-make-efi-pstore-return-a-unique-id.patch create mode 100644 queue-3.10/pstore-clarify-clearing-of-_read_cnt-in-ramoops_context.patch create mode 100644 queue-3.10/pstore-d_alloc_name-doesn-t-return-an-err_ptr.patch create mode 100644 queue-3.10/pstore-fail-to-unlink-if-a-driver-has-not-defined.patch create mode 100644 queue-3.10/pstore-fix-null-pointer-fault-if-get-null-prz-in-ramoops_get_next_prz.patch create mode 100644 queue-3.10/pstore-ram-avoid-atomic-accesses-for-ioremapped-regions.patch create mode 100644 queue-3.10/pstore-skip-zero-size-persistent-ram-buffer-in-traverse.patch diff --git a/queue-3.10/efi-pstore-make-efi-pstore-return-a-unique-id.patch b/queue-3.10/efi-pstore-make-efi-pstore-return-a-unique-id.patch new file mode 100644 index 00000000000..80e1eaac1fc --- /dev/null +++ b/queue-3.10/efi-pstore-make-efi-pstore-return-a-unique-id.patch @@ -0,0 +1,78 @@ +From fdeadb43fdf1e7d5698c027b555c389174548e5a Mon Sep 17 00:00:00 2001 +From: Madper Xie +Date: Fri, 29 Nov 2013 15:58:57 +0800 +Subject: efi-pstore: Make efi-pstore return a unique id + +From: Madper Xie + +commit fdeadb43fdf1e7d5698c027b555c389174548e5a upstream. + +Pstore fs expects that backends provide a unique id which could avoid +pstore making entries as duplication or denominating entries the same +name. So I combine the timestamp, part and count into id. + +Signed-off-by: Madper Xie +Cc: Seiji Aguchi +Cc: stable@vger.kernel.org +Signed-off-by: Matt Fleming +[hkp: Backported to 3.10: adjust context] +Signed-off-by: Hu Keping +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/firmware/efi/efi-pstore.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/firmware/efi/efi-pstore.c ++++ b/drivers/firmware/efi/efi-pstore.c +@@ -38,6 +38,12 @@ struct pstore_read_data { + char **buf; + }; + ++static inline u64 generic_id(unsigned long timestamp, ++ unsigned int part, int count) ++{ ++ return (timestamp * 100 + part) * 1000 + count; ++} ++ + static int efi_pstore_read_func(struct efivar_entry *entry, void *data) + { + efi_guid_t vendor = LINUX_EFI_CRASH_GUID; +@@ -56,7 +62,7 @@ static int efi_pstore_read_func(struct e + + if (sscanf(name, "dump-type%u-%u-%d-%lu", + cb_data->type, &part, &cnt, &time) == 4) { +- *cb_data->id = part; ++ *cb_data->id = generic_id(time, part, cnt); + *cb_data->count = cnt; + cb_data->timespec->tv_sec = time; + cb_data->timespec->tv_nsec = 0; +@@ -67,7 +73,7 @@ static int efi_pstore_read_func(struct e + * which doesn't support holding + * multiple logs, remains. + */ +- *cb_data->id = part; ++ *cb_data->id = generic_id(time, part, 0); + *cb_data->count = 0; + cb_data->timespec->tv_sec = time; + cb_data->timespec->tv_nsec = 0; +@@ -185,14 +191,16 @@ static int efi_pstore_erase(enum pstore_ + char name[DUMP_NAME_LEN]; + efi_char16_t efi_name[DUMP_NAME_LEN]; + int found, i; ++ unsigned int part; + +- sprintf(name, "dump-type%u-%u-%d-%lu", type, (unsigned int)id, count, +- time.tv_sec); ++ do_div(id, 1000); ++ part = do_div(id, 100); ++ sprintf(name, "dump-type%u-%u-%d-%lu", type, part, count, time.tv_sec); + + for (i = 0; i < DUMP_NAME_LEN; i++) + efi_name[i] = name[i]; + +- edata.id = id; ++ edata.id = part; + edata.type = type; + edata.count = count; + edata.time = time; diff --git a/queue-3.10/pstore-clarify-clearing-of-_read_cnt-in-ramoops_context.patch b/queue-3.10/pstore-clarify-clearing-of-_read_cnt-in-ramoops_context.patch new file mode 100644 index 00000000000..27f333d99f8 --- /dev/null +++ b/queue-3.10/pstore-clarify-clearing-of-_read_cnt-in-ramoops_context.patch @@ -0,0 +1,52 @@ +From 57fd835385a043577457a385f28c08be693991bf Mon Sep 17 00:00:00 2001 +From: Liu ShuoX +Date: Mon, 17 Mar 2014 11:24:49 +1100 +Subject: pstore: clarify clearing of _read_cnt in ramoops_context + +From: Liu ShuoX + +commit 57fd835385a043577457a385f28c08be693991bf upstream. + +*_read_cnt in ramoops_context need to be cleared during pstore ->open to +support mutli times getting the records. The patch added missed +ftrace_read_cnt clearing and removed duplicate clearing in ramoops_probe. + +Signed-off-by: Liu ShuoX +Cc: "Zhang, Yanmin" +Cc: Colin Cross +Cc: Kees Cook +Signed-off-by: Andrew Morton +Signed-off-by: Tony Luck +Cc: HuKeping +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/ram.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -92,6 +92,7 @@ struct ramoops_context { + struct persistent_ram_ecc_info ecc_info; + unsigned int max_dump_cnt; + unsigned int dump_write_cnt; ++ /* _read_cnt need clear on ramoops_pstore_open */ + unsigned int dump_read_cnt; + unsigned int console_read_cnt; + unsigned int ftrace_read_cnt; +@@ -107,6 +108,7 @@ static int ramoops_pstore_open(struct ps + + cxt->dump_read_cnt = 0; + cxt->console_read_cnt = 0; ++ cxt->ftrace_read_cnt = 0; + return 0; + } + +@@ -415,7 +417,6 @@ static int ramoops_probe(struct platform + if (!is_power_of_2(pdata->ftrace_size)) + pdata->ftrace_size = rounddown_pow_of_two(pdata->ftrace_size); + +- cxt->dump_read_cnt = 0; + cxt->size = pdata->mem_size; + cxt->phys_addr = pdata->mem_address; + cxt->memtype = pdata->mem_type; diff --git a/queue-3.10/pstore-d_alloc_name-doesn-t-return-an-err_ptr.patch b/queue-3.10/pstore-d_alloc_name-doesn-t-return-an-err_ptr.patch new file mode 100644 index 00000000000..4842f3583dd --- /dev/null +++ b/queue-3.10/pstore-d_alloc_name-doesn-t-return-an-err_ptr.patch @@ -0,0 +1,36 @@ +From c39524e6744284452ef45480d3153bec28960c32 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 14 Aug 2013 10:55:49 -0700 +Subject: pstore: d_alloc_name() doesn't return an ERR_PTR + +From: Dan Carpenter + +commit c39524e6744284452ef45480d3153bec28960c32 upstream. + +d_alloc_name() returns NULL on error. Also I changed the error code +from -ENOSPC to -ENOMEM to reflect that we were short on RAM not disk +space. + +Signed-off-by: Dan Carpenter +Acked-by: Kees Cook +Signed-off-by: Tony Luck +Cc: HuKeping +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/inode.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/fs/pstore/inode.c ++++ b/fs/pstore/inode.c +@@ -336,9 +336,8 @@ int pstore_mkfile(enum pstore_type_id ty + + mutex_lock(&root->d_inode->i_mutex); + +- rc = -ENOSPC; + dentry = d_alloc_name(root, name); +- if (IS_ERR(dentry)) ++ if (!dentry) + goto fail_lockedalloc; + + memcpy(private->data, data, size); diff --git a/queue-3.10/pstore-fail-to-unlink-if-a-driver-has-not-defined.patch b/queue-3.10/pstore-fail-to-unlink-if-a-driver-has-not-defined.patch new file mode 100644 index 00000000000..48a031fa886 --- /dev/null +++ b/queue-3.10/pstore-fail-to-unlink-if-a-driver-has-not-defined.patch @@ -0,0 +1,37 @@ +From bf2883339a33b7544b92ea465b90c3de55082032 Mon Sep 17 00:00:00 2001 +From: Aruna Balakrishnaiah +Date: Tue, 25 Jun 2013 14:33:56 +0530 +Subject: pstore: Fail to unlink if a driver has not defined + pstore_erase + +From: Aruna Balakrishnaiah + +commit bf2883339a33b7544b92ea465b90c3de55082032 upstream. + +pstore_erase is used to erase the record from the persistent store. +So if a driver has not defined pstore_erase callback return +-EPERM instead of unlinking a file as deleting the file without +erasing its record in persistent store will give a wrong impression +to customers. + +Signed-off-by: Aruna Balakrishnaiah +Acked-by: Kees Cook +Signed-off-by: Tony Luck +Cc: HuKeping +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/inode.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/pstore/inode.c ++++ b/fs/pstore/inode.c +@@ -178,6 +178,8 @@ static int pstore_unlink(struct inode *d + if (p->psi->erase) + p->psi->erase(p->type, p->id, p->count, + dentry->d_inode->i_ctime, p->psi); ++ else ++ return -EPERM; + + return simple_unlink(dir, dentry); + } diff --git a/queue-3.10/pstore-fix-null-pointer-fault-if-get-null-prz-in-ramoops_get_next_prz.patch b/queue-3.10/pstore-fix-null-pointer-fault-if-get-null-prz-in-ramoops_get_next_prz.patch new file mode 100644 index 00000000000..7eb3aa79836 --- /dev/null +++ b/queue-3.10/pstore-fix-null-pointer-fault-if-get-null-prz-in-ramoops_get_next_prz.patch @@ -0,0 +1,37 @@ +From b0aa931fb84431394d995472d0af2a6c2b61064d Mon Sep 17 00:00:00 2001 +From: Liu ShuoX +Date: Mon, 17 Mar 2014 13:57:49 -0700 +Subject: pstore: Fix NULL pointer fault if get NULL prz in ramoops_get_next_prz + +From: Liu ShuoX + +commit b0aa931fb84431394d995472d0af2a6c2b61064d upstream. + +ramoops_get_next_prz get the prz according the paramters. If it get a +uninitialized prz, access its members by following persistent_ram_old_size(prz) +will cause a NULL pointer crash. +Ex: if ftrace_size is 0, fprz will be NULL. + +Fix it by return NULL in advance. + +Signed-off-by: Liu ShuoX +Acked-by: Kees Cook +Signed-off-by: Tony Luck +Cc: HuKeping +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/ram.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -125,6 +125,8 @@ ramoops_get_next_prz(struct persistent_r + return NULL; + + prz = przs[i]; ++ if (!prz) ++ return NULL; + + /* Update old/shadowed buffer. */ + if (update) diff --git a/queue-3.10/pstore-ram-avoid-atomic-accesses-for-ioremapped-regions.patch b/queue-3.10/pstore-ram-avoid-atomic-accesses-for-ioremapped-regions.patch new file mode 100644 index 00000000000..58e484413a8 --- /dev/null +++ b/queue-3.10/pstore-ram-avoid-atomic-accesses-for-ioremapped-regions.patch @@ -0,0 +1,109 @@ +From 0405a5cec3406f19e69da07c8111a6bf1088ac29 Mon Sep 17 00:00:00 2001 +From: Rob Herring +Date: Mon, 8 Apr 2013 20:23:33 -0500 +Subject: pstore/ram: avoid atomic accesses for ioremapped regions + +From: Rob Herring + +commit 0405a5cec3406f19e69da07c8111a6bf1088ac29 upstream. + +For persistent RAM outside of main memory, the memory may have limitations +on supported accesses. For internal RAM on highbank platform exclusive +accesses are not supported and will hang the system. So atomic_cmpxchg +cannot be used. This commit uses spinlock protection for buffer size and +start updates on ioremapped regions instead. + +Signed-off-by: Rob Herring +Acked-by: Anton Vorontsov +Signed-off-by: Tony Luck +[hkp: Backported to 3.10: adjust context] +Signed-off-by: HuKeping + +--- + fs/pstore/ram_core.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 52 insertions(+), 2 deletions(-) + +--- a/fs/pstore/ram_core.c ++++ b/fs/pstore/ram_core.c +@@ -46,7 +46,7 @@ static inline size_t buffer_start(struct + } + + /* increase and wrap the start pointer, returning the old value */ +-static inline size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a) ++static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a) + { + int old; + int new; +@@ -62,7 +62,7 @@ static inline size_t buffer_start_add(st + } + + /* increase the size counter until it hits the max size */ +-static inline void buffer_size_add(struct persistent_ram_zone *prz, size_t a) ++static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a) + { + size_t old; + size_t new; +@@ -78,6 +78,53 @@ static inline void buffer_size_add(struc + } while (atomic_cmpxchg(&prz->buffer->size, old, new) != old); + } + ++static DEFINE_RAW_SPINLOCK(buffer_lock); ++ ++/* increase and wrap the start pointer, returning the old value */ ++static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a) ++{ ++ int old; ++ int new; ++ unsigned long flags; ++ ++ raw_spin_lock_irqsave(&buffer_lock, flags); ++ ++ old = atomic_read(&prz->buffer->start); ++ new = old + a; ++ while (unlikely(new > prz->buffer_size)) ++ new -= prz->buffer_size; ++ atomic_set(&prz->buffer->start, new); ++ ++ raw_spin_unlock_irqrestore(&buffer_lock, flags); ++ ++ return old; ++} ++ ++/* increase the size counter until it hits the max size */ ++static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a) ++{ ++ size_t old; ++ size_t new; ++ unsigned long flags; ++ ++ raw_spin_lock_irqsave(&buffer_lock, flags); ++ ++ old = atomic_read(&prz->buffer->size); ++ if (old == prz->buffer_size) ++ goto exit; ++ ++ new = old + a; ++ if (new > prz->buffer_size) ++ new = prz->buffer_size; ++ atomic_set(&prz->buffer->size, new); ++ ++exit: ++ raw_spin_unlock_irqrestore(&buffer_lock, flags); ++} ++ ++static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic; ++static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic; ++ + static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz, + uint8_t *data, size_t len, uint8_t *ecc) + { +@@ -379,6 +426,9 @@ static void *persistent_ram_iomap(phys_a + return NULL; + } + ++ buffer_start_add = buffer_start_add_locked; ++ buffer_size_add = buffer_size_add_locked; ++ + if (memtype) + va = ioremap(start, size); + else diff --git a/queue-3.10/pstore-skip-zero-size-persistent-ram-buffer-in-traverse.patch b/queue-3.10/pstore-skip-zero-size-persistent-ram-buffer-in-traverse.patch new file mode 100644 index 00000000000..6da927b20b4 --- /dev/null +++ b/queue-3.10/pstore-skip-zero-size-persistent-ram-buffer-in-traverse.patch @@ -0,0 +1,46 @@ +From aa9a4a1edfbd3d223af01db833da2f07850bc655 Mon Sep 17 00:00:00 2001 +From: Liu ShuoX +Date: Mon, 17 Mar 2014 11:24:49 +1100 +Subject: pstore: skip zero size persistent ram buffer in traverse + +From: Liu ShuoX + +commit aa9a4a1edfbd3d223af01db833da2f07850bc655 upstream. + +In ramoops_pstore_read, a valid prz pointer with zero size buffer will +break traverse of all persistent ram buffers. The latter buffer might be +lost. + +Signed-off-by: Liu ShuoX +Cc: "Zhang, Yanmin" +Cc: Colin Cross +Reviewed-by: Kees Cook +Signed-off-by: Andrew Morton +Signed-off-by: Tony Luck +Cc: HuKeping +Signed-off-by: Greg Kroah-Hartman + +--- + fs/pstore/ram.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +--- a/fs/pstore/ram.c ++++ b/fs/pstore/ram.c +@@ -126,12 +126,12 @@ ramoops_get_next_prz(struct persistent_r + + prz = przs[i]; + +- if (update) { +- /* Update old/shadowed buffer. */ ++ /* Update old/shadowed buffer. */ ++ if (update) + persistent_ram_save_old(prz); +- if (!persistent_ram_old_size(prz)) +- return NULL; +- } ++ ++ if (!persistent_ram_old_size(prz)) ++ return NULL; + + *typep = type; + *id = i; diff --git a/queue-3.10/series b/queue-3.10/series index ef1e1d017fd..4600282b2f5 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -28,3 +28,10 @@ arm-7931-1-correct-virt_addr_valid.patch arm-dma-ensure-that-old-section-mappings-are-flushed-from-the-tlb.patch arm-8108-1-mm-introduce-pte-pmd-_isset-and.patch arm-8109-1-mm-modify-pte_write-and-pmd_write-logic-for-lpae.patch +pstore-fail-to-unlink-if-a-driver-has-not-defined.patch +pstore-d_alloc_name-doesn-t-return-an-err_ptr.patch +pstore-clarify-clearing-of-_read_cnt-in-ramoops_context.patch +pstore-skip-zero-size-persistent-ram-buffer-in-traverse.patch +pstore-fix-null-pointer-fault-if-get-null-prz-in-ramoops_get_next_prz.patch +pstore-ram-avoid-atomic-accesses-for-ioremapped-regions.patch +efi-pstore-make-efi-pstore-return-a-unique-id.patch -- 2.47.3