]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.8-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Oct 2016 07:48:44 +0000 (09:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 26 Oct 2016 07:48:44 +0000 (09:48 +0200)
added patches:
dm-crypt-fix-crash-on-exit.patch
dm-mark-request_queue-dead-before-destroying-the-dm-device.patch
dm-mpath-check-if-path-s-request_queue-is-dying-in-activate_path.patch
dm-return-correct-error-code-in-dm_resume-s-retry-loop.patch
dm-rq-take-request_queue-lock-while-clearing-queue_flag_stopped.patch
ib-core-correctly-handle-rdma_rw_init_mrs-failure.patch
ib-srp-fix-infinite-loop-when-fmr-sg.offset-0.patch
perf-intel-pt-fix-estimated-timestamps-for-cycle-accurate-mode.patch
perf-intel-pt-fix-mtc-timestamp-calculation-for-large-mtc-periods.patch
perf-intel-pt-fix-snapshot-overlap-detection-decoder-errors.patch
powerpc-64-fix-incorrect-return-value-from-__copy_tofrom_user.patch
powerpc-eeh-null-check-uses-of-eeh_pe_bus_get.patch
powerpc-mm-hash64-fix-might_have_hea-check.patch
powerpc-mm-update-force_max_zoneorder-range-to-allow-hugetlb-w-4k.patch
powerpc-powernv-pass-cpu-endian-pe-number-to-opal_pci_eeh_freeze_clear.patch
powerpc-powernv-use-cpu-endian-hub-diag-data-type-in-pnv_eeh_get_and_dump_hub_diag.patch
powerpc-powernv-use-cpu-endian-pest-in-pnv_pci_dump_p7ioc_diag_data.patch
powerpc-pseries-fix-stack-corruption-in-htpe-code.patch
powerpc-vdso64-use-double-word-compare-on-pointers.patch
powerpc-xmon-don-t-use-ld-on-32-bit.patch
ubi-deal-with-interrupted-erasures-in-wl.patch

22 files changed:
queue-4.8/dm-crypt-fix-crash-on-exit.patch [new file with mode: 0644]
queue-4.8/dm-mark-request_queue-dead-before-destroying-the-dm-device.patch [new file with mode: 0644]
queue-4.8/dm-mpath-check-if-path-s-request_queue-is-dying-in-activate_path.patch [new file with mode: 0644]
queue-4.8/dm-return-correct-error-code-in-dm_resume-s-retry-loop.patch [new file with mode: 0644]
queue-4.8/dm-rq-take-request_queue-lock-while-clearing-queue_flag_stopped.patch [new file with mode: 0644]
queue-4.8/ib-core-correctly-handle-rdma_rw_init_mrs-failure.patch [new file with mode: 0644]
queue-4.8/ib-srp-fix-infinite-loop-when-fmr-sg.offset-0.patch [new file with mode: 0644]
queue-4.8/perf-intel-pt-fix-estimated-timestamps-for-cycle-accurate-mode.patch [new file with mode: 0644]
queue-4.8/perf-intel-pt-fix-mtc-timestamp-calculation-for-large-mtc-periods.patch [new file with mode: 0644]
queue-4.8/perf-intel-pt-fix-snapshot-overlap-detection-decoder-errors.patch [new file with mode: 0644]
queue-4.8/powerpc-64-fix-incorrect-return-value-from-__copy_tofrom_user.patch [new file with mode: 0644]
queue-4.8/powerpc-eeh-null-check-uses-of-eeh_pe_bus_get.patch [new file with mode: 0644]
queue-4.8/powerpc-mm-hash64-fix-might_have_hea-check.patch [new file with mode: 0644]
queue-4.8/powerpc-mm-update-force_max_zoneorder-range-to-allow-hugetlb-w-4k.patch [new file with mode: 0644]
queue-4.8/powerpc-powernv-pass-cpu-endian-pe-number-to-opal_pci_eeh_freeze_clear.patch [new file with mode: 0644]
queue-4.8/powerpc-powernv-use-cpu-endian-hub-diag-data-type-in-pnv_eeh_get_and_dump_hub_diag.patch [new file with mode: 0644]
queue-4.8/powerpc-powernv-use-cpu-endian-pest-in-pnv_pci_dump_p7ioc_diag_data.patch [new file with mode: 0644]
queue-4.8/powerpc-pseries-fix-stack-corruption-in-htpe-code.patch [new file with mode: 0644]
queue-4.8/powerpc-vdso64-use-double-word-compare-on-pointers.patch [new file with mode: 0644]
queue-4.8/powerpc-xmon-don-t-use-ld-on-32-bit.patch [new file with mode: 0644]
queue-4.8/series
queue-4.8/ubi-deal-with-interrupted-erasures-in-wl.patch [new file with mode: 0644]

diff --git a/queue-4.8/dm-crypt-fix-crash-on-exit.patch b/queue-4.8/dm-crypt-fix-crash-on-exit.patch
new file mode 100644 (file)
index 0000000..7bb4957
--- /dev/null
@@ -0,0 +1,122 @@
+From f659b10087daaf4ce0087c3f6aec16746be9628f Mon Sep 17 00:00:00 2001
+From: Rabin Vincent <rabinv@axis.com>
+Date: Wed, 21 Sep 2016 16:22:29 +0200
+Subject: dm crypt: fix crash on exit
+
+From: Rabin Vincent <rabinv@axis.com>
+
+commit f659b10087daaf4ce0087c3f6aec16746be9628f upstream.
+
+As the documentation for kthread_stop() says, "if threadfn() may call
+do_exit() itself, the caller must ensure task_struct can't go away".
+dm-crypt does not ensure this and therefore crashes when crypt_dtr()
+calls kthread_stop().  The crash is trivially reproducible by adding a
+delay before the call to kthread_stop() and just opening and closing a
+dm-crypt device.
+
+ general protection fault: 0000 [#1] PREEMPT SMP
+ CPU: 0 PID: 533 Comm: cryptsetup Not tainted 4.8.0-rc7+ #7
+ task: ffff88003bd0df40 task.stack: ffff8800375b4000
+ RIP: 0010: kthread_stop+0x52/0x300
+ Call Trace:
+  crypt_dtr+0x77/0x120
+  dm_table_destroy+0x6f/0x120
+  __dm_destroy+0x130/0x250
+  dm_destroy+0x13/0x20
+  dev_remove+0xe6/0x120
+  ? dev_suspend+0x250/0x250
+  ctl_ioctl+0x1fc/0x530
+  ? __lock_acquire+0x24f/0x1b10
+  dm_ctl_ioctl+0x13/0x20
+  do_vfs_ioctl+0x91/0x6a0
+  ? ____fput+0xe/0x10
+  ? entry_SYSCALL_64_fastpath+0x5/0xbd
+  ? trace_hardirqs_on_caller+0x151/0x1e0
+  SyS_ioctl+0x41/0x70
+  entry_SYSCALL_64_fastpath+0x1f/0xbd
+
+This problem was introduced by bcbd94ff481e ("dm crypt: fix a possible
+hang due to race condition on exit").
+
+Looking at the description of that patch (excerpted below), it seems
+like the problem it addresses can be solved by just using
+set_current_state instead of __set_current_state, since we obviously
+need the memory barrier.
+
+| dm crypt: fix a possible hang due to race condition on exit
+|
+| A kernel thread executes __set_current_state(TASK_INTERRUPTIBLE),
+| __add_wait_queue, spin_unlock_irq and then tests kthread_should_stop().
+| It is possible that the processor reorders memory accesses so that
+| kthread_should_stop() is executed before __set_current_state().  If
+| such reordering happens, there is a possible race on thread
+| termination: [...]
+
+So this patch just reverts the aforementioned patch and changes the
+__set_current_state(TASK_INTERRUPTIBLE) to set_current_state(...).  This
+fixes the crash and should also fix the potential hang.
+
+Fixes: bcbd94ff481e ("dm crypt: fix a possible hang due to race condition on exit")
+Cc: Mikulas Patocka <mpatocka@redhat.com>
+Signed-off-by: Rabin Vincent <rabinv@axis.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-crypt.c |   24 ++++++++++--------------
+ 1 file changed, 10 insertions(+), 14 deletions(-)
+
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -113,8 +113,7 @@ struct iv_tcw_private {
+  * and encrypts / decrypts at the same time.
+  */
+ enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
+-           DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD,
+-           DM_CRYPT_EXIT_THREAD};
++           DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD };
+ /*
+  * The fields in here must be read only after initialization.
+@@ -1207,18 +1206,20 @@ continue_locked:
+               if (!RB_EMPTY_ROOT(&cc->write_tree))
+                       goto pop_from_list;
+-              if (unlikely(test_bit(DM_CRYPT_EXIT_THREAD, &cc->flags))) {
+-                      spin_unlock_irq(&cc->write_thread_wait.lock);
+-                      break;
+-              }
+-
+-              __set_current_state(TASK_INTERRUPTIBLE);
++              set_current_state(TASK_INTERRUPTIBLE);
+               __add_wait_queue(&cc->write_thread_wait, &wait);
+               spin_unlock_irq(&cc->write_thread_wait.lock);
++              if (unlikely(kthread_should_stop())) {
++                      set_task_state(current, TASK_RUNNING);
++                      remove_wait_queue(&cc->write_thread_wait, &wait);
++                      break;
++              }
++
+               schedule();
++              set_task_state(current, TASK_RUNNING);
+               spin_lock_irq(&cc->write_thread_wait.lock);
+               __remove_wait_queue(&cc->write_thread_wait, &wait);
+               goto continue_locked;
+@@ -1533,13 +1534,8 @@ static void crypt_dtr(struct dm_target *
+       if (!cc)
+               return;
+-      if (cc->write_thread) {
+-              spin_lock_irq(&cc->write_thread_wait.lock);
+-              set_bit(DM_CRYPT_EXIT_THREAD, &cc->flags);
+-              wake_up_locked(&cc->write_thread_wait);
+-              spin_unlock_irq(&cc->write_thread_wait.lock);
++      if (cc->write_thread)
+               kthread_stop(cc->write_thread);
+-      }
+       if (cc->io_queue)
+               destroy_workqueue(cc->io_queue);
diff --git a/queue-4.8/dm-mark-request_queue-dead-before-destroying-the-dm-device.patch b/queue-4.8/dm-mark-request_queue-dead-before-destroying-the-dm-device.patch
new file mode 100644 (file)
index 0000000..00b06fe
--- /dev/null
@@ -0,0 +1,41 @@
+From 3b785fbcf81c3533772c52b717f77293099498d3 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Wed, 31 Aug 2016 15:17:49 -0700
+Subject: dm: mark request_queue dead before destroying the DM device
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit 3b785fbcf81c3533772c52b717f77293099498d3 upstream.
+
+This avoids that new requests are queued while __dm_destroy() is in
+progress.
+
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1873,6 +1873,7 @@ EXPORT_SYMBOL_GPL(dm_device_name);
+ static void __dm_destroy(struct mapped_device *md, bool wait)
+ {
++      struct request_queue *q = dm_get_md_queue(md);
+       struct dm_table *map;
+       int srcu_idx;
+@@ -1883,6 +1884,10 @@ static void __dm_destroy(struct mapped_d
+       set_bit(DMF_FREEING, &md->flags);
+       spin_unlock(&_minor_lock);
++      spin_lock_irq(q->queue_lock);
++      queue_flag_set(QUEUE_FLAG_DYING, q);
++      spin_unlock_irq(q->queue_lock);
++
+       if (dm_request_based(md) && md->kworker_task)
+               flush_kthread_worker(&md->kworker);
diff --git a/queue-4.8/dm-mpath-check-if-path-s-request_queue-is-dying-in-activate_path.patch b/queue-4.8/dm-mpath-check-if-path-s-request_queue-is-dying-in-activate_path.patch
new file mode 100644 (file)
index 0000000..bbc5913
--- /dev/null
@@ -0,0 +1,41 @@
+From f10e06b744074824fb8ec7066bc03ecc90918f5b Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+Date: Thu, 1 Sep 2016 12:06:37 -0400
+Subject: dm mpath: check if path's request_queue is dying in activate_path()
+
+From: Mike Snitzer <snitzer@redhat.com>
+
+commit f10e06b744074824fb8ec7066bc03ecc90918f5b upstream.
+
+If pg_init_retries is set and a request is queued against a multipath
+device with all underlying block device request_queues in the "dying"
+state then an infinite loop is triggered because activate_path() never
+succeeds and hence never calls pg_init_done().
+
+This change avoids that device removal triggers an infinite loop by
+failing the activate_path() which causes the "dying" path to be failed.
+
+Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-mpath.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -1521,10 +1521,10 @@ static void activate_path(struct work_st
+ {
+       struct pgpath *pgpath =
+               container_of(work, struct pgpath, activate_path.work);
++      struct request_queue *q = bdev_get_queue(pgpath->path.dev->bdev);
+-      if (pgpath->is_active)
+-              scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
+-                               pg_init_done, pgpath);
++      if (pgpath->is_active && !blk_queue_dying(q))
++              scsi_dh_activate(q, pg_init_done, pgpath);
+       else
+               pg_init_done(pgpath, SCSI_DH_DEV_OFFLINED);
+ }
diff --git a/queue-4.8/dm-return-correct-error-code-in-dm_resume-s-retry-loop.patch b/queue-4.8/dm-return-correct-error-code-in-dm_resume-s-retry-loop.patch
new file mode 100644 (file)
index 0000000..71a2b63
--- /dev/null
@@ -0,0 +1,48 @@
+From 8dc23658b7aaa8b6b0609c81c8ad75e98b612801 Mon Sep 17 00:00:00 2001
+From: Minfei Huang <mnghuan@gmail.com>
+Date: Tue, 6 Sep 2016 16:00:29 +0800
+Subject: dm: return correct error code in dm_resume()'s retry loop
+
+From: Minfei Huang <mnghuan@gmail.com>
+
+commit 8dc23658b7aaa8b6b0609c81c8ad75e98b612801 upstream.
+
+dm_resume() will return success (0) rather than -EINVAL if
+!dm_suspended_md() upon retry within dm_resume().
+
+Reset the error code at the start of dm_resume()'s retry loop.
+Also, remove a useless assignment at the end of dm_resume().
+
+Fixes: ffcc393641 ("dm: enhance internal suspend and resume interface")
+Signed-off-by: Minfei Huang <mnghuan@gmail.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -2254,10 +2254,11 @@ static int __dm_resume(struct mapped_dev
+ int dm_resume(struct mapped_device *md)
+ {
+-      int r = -EINVAL;
++      int r;
+       struct dm_table *map = NULL;
+ retry:
++      r = -EINVAL;
+       mutex_lock_nested(&md->suspend_lock, SINGLE_DEPTH_NESTING);
+       if (!dm_suspended_md(md))
+@@ -2281,8 +2282,6 @@ retry:
+               goto out;
+       clear_bit(DMF_SUSPENDED, &md->flags);
+-
+-      r = 0;
+ out:
+       mutex_unlock(&md->suspend_lock);
diff --git a/queue-4.8/dm-rq-take-request_queue-lock-while-clearing-queue_flag_stopped.patch b/queue-4.8/dm-rq-take-request_queue-lock-while-clearing-queue_flag_stopped.patch
new file mode 100644 (file)
index 0000000..b1efa3e
--- /dev/null
@@ -0,0 +1,56 @@
+From 9dbeaeabacb26260d1621fe58f0f6fdedc8860d4 Mon Sep 17 00:00:00 2001
+From: Mike Snitzer <snitzer@redhat.com>
+Date: Thu, 1 Sep 2016 11:59:33 -0400
+Subject: dm rq: take request_queue lock while clearing QUEUE_FLAG_STOPPED
+
+From: Mike Snitzer <snitzer@redhat.com>
+
+commit 9dbeaeabacb26260d1621fe58f0f6fdedc8860d4 upstream.
+
+Every call of queue_flag_clear_unlocked() after block device
+initialization has finished is wrong if blk_cleanup_queue() can be
+called concurrently.  Convert queue_flag_clear_unlocked() into
+queue_flag_clear() and protect it by the block layer queue lock.
+
+Also, factor out dm_mq_start_queue().
+
+Reported-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Mike Snitzer <snitzer@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/md/dm-rq.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -73,15 +73,24 @@ static void dm_old_start_queue(struct re
+       spin_unlock_irqrestore(q->queue_lock, flags);
+ }
++static void dm_mq_start_queue(struct request_queue *q)
++{
++      unsigned long flags;
++
++      spin_lock_irqsave(q->queue_lock, flags);
++      queue_flag_clear(QUEUE_FLAG_STOPPED, q);
++      spin_unlock_irqrestore(q->queue_lock, flags);
++
++      blk_mq_start_stopped_hw_queues(q, true);
++      blk_mq_kick_requeue_list(q);
++}
++
+ void dm_start_queue(struct request_queue *q)
+ {
+       if (!q->mq_ops)
+               dm_old_start_queue(q);
+-      else {
+-              queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, q);
+-              blk_mq_start_stopped_hw_queues(q, true);
+-              blk_mq_kick_requeue_list(q);
+-      }
++      else
++              dm_mq_start_queue(q);
+ }
+ static void dm_old_stop_queue(struct request_queue *q)
diff --git a/queue-4.8/ib-core-correctly-handle-rdma_rw_init_mrs-failure.patch b/queue-4.8/ib-core-correctly-handle-rdma_rw_init_mrs-failure.patch
new file mode 100644 (file)
index 0000000..6cd5732
--- /dev/null
@@ -0,0 +1,73 @@
+From b6bc1c731f0b985e91f618561fc82c6e252dfaf4 Mon Sep 17 00:00:00 2001
+From: Steve Wise <swise@opengridcomputing.com>
+Date: Thu, 29 Sep 2016 07:31:33 -0700
+Subject: IB/core: correctly handle rdma_rw_init_mrs() failure
+
+From: Steve Wise <swise@opengridcomputing.com>
+
+commit b6bc1c731f0b985e91f618561fc82c6e252dfaf4 upstream.
+
+Function ib_create_qp() was failing to return an error when
+rdma_rw_init_mrs() fails, causing a crash further down in ib_create_qp()
+when trying to dereferece the qp pointer which was actually a negative
+errno.
+
+The crash:
+
+crash> log|grep BUG
+[  136.458121] BUG: unable to handle kernel NULL pointer dereference at 0000000000000098
+crash> bt
+PID: 3736   TASK: ffff8808543215c0  CPU: 2   COMMAND: "kworker/u64:2"
+ #0 [ffff88084d323340] machine_kexec at ffffffff8105fbb0
+ #1 [ffff88084d3233b0] __crash_kexec at ffffffff81116758
+ #2 [ffff88084d323480] crash_kexec at ffffffff8111682d
+ #3 [ffff88084d3234b0] oops_end at ffffffff81032bd6
+ #4 [ffff88084d3234e0] no_context at ffffffff8106e431
+ #5 [ffff88084d323530] __bad_area_nosemaphore at ffffffff8106e610
+ #6 [ffff88084d323590] bad_area_nosemaphore at ffffffff8106e6f4
+ #7 [ffff88084d3235a0] __do_page_fault at ffffffff8106ebdc
+ #8 [ffff88084d323620] do_page_fault at ffffffff8106f057
+ #9 [ffff88084d323660] page_fault at ffffffff816e3148
+    [exception RIP: ib_create_qp+427]
+    RIP: ffffffffa02554fb  RSP: ffff88084d323718  RFLAGS: 00010246
+    RAX: 0000000000000004  RBX: fffffffffffffff4  RCX: 000000018020001f
+    RDX: ffff880830997fc0  RSI: 0000000000000001  RDI: ffff88085f407200
+    RBP: ffff88084d323778   R8: 0000000000000001   R9: ffffea0020bae210
+    R10: ffffea0020bae218  R11: 0000000000000001  R12: ffff88084d3237c8
+    R13: 00000000fffffff4  R14: ffff880859fa5000  R15: ffff88082eb89800
+    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
+#10 [ffff88084d323780] rdma_create_qp at ffffffffa0782681 [rdma_cm]
+#11 [ffff88084d3237b0] nvmet_rdma_create_queue_ib at ffffffffa07c43f3 [nvmet_rdma]
+#12 [ffff88084d323860] nvmet_rdma_alloc_queue at ffffffffa07c5ba9 [nvmet_rdma]
+#13 [ffff88084d323900] nvmet_rdma_queue_connect at ffffffffa07c5c96 [nvmet_rdma]
+#14 [ffff88084d323980] nvmet_rdma_cm_handler at ffffffffa07c6450 [nvmet_rdma]
+#15 [ffff88084d3239b0] iw_conn_req_handler at ffffffffa0787480 [rdma_cm]
+#16 [ffff88084d323a60] cm_conn_req_handler at ffffffffa0775f06 [iw_cm]
+#17 [ffff88084d323ab0] process_event at ffffffffa0776019 [iw_cm]
+#18 [ffff88084d323af0] cm_work_handler at ffffffffa0776170 [iw_cm]
+#19 [ffff88084d323cb0] process_one_work at ffffffff810a1483
+#20 [ffff88084d323d90] worker_thread at ffffffff810a211d
+#21 [ffff88084d323ec0] kthread at ffffffff810a6c5c
+#22 [ffff88084d323f50] ret_from_fork at ffffffff816e1ebf
+
+Fixes: 632bc3f65081 ("IB/core, RDMA RW API: Do not exceed QP SGE send limit")
+Signed-off-by: Steve Wise <swise@opengridcomputing.com>
+Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/core/verbs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -821,7 +821,7 @@ struct ib_qp *ib_create_qp(struct ib_pd
+               if (ret) {
+                       pr_err("failed to init MR pool ret= %d\n", ret);
+                       ib_destroy_qp(qp);
+-                      qp = ERR_PTR(ret);
++                      return ERR_PTR(ret);
+               }
+       }
diff --git a/queue-4.8/ib-srp-fix-infinite-loop-when-fmr-sg.offset-0.patch b/queue-4.8/ib-srp-fix-infinite-loop-when-fmr-sg.offset-0.patch
new file mode 100644 (file)
index 0000000..056aec5
--- /dev/null
@@ -0,0 +1,54 @@
+From 681cc3608355737c1effebc8145f95c8c3344bc3 Mon Sep 17 00:00:00 2001
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+Date: Mon, 26 Sep 2016 12:58:49 -0700
+Subject: IB/srp: Fix infinite loop when FMR sg[0].offset != 0
+
+From: Bart Van Assche <bart.vanassche@sandisk.com>
+
+commit 681cc3608355737c1effebc8145f95c8c3344bc3 upstream.
+
+Avoid that mapping an sg-list in which the first element has a
+non-zero offset triggers an infinite loop when using FMR. This
+patch makes the FMR mapping code similar to that of ib_sg_to_pages().
+
+Note: older Mellanox HCAs do not support non-zero offsets for FMR.
+See also commit 8c4037b501ac ("IB/srp: always avoid non-zero offsets
+into an FMR").
+
+Reported-by: Alex Estrin <alex.estrin@intel.com>
+Signed-off-by: Bart Van Assche <bart.vanassche@sandisk.com>
+Signed-off-by: Doug Ledford <dledford@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/infiniband/ulp/srp/ib_srp.c |    8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -1400,7 +1400,9 @@ static int srp_map_sg_entry(struct srp_m
+       while (dma_len) {
+               unsigned offset = dma_addr & ~dev->mr_page_mask;
+-              if (state->npages == dev->max_pages_per_mr || offset != 0) {
++
++              if (state->npages == dev->max_pages_per_mr ||
++                  (state->npages > 0 && offset != 0)) {
+                       ret = srp_map_finish_fmr(state, ch);
+                       if (ret)
+                               return ret;
+@@ -1417,12 +1419,12 @@ static int srp_map_sg_entry(struct srp_m
+       }
+       /*
+-       * If the last entry of the MR wasn't a full page, then we need to
++       * If the end of the MR is not on a page boundary then we need to
+        * close it out and start a new one -- we can only merge at page
+        * boundaries.
+        */
+       ret = 0;
+-      if (len != dev->mr_page_size)
++      if ((dma_addr & ~dev->mr_page_mask) != 0)
+               ret = srp_map_finish_fmr(state, ch);
+       return ret;
+ }
diff --git a/queue-4.8/perf-intel-pt-fix-estimated-timestamps-for-cycle-accurate-mode.patch b/queue-4.8/perf-intel-pt-fix-estimated-timestamps-for-cycle-accurate-mode.patch
new file mode 100644 (file)
index 0000000..12ef5d5
--- /dev/null
@@ -0,0 +1,37 @@
+From 51ee6481fa8e879cc942bcc1b0af713e158b7a98 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Wed, 28 Sep 2016 14:41:35 +0300
+Subject: perf intel-pt: Fix estimated timestamps for cycle-accurate mode
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 51ee6481fa8e879cc942bcc1b0af713e158b7a98 upstream.
+
+In cycle-accurate mode, timestamps can be calculated from CYC packets.
+The decoder also estimates timestamps based on the number of
+instructions since the last timestamp. For that to work in
+cycle-accurate mode, the instruction count needs to be reset to zero
+when a timestamp is calculated from a CYC packet, but that wasn't
+happening, so fix it.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Link: http://lkml.kernel.org/r/1475062896-22274-1-git-send-email-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/intel-pt-decoder/intel-pt-decoder.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+@@ -1323,6 +1323,8 @@ static void intel_pt_calc_cyc_timestamp(
+                            timestamp, decoder->timestamp);
+       else
+               decoder->timestamp = timestamp;
++
++      decoder->timestamp_insn_cnt = 0;
+ }
+ /* Walk PSB+ packets when already in sync. */
diff --git a/queue-4.8/perf-intel-pt-fix-mtc-timestamp-calculation-for-large-mtc-periods.patch b/queue-4.8/perf-intel-pt-fix-mtc-timestamp-calculation-for-large-mtc-periods.patch
new file mode 100644 (file)
index 0000000..eabc932
--- /dev/null
@@ -0,0 +1,118 @@
+From 3bccbe20f6d188ce7b00326e776b745cfd35b10a Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Wed, 28 Sep 2016 14:41:36 +0300
+Subject: perf intel-pt: Fix MTC timestamp calculation for large MTC periods
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 3bccbe20f6d188ce7b00326e776b745cfd35b10a upstream.
+
+The MTC packet provides a 8-bit slice of CTC which is related to TSC by
+the TMA packet, however the TMA packet only provides the lower 16 bits
+of CTC.  If mtc_shift > 8 then some of the MTC bits are not in the CTC
+provided by the TMA packet. Fix-up the last_mtc calculated from the TMA
+packet by copying the missing bits from the current MTC assuming the
+least difference between the two, and that the current MTC comes after
+last_mtc.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Link: http://lkml.kernel.org/r/1475062896-22274-2-git-send-email-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/intel-pt-decoder/intel-pt-decoder.c |   36 ++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+@@ -89,6 +89,7 @@ struct intel_pt_decoder {
+       bool pge;
+       bool have_tma;
+       bool have_cyc;
++      bool fixup_last_mtc;
+       uint64_t pos;
+       uint64_t last_ip;
+       uint64_t ip;
+@@ -584,10 +585,31 @@ struct intel_pt_calc_cyc_to_tsc_info {
+       uint64_t        tsc_timestamp;
+       uint64_t        timestamp;
+       bool            have_tma;
++      bool            fixup_last_mtc;
+       bool            from_mtc;
+       double          cbr_cyc_to_tsc;
+ };
++/*
++ * MTC provides a 8-bit slice of CTC but the TMA packet only provides the lower
++ * 16 bits of CTC. If mtc_shift > 8 then some of the MTC bits are not in the CTC
++ * provided by the TMA packet. Fix-up the last_mtc calculated from the TMA
++ * packet by copying the missing bits from the current MTC assuming the least
++ * difference between the two, and that the current MTC comes after last_mtc.
++ */
++static void intel_pt_fixup_last_mtc(uint32_t mtc, int mtc_shift,
++                                  uint32_t *last_mtc)
++{
++      uint32_t first_missing_bit = 1U << (16 - mtc_shift);
++      uint32_t mask = ~(first_missing_bit - 1);
++
++      *last_mtc |= mtc & mask;
++      if (*last_mtc >= mtc) {
++              *last_mtc -= first_missing_bit;
++              *last_mtc &= 0xff;
++      }
++}
++
+ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
+ {
+       struct intel_pt_decoder *decoder = pkt_info->decoder;
+@@ -617,6 +639,11 @@ static int intel_pt_calc_cyc_cb(struct i
+                       return 0;
+               mtc = pkt_info->packet.payload;
++              if (decoder->mtc_shift > 8 && data->fixup_last_mtc) {
++                      data->fixup_last_mtc = false;
++                      intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
++                                              &data->last_mtc);
++              }
+               if (mtc > data->last_mtc)
+                       mtc_delta = mtc - data->last_mtc;
+               else
+@@ -685,6 +712,7 @@ static int intel_pt_calc_cyc_cb(struct i
+               data->ctc_delta = 0;
+               data->have_tma = true;
++              data->fixup_last_mtc = true;
+               return 0;
+@@ -751,6 +779,7 @@ static void intel_pt_calc_cyc_to_tsc(str
+               .tsc_timestamp  = decoder->tsc_timestamp,
+               .timestamp      = decoder->timestamp,
+               .have_tma       = decoder->have_tma,
++              .fixup_last_mtc = decoder->fixup_last_mtc,
+               .from_mtc       = from_mtc,
+               .cbr_cyc_to_tsc = 0,
+       };
+@@ -1241,6 +1270,7 @@ static void intel_pt_calc_tma(struct int
+       }
+       decoder->ctc_delta = 0;
+       decoder->have_tma = true;
++      decoder->fixup_last_mtc = true;
+       intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x  CTC rem %#x\n",
+                    decoder->ctc_timestamp, decoder->last_mtc, ctc_rem);
+ }
+@@ -1255,6 +1285,12 @@ static void intel_pt_calc_mtc_timestamp(
+       mtc = decoder->packet.payload;
++      if (decoder->mtc_shift > 8 && decoder->fixup_last_mtc) {
++              decoder->fixup_last_mtc = false;
++              intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
++                                      &decoder->last_mtc);
++      }
++
+       if (mtc > decoder->last_mtc)
+               mtc_delta = mtc - decoder->last_mtc;
+       else
diff --git a/queue-4.8/perf-intel-pt-fix-snapshot-overlap-detection-decoder-errors.patch b/queue-4.8/perf-intel-pt-fix-snapshot-overlap-detection-decoder-errors.patch
new file mode 100644 (file)
index 0000000..d2078aa
--- /dev/null
@@ -0,0 +1,70 @@
+From 810c398bc09b2f2dfde52a7d2483a710612c5fb8 Mon Sep 17 00:00:00 2001
+From: Adrian Hunter <adrian.hunter@intel.com>
+Date: Fri, 23 Sep 2016 17:38:41 +0300
+Subject: perf intel-pt: Fix snapshot overlap detection decoder errors
+
+From: Adrian Hunter <adrian.hunter@intel.com>
+
+commit 810c398bc09b2f2dfde52a7d2483a710612c5fb8 upstream.
+
+Fix occasional decoder errors decoding trace data collected in snapshot
+mode.
+
+Snapshot mode can take successive snapshots of trace which might overlap.
+The decoder checks whether there is an overlap but only looks at the
+current and previous buffer. However buffers that do not contain
+synchronization (i.e. PSB) packets cannot be decoded or used for overlap
+checking. That means the decoder actually needs to check overlaps between
+the current buffer and the previous buffer that contained usable data.
+Make that change.
+
+Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
+Cc: Jiri Olsa <jolsa@redhat.com>
+Cc: Masami Hiramatsu <mhiramat@kernel.org>
+Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
+Link: http://lkml.kernel.org/r/1474641528-18776-10-git-send-email-adrian.hunter@intel.com
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/intel-pt.c |   15 +++++++++++----
+ 1 file changed, 11 insertions(+), 4 deletions(-)
+
+--- a/tools/perf/util/intel-pt.c
++++ b/tools/perf/util/intel-pt.c
+@@ -241,7 +241,7 @@ static int intel_pt_get_trace(struct int
+       }
+       queue = &ptq->pt->queues.queue_array[ptq->queue_nr];
+-
++next:
+       buffer = auxtrace_buffer__next(queue, buffer);
+       if (!buffer) {
+               if (old_buffer)
+@@ -264,9 +264,6 @@ static int intel_pt_get_trace(struct int
+           intel_pt_do_fix_overlap(ptq->pt, old_buffer, buffer))
+               return -ENOMEM;
+-      if (old_buffer)
+-              auxtrace_buffer__drop_data(old_buffer);
+-
+       if (buffer->use_data) {
+               b->len = buffer->use_size;
+               b->buf = buffer->use_data;
+@@ -276,6 +273,16 @@ static int intel_pt_get_trace(struct int
+       }
+       b->ref_timestamp = buffer->reference;
++      /*
++       * If in snapshot mode and the buffer has no usable data, get next
++       * buffer and again check overlap against old_buffer.
++       */
++      if (ptq->pt->snapshot_mode && !b->len)
++              goto next;
++
++      if (old_buffer)
++              auxtrace_buffer__drop_data(old_buffer);
++
+       if (!old_buffer || ptq->pt->sampling_mode || (ptq->pt->snapshot_mode &&
+                                                     !buffer->consecutive)) {
+               b->consecutive = false;
diff --git a/queue-4.8/powerpc-64-fix-incorrect-return-value-from-__copy_tofrom_user.patch b/queue-4.8/powerpc-64-fix-incorrect-return-value-from-__copy_tofrom_user.patch
new file mode 100644 (file)
index 0000000..77227b1
--- /dev/null
@@ -0,0 +1,58 @@
+From 1a34439e5a0b2235e43f96816dbb15ee1154f656 Mon Sep 17 00:00:00 2001
+From: Paul Mackerras <paulus@ozlabs.org>
+Date: Tue, 11 Oct 2016 22:25:47 +1100
+Subject: powerpc/64: Fix incorrect return value from __copy_tofrom_user
+
+From: Paul Mackerras <paulus@ozlabs.org>
+
+commit 1a34439e5a0b2235e43f96816dbb15ee1154f656 upstream.
+
+Debugging a data corruption issue with virtio-net/vhost-net led to
+the observation that __copy_tofrom_user was occasionally returning
+a value 16 larger than it should.  Since the return value from
+__copy_tofrom_user is the number of bytes not copied, this means
+that __copy_tofrom_user can occasionally return a value larger
+than the number of bytes it was asked to copy.  In turn this can
+cause higher-level copy functions such as copy_page_to_iter_iovec
+to corrupt memory by copying data into the wrong memory locations.
+
+It turns out that the failing case involves a fault on the store
+at label 79, and at that point the first unmodified byte of the
+destination is at R3 + 16.  Consequently the exception handler
+for that store needs to add 16 to R3 before using it to work out
+how many bytes were not copied, but in this one case it was not
+adding the offset to R3.  To fix it, this moves the label 179 to
+the point where we add 16 to R3.  I have checked manually all the
+exception handlers for the loads and stores in this code and the
+rest of them are correct (it would be excellent to have an
+automated test of all the exception cases).
+
+This bug has been present since this code was initially
+committed in May 2002 to Linux version 2.5.20.
+
+Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/lib/copyuser_64.S |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/lib/copyuser_64.S
++++ b/arch/powerpc/lib/copyuser_64.S
+@@ -359,6 +359,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
+       addi    r3,r3,8
+ 171:
+ 177:
++179:
+       addi    r3,r3,8
+ 370:
+ 372:
+@@ -373,7 +374,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_
+ 173:
+ 174:
+ 175:
+-179:
+ 181:
+ 184:
+ 186:
diff --git a/queue-4.8/powerpc-eeh-null-check-uses-of-eeh_pe_bus_get.patch b/queue-4.8/powerpc-eeh-null-check-uses-of-eeh_pe_bus_get.patch
new file mode 100644 (file)
index 0000000..f2d9850
--- /dev/null
@@ -0,0 +1,57 @@
+From 04fec21c06e35b169a83e75a84a015ab4606bf5e Mon Sep 17 00:00:00 2001
+From: Russell Currey <ruscur@russell.cc>
+Date: Mon, 12 Sep 2016 14:17:22 +1000
+Subject: powerpc/eeh: Null check uses of eeh_pe_bus_get
+
+From: Russell Currey <ruscur@russell.cc>
+
+commit 04fec21c06e35b169a83e75a84a015ab4606bf5e upstream.
+
+eeh_pe_bus_get() can return NULL if a PCI bus isn't found for a given PE.
+Some callers don't check this, and can cause a null pointer dereference
+under certain circumstances.
+
+Fix this by checking NULL everywhere eeh_pe_bus_get() is called.
+
+Fixes: 8a6b1bc70dbb ("powerpc/eeh: EEH core to handle special event")
+Signed-off-by: Russell Currey <ruscur@russell.cc>
+Reviewed-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/eeh_driver.c             |    8 ++++++++
+ arch/powerpc/platforms/powernv/eeh-powernv.c |    5 +++++
+ 2 files changed, 13 insertions(+)
+
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -994,6 +994,14 @@ static void eeh_handle_special_event(voi
+                               /* Notify all devices to be down */
+                               eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+                               bus = eeh_pe_bus_get(phb_pe);
++                              if (!bus) {
++                                      pr_err("%s: Cannot find PCI bus for "
++                                             "PHB#%d-PE#%x\n",
++                                             __func__,
++                                             pe->phb->global_number,
++                                             pe->addr);
++                                      break;
++                              }
+                               eeh_pe_dev_traverse(pe,
+                                       eeh_report_failure, NULL);
+                               pci_hp_remove_devices(bus);
+--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
++++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
+@@ -1091,6 +1091,11 @@ static int pnv_eeh_reset(struct eeh_pe *
+       }
+       bus = eeh_pe_bus_get(pe);
++      if (!bus) {
++              pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
++                      __func__, pe->phb->global_number, pe->addr);
++              return -EIO;
++      }
+       if (pe->type & EEH_PE_VF)
+               return pnv_eeh_reset_vf_pe(pe, option);
diff --git a/queue-4.8/powerpc-mm-hash64-fix-might_have_hea-check.patch b/queue-4.8/powerpc-mm-hash64-fix-might_have_hea-check.patch
new file mode 100644 (file)
index 0000000..2912398
--- /dev/null
@@ -0,0 +1,48 @@
+From 08bf75ba852ef8304a84b6a030466b4b4850382e Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Tue, 11 Oct 2016 21:15:04 +1100
+Subject: powerpc/mm/hash64: Fix might_have_hea() check
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit 08bf75ba852ef8304a84b6a030466b4b4850382e upstream.
+
+In commit 2b4e3ad8f579 ("powerpc/mm/hash64: Don't test for machine type
+to detect HEA special case") we changed the logic in might_have_hea()
+to check FW_FEATURE_SPLPAR rather than machine_is(pseries).
+
+However the check was incorrectly negated, leading to crashes on
+machines with HEA adapters, such as:
+
+  mm: Hashing failure ! EA=0xd000080080004040 access=0x800000000000000e current=NetworkManager
+      trap=0x300 vsid=0x13d349c ssize=1 base psize=2 psize 2 pte=0xc0003cc033e701ae
+  Unable to handle kernel paging request for data at address 0xd000080080004040
+  Call Trace:
+    .ehea_create_cq+0x148/0x340 [ehea] (unreliable)
+    .ehea_up+0x258/0x1200 [ehea]
+    .ehea_open+0x44/0x1a0 [ehea]
+    ...
+
+Fix it by removing the negation.
+
+Fixes: 2b4e3ad8f579 ("powerpc/mm/hash64: Don't test for machine type to detect HEA special case")
+Reported-by: Denis Kirjanov <kda@linux-powerpc.org>
+Reported-by: Jan Stancek <jstancek@redhat.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/mm/hash_utils_64.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/mm/hash_utils_64.c
++++ b/arch/powerpc/mm/hash_utils_64.c
+@@ -526,7 +526,7 @@ static bool might_have_hea(void)
+        */
+ #ifdef CONFIG_IBMEBUS
+       return !cpu_has_feature(CPU_FTR_ARCH_207S) &&
+-              !firmware_has_feature(FW_FEATURE_SPLPAR);
++              firmware_has_feature(FW_FEATURE_SPLPAR);
+ #else
+       return false;
+ #endif
diff --git a/queue-4.8/powerpc-mm-update-force_max_zoneorder-range-to-allow-hugetlb-w-4k.patch b/queue-4.8/powerpc-mm-update-force_max_zoneorder-range-to-allow-hugetlb-w-4k.patch
new file mode 100644 (file)
index 0000000..1ec43ee
--- /dev/null
@@ -0,0 +1,54 @@
+From d5a1e42cb4be016a45a787953dd70c3bc4509da5 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
+Date: Mon, 19 Sep 2016 23:01:33 +0530
+Subject: powerpc/mm: Update FORCE_MAX_ZONEORDER range to allow hugetlb w/4K
+
+From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+
+commit d5a1e42cb4be016a45a787953dd70c3bc4509da5 upstream.
+
+For hugetlb to work with 4K page size, we need MAX_ORDER to be 13 or
+more. When switching from a 64K page size to 4K linux page size using
+make oldconfig, we end up with a CONFIG_FORCE_MAX_ZONEORDER value of 9.
+This results in a 16M hugepage beiing considered as a gigantic huge page
+which in turn results in failure to setup hugepages if gigantic hugepage
+support is not enabled.
+
+This also results in kernel crash with 4K radix configuration. We
+hit the below BUG_ON on radix:
+
+  kernel BUG at mm/huge_memory.c:364!
+  Oops: Exception in kernel mode, sig: 5 [#1]
+  SMP NR_CPUS=2048 NUMA PowerNV
+  CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.8.0-rc1-00006-gbae9cc6 #1
+  task: c0000000f1af8000 task.stack: c0000000f1aec000
+  NIP: c000000000c5fa0c LR: c000000000c5f9d8 CTR: c000000000c5f9a4
+  REGS: c0000000f1aef920 TRAP: 0700   Not tainted (4.8.0-rc1-00006-gbae9cc6)
+  MSR: 9000000102029033 <SF,HV,VEC,EE,ME,IR,DR,RI,LE,TM[E]>  CR: 24000844  XER: 00000000
+  CFAR: c000000000c5f9e0 SOFTE: 1
+  ....
+  NIP [c000000000c5fa0c] hugepage_init+0x68/0x238
+  LR [c000000000c5f9d8] hugepage_init+0x34/0x238
+
+Fixes: a7ee539584acf ("powerpc/Kconfig: Update config option based on page size")
+Reported-by: Santhosh <santhog4@linux.vnet.ibm.com>
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Acked-by: Balbir Singh <bsingharora@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/Kconfig |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -637,7 +637,7 @@ config FORCE_MAX_ZONEORDER
+       int "Maximum zone order"
+       range 8 9 if PPC64 && PPC_64K_PAGES
+       default "9" if PPC64 && PPC_64K_PAGES
+-      range 9 13 if PPC64 && !PPC_64K_PAGES
++      range 13 13 if PPC64 && !PPC_64K_PAGES
+       default "13" if PPC64 && !PPC_64K_PAGES
+       range 9 64 if PPC32 && PPC_16K_PAGES
+       default "9" if PPC32 && PPC_16K_PAGES
diff --git a/queue-4.8/powerpc-powernv-pass-cpu-endian-pe-number-to-opal_pci_eeh_freeze_clear.patch b/queue-4.8/powerpc-powernv-pass-cpu-endian-pe-number-to-opal_pci_eeh_freeze_clear.patch
new file mode 100644 (file)
index 0000000..aaafaf5
--- /dev/null
@@ -0,0 +1,43 @@
+From d63e51b31e0b655ed0f581b8a8fd4c4b4f8d1919 Mon Sep 17 00:00:00 2001
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Date: Tue, 2 Aug 2016 14:10:29 +1000
+Subject: powerpc/powernv: Pass CPU-endian PE number to opal_pci_eeh_freeze_clear()
+
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+
+commit d63e51b31e0b655ed0f581b8a8fd4c4b4f8d1919 upstream.
+
+The PE number (@frozen_pe_no), filled by opal_pci_next_error() is in
+big-endian format. It should be converted to CPU-endian before it is
+passed to opal_pci_eeh_freeze_clear() when clearing the frozen state if
+the PE is invalid one. As Michael Ellerman pointed out, the issue is
+also detected by sparse:
+
+  eeh-powernv.c:1541:41: warning: incorrect type in argument 2 (different base types)
+
+This passes CPU-endian PE number to opal_pci_eeh_freeze_clear() and it
+should be part of commit <0f36db77643b> ("powerpc/eeh: Fix wrong printed
+PE number"), which was merged to 4.3 kernel.
+
+Fixes: 71b540adffd9 ("powerpc/powernv: Don't escalate non-existing frozen PE")
+Suggested-by: Paul Mackerras <paulus@samba.org>
+Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Reviewed-by: Russell Currey <ruscur@russell.cc>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/eeh-powernv.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
++++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
+@@ -1538,7 +1538,7 @@ static int pnv_eeh_next_error(struct eeh
+                               /* Try best to clear it */
+                               opal_pci_eeh_freeze_clear(phb->opal_id,
+-                                      frozen_pe_no,
++                                      be64_to_cpu(frozen_pe_no),
+                                       OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+                               ret = EEH_NEXT_ERR_NONE;
+                       } else if ((*pe)->state & EEH_PE_ISOLATED ||
diff --git a/queue-4.8/powerpc-powernv-use-cpu-endian-hub-diag-data-type-in-pnv_eeh_get_and_dump_hub_diag.patch b/queue-4.8/powerpc-powernv-use-cpu-endian-hub-diag-data-type-in-pnv_eeh_get_and_dump_hub_diag.patch
new file mode 100644 (file)
index 0000000..2786326
--- /dev/null
@@ -0,0 +1,41 @@
+From a7032132d7560a8434e1f54b71efd7fa20f073bd Mon Sep 17 00:00:00 2001
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Date: Tue, 2 Aug 2016 14:10:30 +1000
+Subject: powerpc/powernv: Use CPU-endian hub diag-data type in pnv_eeh_get_and_dump_hub_diag()
+
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+
+commit a7032132d7560a8434e1f54b71efd7fa20f073bd upstream.
+
+The hub diag-data type is filled with big-endian data by OPAL call
+opal_pci_get_hub_diag_data(). We need convert it to CPU-endian value
+before using it. The issue is reported by sparse as pointed by Michael
+Ellerman:
+
+  eeh-powernv.c:1309:21: warning: restricted __be16 degrades to integer
+
+This converts hub diag-data type to CPU-endian before using it in
+pnv_eeh_get_and_dump_hub_diag().
+
+Fixes: 2a485ad7c88d ("powerpc/powernv: Drop PHB operation next_error()")
+Suggested-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Reviewed-by: Russell Currey <ruscur@russell.cc>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/eeh-powernv.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
++++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
+@@ -1311,7 +1311,7 @@ static void pnv_eeh_get_and_dump_hub_dia
+               return;
+       }
+-      switch (data->type) {
++      switch (be16_to_cpu(data->type)) {
+       case OPAL_P7IOC_DIAG_TYPE_RGC:
+               pr_info("P7IOC diag-data for RGC\n\n");
+               pnv_eeh_dump_hub_diag_common(data);
diff --git a/queue-4.8/powerpc-powernv-use-cpu-endian-pest-in-pnv_pci_dump_p7ioc_diag_data.patch b/queue-4.8/powerpc-powernv-use-cpu-endian-pest-in-pnv_pci_dump_p7ioc_diag_data.patch
new file mode 100644 (file)
index 0000000..10f9f39
--- /dev/null
@@ -0,0 +1,36 @@
+From 5adaf8629b193f185ca5a1665b9e777a0579f518 Mon Sep 17 00:00:00 2001
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Date: Tue, 2 Aug 2016 14:10:32 +1000
+Subject: powerpc/powernv: Use CPU-endian PEST in pnv_pci_dump_p7ioc_diag_data()
+
+From: Gavin Shan <gwshan@linux.vnet.ibm.com>
+
+commit 5adaf8629b193f185ca5a1665b9e777a0579f518 upstream.
+
+This fixes the warnings reported from sparse:
+
+  pci.c:312:33: warning: restricted __be64 degrades to integer
+  pci.c:313:33: warning: restricted __be64 degrades to integer
+
+Fixes: cee72d5bb489 ("powerpc/powernv: Display diag data on p7ioc EEH errors")
+Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/powernv/pci.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/platforms/powernv/pci.c
++++ b/arch/powerpc/platforms/powernv/pci.c
+@@ -309,8 +309,8 @@ static void pnv_pci_dump_p7ioc_diag_data
+                       be64_to_cpu(data->dma1ErrorLog1));
+       for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) {
+-              if ((data->pestA[i] >> 63) == 0 &&
+-                  (data->pestB[i] >> 63) == 0)
++              if ((be64_to_cpu(data->pestA[i]) >> 63) == 0 &&
++                  (be64_to_cpu(data->pestB[i]) >> 63) == 0)
+                       continue;
+               pr_info("PE[%3d] A/B: %016llx %016llx\n",
diff --git a/queue-4.8/powerpc-pseries-fix-stack-corruption-in-htpe-code.patch b/queue-4.8/powerpc-pseries-fix-stack-corruption-in-htpe-code.patch
new file mode 100644 (file)
index 0000000..1647e04
--- /dev/null
@@ -0,0 +1,92 @@
+From 05af40e885955065aee8bb7425058eb3e1adca08 Mon Sep 17 00:00:00 2001
+From: Laurent Dufour <ldufour@linux.vnet.ibm.com>
+Date: Thu, 6 Oct 2016 15:33:21 +0200
+Subject: powerpc/pseries: Fix stack corruption in htpe code
+
+From: Laurent Dufour <ldufour@linux.vnet.ibm.com>
+
+commit 05af40e885955065aee8bb7425058eb3e1adca08 upstream.
+
+This commit fixes a stack corruption in the pseries specific code dealing
+with the huge pages.
+
+In __pSeries_lpar_hugepage_invalidate() the buffer used to pass arguments
+to the hypervisor is not large enough. This leads to a stack corruption
+where a previously saved register could be corrupted leading to unexpected
+result in the caller, like the following panic:
+
+  Oops: Kernel access of bad area, sig: 11 [#1]
+  SMP NR_CPUS=2048 NUMA pSeries
+  Modules linked in: virtio_balloon ip_tables x_tables autofs4
+  virtio_blk 8139too virtio_pci virtio_ring 8139cp virtio
+  CPU: 11 PID: 1916 Comm: mmstress Not tainted 4.8.0 #76
+  task: c000000005394880 task.stack: c000000005570000
+  NIP: c00000000027bf6c LR: c00000000027bf64 CTR: 0000000000000000
+  REGS: c000000005573820 TRAP: 0300   Not tainted  (4.8.0)
+  MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE>  CR: 84822884  XER: 20000000
+  CFAR: c00000000010a924 DAR: 420000000014e5e0 DSISR: 40000000 SOFTE: 1
+  GPR00: c00000000027bf64 c000000005573aa0 c000000000e02800 c000000004447964
+  GPR04: c00000000404de18 c000000004d38810 00000000042100f5 00000000f5002104
+  GPR08: e0000000f5002104 0000000000000001 042100f5000000e0 00000000042100f5
+  GPR12: 0000000000002200 c00000000fe02c00 c00000000404de18 0000000000000000
+  GPR16: c1ffffffffffe7ff 00003fff62000000 420000000014e5e0 00003fff63000000
+  GPR20: 0008000000000000 c0000000f7014800 0405e600000000e0 0000000000010000
+  GPR24: c000000004d38810 c000000004447c10 c00000000404de18 c000000004447964
+  GPR28: c000000005573b10 c000000004d38810 00003fff62000000 420000000014e5e0
+  NIP [c00000000027bf6c] zap_huge_pmd+0x4c/0x470
+  LR [c00000000027bf64] zap_huge_pmd+0x44/0x470
+  Call Trace:
+  [c000000005573aa0] [c00000000027bf64] zap_huge_pmd+0x44/0x470 (unreliable)
+  [c000000005573af0] [c00000000022bbd8] unmap_page_range+0xcf8/0xed0
+  [c000000005573c30] [c00000000022c2d4] unmap_vmas+0x84/0x120
+  [c000000005573c80] [c000000000235448] unmap_region+0xd8/0x1b0
+  [c000000005573d80] [c0000000002378f0] do_munmap+0x2d0/0x4c0
+  [c000000005573df0] [c000000000237be4] SyS_munmap+0x64/0xb0
+  [c000000005573e30] [c000000000009560] system_call+0x38/0x108
+  Instruction dump:
+  fbe1fff8 fb81ffe0 7c7f1b78 7ca32b78 7cbd2b78 f8010010 7c9a2378 f821ffb1
+  7cde3378 4bfffea9 7c7b1b79 41820298 <e87f0000> 48000130 7fa5eb78 7fc4f378
+
+Most of the time, the bug is surfacing in a caller up in the stack from
+__pSeries_lpar_hugepage_invalidate() which is quite confusing.
+
+This bug is pending since v3.11 but was hidden if a caller of the
+caller of __pSeries_lpar_hugepage_invalidate() has pushed the corruped
+register (r18 in this case) in the stack and is not using it until
+restoring it. GCC 6.2.0 seems to raise it more frequently.
+
+This commit also change the definition of the parameter buffer in
+pSeries_lpar_flush_hash_range() to rely on the global define
+PLPAR_HCALL9_BUFSIZE (no functional change here).
+
+Fixes: 1a5272866f87 ("powerpc: Optimize hugepage invalidate")
+Signed-off-by: Laurent Dufour <ldufour@linux.vnet.ibm.com>
+Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+Acked-by: Balbir Singh <bsingharora@gmail.com>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/platforms/pseries/lpar.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -393,7 +393,7 @@ static void __pSeries_lpar_hugepage_inva
+                                            unsigned long *vpn, int count,
+                                            int psize, int ssize)
+ {
+-      unsigned long param[8];
++      unsigned long param[PLPAR_HCALL9_BUFSIZE];
+       int i = 0, pix = 0, rc;
+       unsigned long flags = 0;
+       int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+@@ -522,7 +522,7 @@ static void pSeries_lpar_flush_hash_rang
+       unsigned long flags = 0;
+       struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
+       int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+-      unsigned long param[9];
++      unsigned long param[PLPAR_HCALL9_BUFSIZE];
+       unsigned long hash, index, shift, hidx, slot;
+       real_pte_t pte;
+       int psize, ssize;
diff --git a/queue-4.8/powerpc-vdso64-use-double-word-compare-on-pointers.patch b/queue-4.8/powerpc-vdso64-use-double-word-compare-on-pointers.patch
new file mode 100644 (file)
index 0000000..9f9c020
--- /dev/null
@@ -0,0 +1,65 @@
+From 5045ea37377ce8cca6890d32b127ad6770e6dce5 Mon Sep 17 00:00:00 2001
+From: Anton Blanchard <anton@samba.org>
+Date: Sun, 25 Sep 2016 17:16:53 +1000
+Subject: powerpc/vdso64: Use double word compare on pointers
+
+From: Anton Blanchard <anton@samba.org>
+
+commit 5045ea37377ce8cca6890d32b127ad6770e6dce5 upstream.
+
+__kernel_get_syscall_map() and __kernel_clock_getres() use cmpli to
+check if the passed in pointer is non zero. cmpli maps to a 32 bit
+compare on binutils, so we ignore the top 32 bits.
+
+A simple test case can be created by passing in a bogus pointer with
+the bottom 32 bits clear. Using a clk_id that is handled by the VDSO,
+then one that is handled by the kernel shows the problem:
+
+  printf("%d\n", clock_getres(CLOCK_REALTIME, (void *)0x100000000));
+  printf("%d\n", clock_getres(CLOCK_BOOTTIME, (void *)0x100000000));
+
+And we get:
+
+  0
+  -1
+
+The bigger issue is if we pass a valid pointer with the bottom 32 bits
+clear, in this case we will return success but won't write any data
+to the pointer.
+
+I stumbled across this issue because the LLVM integrated assembler
+doesn't accept cmpli with 3 arguments. Fix this by converting them to
+cmpldi.
+
+Fixes: a7f290dad32e ("[PATCH] powerpc: Merge vdso's and add vdso support to 32 bits kernel")
+Signed-off-by: Anton Blanchard <anton@samba.org>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/kernel/vdso64/datapage.S     |    2 +-
+ arch/powerpc/kernel/vdso64/gettimeofday.S |    2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/kernel/vdso64/datapage.S
++++ b/arch/powerpc/kernel/vdso64/datapage.S
+@@ -59,7 +59,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_ma
+       bl      V_LOCAL_FUNC(__get_datapage)
+       mtlr    r12
+       addi    r3,r3,CFG_SYSCALL_MAP64
+-      cmpli   cr0,r4,0
++      cmpldi  cr0,r4,0
+       crclr   cr0*4+so
+       beqlr
+       li      r0,NR_syscalls
+--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
++++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
+@@ -145,7 +145,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
+       bne     cr0,99f
+       li      r3,0
+-      cmpli   cr0,r4,0
++      cmpldi  cr0,r4,0
+       crclr   cr0*4+so
+       beqlr
+       lis     r5,CLOCK_REALTIME_RES@h
diff --git a/queue-4.8/powerpc-xmon-don-t-use-ld-on-32-bit.patch b/queue-4.8/powerpc-xmon-don-t-use-ld-on-32-bit.patch
new file mode 100644 (file)
index 0000000..312ff8a
--- /dev/null
@@ -0,0 +1,43 @@
+From b42d9023a31e384504f5b53fc9a437d5536a3f63 Mon Sep 17 00:00:00 2001
+From: Michael Ellerman <mpe@ellerman.id.au>
+Date: Fri, 9 Sep 2016 14:01:07 +1000
+Subject: powerpc/xmon: Don't use ld on 32-bit
+
+From: Michael Ellerman <mpe@ellerman.id.au>
+
+commit b42d9023a31e384504f5b53fc9a437d5536a3f63 upstream.
+
+In commit 31cdd0c39c75 ("powerpc/xmon: Fix SPR read/write commands and
+add command to dump SPRs") I added two uses of the "ld" instruction in
+spr_access.S. "ld" is a 64-bit instruction, so shouldn't be used on
+32-bit CPUs.
+
+Replace it with PPC_LL which is a macro that gives us either "ld" or
+"lwz" depending on whether we're 64 or 32-bit.
+
+Fixes: 31cdd0c39c75 ("powerpc/xmon: Fix SPR read/write commands and add command to dump SPRs")
+Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
+Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/powerpc/xmon/spr_access.S |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/arch/powerpc/xmon/spr_access.S
++++ b/arch/powerpc/xmon/spr_access.S
+@@ -2,12 +2,12 @@
+ /* unsigned long xmon_mfspr(sprn, default_value) */
+ _GLOBAL(xmon_mfspr)
+-      ld      r5, .Lmfspr_table@got(r2)
++      PPC_LL  r5, .Lmfspr_table@got(r2)
+       b       xmon_mxspr
+ /* void xmon_mtspr(sprn, new_value) */
+ _GLOBAL(xmon_mtspr)
+-      ld      r5, .Lmtspr_table@got(r2)
++      PPC_LL  r5, .Lmtspr_table@got(r2)
+       b       xmon_mxspr
+ /*
index a9681fbdd1f11e5c417059e08bc839ff4b8c7d46..c62086634f479ef2f0743ebb689384e48255aa96 100644 (file)
@@ -26,3 +26,24 @@ pstore-ramoops-fixup-driver-removal.patch
 pstore-core-drop-cmpxchg-based-updates.patch
 pstore-ram-use-memcpy_toio-instead-of-memcpy.patch
 pstore-ram-use-memcpy_fromio-to-save-old-buffer.patch
+perf-intel-pt-fix-snapshot-overlap-detection-decoder-errors.patch
+perf-intel-pt-fix-estimated-timestamps-for-cycle-accurate-mode.patch
+perf-intel-pt-fix-mtc-timestamp-calculation-for-large-mtc-periods.patch
+dm-mark-request_queue-dead-before-destroying-the-dm-device.patch
+dm-return-correct-error-code-in-dm_resume-s-retry-loop.patch
+dm-rq-take-request_queue-lock-while-clearing-queue_flag_stopped.patch
+dm-mpath-check-if-path-s-request_queue-is-dying-in-activate_path.patch
+dm-crypt-fix-crash-on-exit.patch
+powerpc-xmon-don-t-use-ld-on-32-bit.patch
+powerpc-vdso64-use-double-word-compare-on-pointers.patch
+powerpc-powernv-pass-cpu-endian-pe-number-to-opal_pci_eeh_freeze_clear.patch
+powerpc-eeh-null-check-uses-of-eeh_pe_bus_get.patch
+powerpc-powernv-use-cpu-endian-hub-diag-data-type-in-pnv_eeh_get_and_dump_hub_diag.patch
+powerpc-powernv-use-cpu-endian-pest-in-pnv_pci_dump_p7ioc_diag_data.patch
+powerpc-mm-update-force_max_zoneorder-range-to-allow-hugetlb-w-4k.patch
+powerpc-64-fix-incorrect-return-value-from-__copy_tofrom_user.patch
+powerpc-pseries-fix-stack-corruption-in-htpe-code.patch
+powerpc-mm-hash64-fix-might_have_hea-check.patch
+ib-srp-fix-infinite-loop-when-fmr-sg.offset-0.patch
+ib-core-correctly-handle-rdma_rw_init_mrs-failure.patch
+ubi-deal-with-interrupted-erasures-in-wl.patch
diff --git a/queue-4.8/ubi-deal-with-interrupted-erasures-in-wl.patch b/queue-4.8/ubi-deal-with-interrupted-erasures-in-wl.patch
new file mode 100644 (file)
index 0000000..2d99f5a
--- /dev/null
@@ -0,0 +1,82 @@
+From 2365418879e9abf12ea9def7f9f3caf0dfa7ffb0 Mon Sep 17 00:00:00 2001
+From: Richard Weinberger <richard@nod.at>
+Date: Wed, 24 Aug 2016 14:36:13 +0200
+Subject: ubi: Deal with interrupted erasures in WL
+
+From: Richard Weinberger <richard@nod.at>
+
+commit 2365418879e9abf12ea9def7f9f3caf0dfa7ffb0 upstream.
+
+When Fastmap is used we can face here an -EBADMSG
+since Fastmap cannot know about unmaps.
+If the erasure was interrupted the PEB may show ECC
+errors and UBI would go to ro-mode as it assumes
+that the PEB was check during attach time, which is
+not the case with Fastmap.
+
+Fixes: dbb7d2a88d ("UBI: Add fastmap core")
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/mtd/ubi/wl.c |   21 +++++++++++++++++++--
+ 1 file changed, 19 insertions(+), 2 deletions(-)
+
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -644,7 +644,7 @@ static int wear_leveling_worker(struct u
+                               int shutdown)
+ {
+       int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0;
+-      int vol_id = -1, lnum = -1;
++      int erase = 0, keep = 0, vol_id = -1, lnum = -1;
+ #ifdef CONFIG_MTD_UBI_FASTMAP
+       int anchor = wrk->anchor;
+ #endif
+@@ -780,6 +780,16 @@ static int wear_leveling_worker(struct u
+                              e1->pnum);
+                       scrubbing = 1;
+                       goto out_not_moved;
++              } else if (ubi->fast_attach && err == UBI_IO_BAD_HDR_EBADMSG) {
++                      /*
++                       * While a full scan would detect interrupted erasures
++                       * at attach time we can face them here when attached from
++                       * Fastmap.
++                       */
++                      dbg_wl("PEB %d has ECC errors, maybe from an interrupted erasure",
++                             e1->pnum);
++                      erase = 1;
++                      goto out_not_moved;
+               }
+               ubi_err(ubi, "error %d while reading VID header from PEB %d",
+@@ -815,6 +825,7 @@ static int wear_leveling_worker(struct u
+                        * Target PEB had bit-flips or write error - torture it.
+                        */
+                       torture = 1;
++                      keep = 1;
+                       goto out_not_moved;
+               }
+@@ -901,7 +912,7 @@ out_not_moved:
+               ubi->erroneous_peb_count += 1;
+       } else if (scrubbing)
+               wl_tree_add(e1, &ubi->scrub);
+-      else
++      else if (keep)
+               wl_tree_add(e1, &ubi->used);
+       if (dst_leb_clean) {
+               wl_tree_add(e2, &ubi->free);
+@@ -921,6 +932,12 @@ out_not_moved:
+               if (err)
+                       goto out_ro;
+       }
++
++      if (erase) {
++              err = do_sync_erase(ubi, e1, vol_id, lnum, 1);
++              if (err)
++                      goto out_ro;
++      }
+       mutex_unlock(&ubi->move_mutex);
+       return 0;