]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 1 Sep 2018 21:36:54 +0000 (14:36 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 1 Sep 2018 21:36:54 +0000 (14:36 -0700)
added patches:
fuse-add-missed-unlock_page-to-fuse_readpages_fill.patch
fuse-don-t-access-pipe-buffers-without-pipe_lock.patch
fuse-fix-double-request_end.patch
fuse-fix-oops-at-process_init_reply.patch
fuse-fix-unlocked-access-to-processing-queue.patch
fuse-umount-should-wait-for-all-requests.patch
x86-process-re-export-start_thread.patch
x86-speculation-l1tf-fix-off-by-one-error-when-warning-that-system-has-too-much-ram.patch
x86-speculation-l1tf-fix-overflow-in-l1tf_pfn_limit-on-32bit.patch
x86-speculation-l1tf-suggest-what-to-do-on-systems-with-too-much-ram.patch

queue-4.4/fuse-add-missed-unlock_page-to-fuse_readpages_fill.patch [new file with mode: 0644]
queue-4.4/fuse-don-t-access-pipe-buffers-without-pipe_lock.patch [new file with mode: 0644]
queue-4.4/fuse-fix-double-request_end.patch [new file with mode: 0644]
queue-4.4/fuse-fix-oops-at-process_init_reply.patch [new file with mode: 0644]
queue-4.4/fuse-fix-unlocked-access-to-processing-queue.patch [new file with mode: 0644]
queue-4.4/fuse-umount-should-wait-for-all-requests.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/x86-process-re-export-start_thread.patch [new file with mode: 0644]
queue-4.4/x86-speculation-l1tf-fix-off-by-one-error-when-warning-that-system-has-too-much-ram.patch [new file with mode: 0644]
queue-4.4/x86-speculation-l1tf-fix-overflow-in-l1tf_pfn_limit-on-32bit.patch [new file with mode: 0644]
queue-4.4/x86-speculation-l1tf-suggest-what-to-do-on-systems-with-too-much-ram.patch [new file with mode: 0644]

diff --git a/queue-4.4/fuse-add-missed-unlock_page-to-fuse_readpages_fill.patch b/queue-4.4/fuse-add-missed-unlock_page-to-fuse_readpages_fill.patch
new file mode 100644 (file)
index 0000000..48ce7b1
--- /dev/null
@@ -0,0 +1,31 @@
+From 109728ccc5933151c68d1106e4065478a487a323 Mon Sep 17 00:00:00 2001
+From: Kirill Tkhai <ktkhai@virtuozzo.com>
+Date: Thu, 19 Jul 2018 15:49:39 +0300
+Subject: fuse: Add missed unlock_page() to fuse_readpages_fill()
+
+From: Kirill Tkhai <ktkhai@virtuozzo.com>
+
+commit 109728ccc5933151c68d1106e4065478a487a323 upstream.
+
+The above error path returns with page unlocked, so this place seems also
+to behave the same.
+
+Fixes: f8dbdf81821b ("fuse: rework fuse_readpages()")
+Signed-off-by: Kirill Tkhai <ktkhai@virtuozzo.com>
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/file.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -879,6 +879,7 @@ static int fuse_readpages_fill(void *_da
+       }
+       if (WARN_ON(req->num_pages >= req->max_pages)) {
++              unlock_page(page);
+               fuse_put_request(fc, req);
+               return -EIO;
+       }
diff --git a/queue-4.4/fuse-don-t-access-pipe-buffers-without-pipe_lock.patch b/queue-4.4/fuse-don-t-access-pipe-buffers-without-pipe_lock.patch
new file mode 100644 (file)
index 0000000..60fb81e
--- /dev/null
@@ -0,0 +1,45 @@
+From a2477b0e67c52f4364a47c3ad70902bc2a61bd4c Mon Sep 17 00:00:00 2001
+From: Andrey Ryabinin <aryabinin@virtuozzo.com>
+Date: Tue, 17 Jul 2018 19:00:33 +0300
+Subject: fuse: Don't access pipe->buffers without pipe_lock()
+
+From: Andrey Ryabinin <aryabinin@virtuozzo.com>
+
+commit a2477b0e67c52f4364a47c3ad70902bc2a61bd4c upstream.
+
+fuse_dev_splice_write() reads pipe->buffers to determine the size of
+'bufs' array before taking the pipe_lock(). This is not safe as
+another thread might change the 'pipe->buffers' between the allocation
+and taking the pipe_lock(). So we end up with too small 'bufs' array.
+
+Move the bufs allocations inside pipe_lock()/pipe_unlock() to fix this.
+
+Fixes: dd3bb14f44a6 ("fuse: support splice() writing to fuse device")
+Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
+Cc: <stable@vger.kernel.org> # v2.6.35
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c |    7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -1991,11 +1991,14 @@ static ssize_t fuse_dev_splice_write(str
+       if (!fud)
+               return -EPERM;
++      pipe_lock(pipe);
++
+       bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL);
+-      if (!bufs)
++      if (!bufs) {
++              pipe_unlock(pipe);
+               return -ENOMEM;
++      }
+-      pipe_lock(pipe);
+       nbuf = 0;
+       rem = 0;
+       for (idx = 0; idx < pipe->nrbufs && rem < len; idx++)
diff --git a/queue-4.4/fuse-fix-double-request_end.patch b/queue-4.4/fuse-fix-double-request_end.patch
new file mode 100644 (file)
index 0000000..bec92d0
--- /dev/null
@@ -0,0 +1,59 @@
+From 87114373ea507895a62afb10d2910bd9adac35a8 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Thu, 26 Jul 2018 16:13:11 +0200
+Subject: fuse: fix double request_end()
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 87114373ea507895a62afb10d2910bd9adac35a8 upstream.
+
+Refcounting of request is broken when fuse_abort_conn() is called and
+request is on the fpq->io list:
+
+ - ref is taken too late
+ - then it is not dropped
+
+Fixes: 0d8e84b0432b ("fuse: simplify request abort")
+Cc: <stable@vger.kernel.org> # v4.2
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -382,7 +382,7 @@ static void request_end(struct fuse_conn
+       struct fuse_iqueue *fiq = &fc->iq;
+       if (test_and_set_bit(FR_FINISHED, &req->flags))
+-              return;
++              goto out_put_req;
+       spin_lock(&fiq->waitq.lock);
+       list_del_init(&req->intr_entry);
+@@ -412,6 +412,7 @@ static void request_end(struct fuse_conn
+       wake_up(&req->waitq);
+       if (req->end)
+               req->end(fc, req);
++out_put_req:
+       fuse_put_request(fc, req);
+ }
+@@ -2154,6 +2155,7 @@ void fuse_abort_conn(struct fuse_conn *f
+                               set_bit(FR_ABORTED, &req->flags);
+                               if (!test_bit(FR_LOCKED, &req->flags)) {
+                                       set_bit(FR_PRIVATE, &req->flags);
++                                      __fuse_get_request(req);
+                                       list_move(&req->list, &to_end1);
+                               }
+                               spin_unlock(&req->waitq.lock);
+@@ -2180,7 +2182,6 @@ void fuse_abort_conn(struct fuse_conn *f
+               while (!list_empty(&to_end1)) {
+                       req = list_first_entry(&to_end1, struct fuse_req, list);
+-                      __fuse_get_request(req);
+                       list_del_init(&req->list);
+                       request_end(fc, req);
+               }
diff --git a/queue-4.4/fuse-fix-oops-at-process_init_reply.patch b/queue-4.4/fuse-fix-oops-at-process_init_reply.patch
new file mode 100644 (file)
index 0000000..a7abf14
--- /dev/null
@@ -0,0 +1,85 @@
+From e8f3bd773d22f488724dffb886a1618da85c2966 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Thu, 26 Jul 2018 16:13:11 +0200
+Subject: fuse: Fix oops at process_init_reply()
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit e8f3bd773d22f488724dffb886a1618da85c2966 upstream.
+
+syzbot is hitting NULL pointer dereference at process_init_reply().
+This is because deactivate_locked_super() is called before response for
+initial request is processed.
+
+Fix this by aborting and waiting for all requests (including FUSE_INIT)
+before resetting fc->sb.
+
+Original patch by Tetsuo Handa <penguin-kernel@I-love.SKAURA.ne.jp>.
+
+Reported-by: syzbot <syzbot+b62f08f4d5857755e3bc@syzkaller.appspotmail.com>
+Fixes: e27c9d3877a0 ("fuse: fuse: add time_gran to INIT_OUT")
+Cc: <stable@vger.kernel.org> # v3.19
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/inode.c |   25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -379,11 +379,6 @@ static void fuse_put_super(struct super_
+ {
+       struct fuse_conn *fc = get_fuse_conn_super(sb);
+-      fuse_send_destroy(fc);
+-
+-      fuse_abort_conn(fc);
+-      fuse_wait_aborted(fc);
+-
+       mutex_lock(&fuse_mutex);
+       list_del(&fc->entry);
+       fuse_ctl_remove_conn(fc);
+@@ -1174,16 +1169,25 @@ static struct dentry *fuse_mount(struct
+       return mount_nodev(fs_type, flags, raw_data, fuse_fill_super);
+ }
+-static void fuse_kill_sb_anon(struct super_block *sb)
++static void fuse_sb_destroy(struct super_block *sb)
+ {
+       struct fuse_conn *fc = get_fuse_conn_super(sb);
+       if (fc) {
++              fuse_send_destroy(fc);
++
++              fuse_abort_conn(fc);
++              fuse_wait_aborted(fc);
++
+               down_write(&fc->killsb);
+               fc->sb = NULL;
+               up_write(&fc->killsb);
+       }
++}
++static void fuse_kill_sb_anon(struct super_block *sb)
++{
++      fuse_sb_destroy(sb);
+       kill_anon_super(sb);
+ }
+@@ -1206,14 +1210,7 @@ static struct dentry *fuse_mount_blk(str
+ static void fuse_kill_sb_blk(struct super_block *sb)
+ {
+-      struct fuse_conn *fc = get_fuse_conn_super(sb);
+-
+-      if (fc) {
+-              down_write(&fc->killsb);
+-              fc->sb = NULL;
+-              up_write(&fc->killsb);
+-      }
+-
++      fuse_sb_destroy(sb);
+       kill_block_super(sb);
+ }
diff --git a/queue-4.4/fuse-fix-unlocked-access-to-processing-queue.patch b/queue-4.4/fuse-fix-unlocked-access-to-processing-queue.patch
new file mode 100644 (file)
index 0000000..6c0b0d6
--- /dev/null
@@ -0,0 +1,41 @@
+From 45ff350bbd9d0f0977ff270a0d427c71520c0c37 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Thu, 26 Jul 2018 16:13:11 +0200
+Subject: fuse: fix unlocked access to processing queue
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit 45ff350bbd9d0f0977ff270a0d427c71520c0c37 upstream.
+
+fuse_dev_release() assumes that it's the only one referencing the
+fpq->processing list, but that's not true, since fuse_abort_conn() can be
+doing the same without any serialization between the two.
+
+Fixes: c3696046beb3 ("fuse: separate pqueue for clones")
+Cc: <stable@vger.kernel.org> # v4.2
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c |    8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -2199,9 +2199,15 @@ int fuse_dev_release(struct inode *inode
+       if (fud) {
+               struct fuse_conn *fc = fud->fc;
+               struct fuse_pqueue *fpq = &fud->pq;
++              LIST_HEAD(to_end);
++              spin_lock(&fpq->lock);
+               WARN_ON(!list_empty(&fpq->io));
+-              end_requests(fc, &fpq->processing);
++              list_splice_init(&fpq->processing, &to_end);
++              spin_unlock(&fpq->lock);
++
++              end_requests(fc, &to_end);
++
+               /* Are we the last open device? */
+               if (atomic_dec_and_test(&fc->dev_count)) {
+                       WARN_ON(fc->iq.fasync != NULL);
diff --git a/queue-4.4/fuse-umount-should-wait-for-all-requests.patch b/queue-4.4/fuse-umount-should-wait-for-all-requests.patch
new file mode 100644 (file)
index 0000000..f4545bb
--- /dev/null
@@ -0,0 +1,116 @@
+From b8f95e5d13f5f0191dcb4b9113113d241636e7cb Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@redhat.com>
+Date: Thu, 26 Jul 2018 16:13:11 +0200
+Subject: fuse: umount should wait for all requests
+
+From: Miklos Szeredi <mszeredi@redhat.com>
+
+commit b8f95e5d13f5f0191dcb4b9113113d241636e7cb upstream.
+
+fuse_abort_conn() does not guarantee that all async requests have actually
+finished aborting (i.e. their ->end() function is called).  This could
+actually result in still used inodes after umount.
+
+Add a helper to wait until all requests are fully done.  This is done by
+looking at the "num_waiting" counter.  When this counter drops to zero, we
+can be sure that no more requests are outstanding.
+
+Fixes: 0d8e84b0432b ("fuse: simplify request abort")
+Cc: <stable@vger.kernel.org> # v4.2
+Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/fuse/dev.c    |   23 +++++++++++++++++++----
+ fs/fuse/fuse_i.h |    1 +
+ fs/fuse/inode.c  |    2 ++
+ 3 files changed, 22 insertions(+), 4 deletions(-)
+
+--- a/fs/fuse/dev.c
++++ b/fs/fuse/dev.c
+@@ -143,6 +143,16 @@ static bool fuse_block_alloc(struct fuse
+       return !fc->initialized || (for_background && fc->blocked);
+ }
++static void fuse_drop_waiting(struct fuse_conn *fc)
++{
++      if (fc->connected) {
++              atomic_dec(&fc->num_waiting);
++      } else if (atomic_dec_and_test(&fc->num_waiting)) {
++              /* wake up aborters */
++              wake_up_all(&fc->blocked_waitq);
++      }
++}
++
+ static struct fuse_req *__fuse_get_req(struct fuse_conn *fc, unsigned npages,
+                                      bool for_background)
+ {
+@@ -189,7 +199,7 @@ static struct fuse_req *__fuse_get_req(s
+       return req;
+  out:
+-      atomic_dec(&fc->num_waiting);
++      fuse_drop_waiting(fc);
+       return ERR_PTR(err);
+ }
+@@ -296,7 +306,7 @@ void fuse_put_request(struct fuse_conn *
+               if (test_bit(FR_WAITING, &req->flags)) {
+                       __clear_bit(FR_WAITING, &req->flags);
+-                      atomic_dec(&fc->num_waiting);
++                      fuse_drop_waiting(fc);
+               }
+               if (req->stolen_file)
+@@ -382,7 +392,7 @@ static void request_end(struct fuse_conn
+       struct fuse_iqueue *fiq = &fc->iq;
+       if (test_and_set_bit(FR_FINISHED, &req->flags))
+-              goto out_put_req;
++              goto put_request;
+       spin_lock(&fiq->waitq.lock);
+       list_del_init(&req->intr_entry);
+@@ -412,7 +422,7 @@ static void request_end(struct fuse_conn
+       wake_up(&req->waitq);
+       if (req->end)
+               req->end(fc, req);
+-out_put_req:
++put_request:
+       fuse_put_request(fc, req);
+ }
+@@ -2192,6 +2202,11 @@ void fuse_abort_conn(struct fuse_conn *f
+ }
+ EXPORT_SYMBOL_GPL(fuse_abort_conn);
++void fuse_wait_aborted(struct fuse_conn *fc)
++{
++      wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0);
++}
++
+ int fuse_dev_release(struct inode *inode, struct file *file)
+ {
+       struct fuse_dev *fud = fuse_get_dev(file);
+--- a/fs/fuse/fuse_i.h
++++ b/fs/fuse/fuse_i.h
+@@ -842,6 +842,7 @@ void fuse_request_send_background_locked
+ /* Abort all requests */
+ void fuse_abort_conn(struct fuse_conn *fc);
++void fuse_wait_aborted(struct fuse_conn *fc);
+ /**
+  * Invalidate inode attributes
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -382,6 +382,8 @@ static void fuse_put_super(struct super_
+       fuse_send_destroy(fc);
+       fuse_abort_conn(fc);
++      fuse_wait_aborted(fc);
++
+       mutex_lock(&fuse_mutex);
+       list_del(&fc->entry);
+       fuse_ctl_remove_conn(fc);
index 5410de384027f720ac66fa7bba07c346b1a461f5..ad9a9c5e6155f76238263261b951f91e34055068 100644 (file)
@@ -50,3 +50,13 @@ ext4-reset-error-code-in-ext4_find_entry-in-fallback.patch
 arm64-mm-check-for-upper-page_shift-bits-in-pfn_valid.patch
 kvm-arm-arm64-skip-updating-pte-entry-if-no-change.patch
 kvm-arm-arm64-skip-updating-pmd-entry-if-no-change.patch
+x86-speculation-l1tf-fix-overflow-in-l1tf_pfn_limit-on-32bit.patch
+x86-speculation-l1tf-fix-off-by-one-error-when-warning-that-system-has-too-much-ram.patch
+x86-speculation-l1tf-suggest-what-to-do-on-systems-with-too-much-ram.patch
+x86-process-re-export-start_thread.patch
+fuse-don-t-access-pipe-buffers-without-pipe_lock.patch
+fuse-fix-double-request_end.patch
+fuse-fix-unlocked-access-to-processing-queue.patch
+fuse-umount-should-wait-for-all-requests.patch
+fuse-fix-oops-at-process_init_reply.patch
+fuse-add-missed-unlock_page-to-fuse_readpages_fill.patch
diff --git a/queue-4.4/x86-process-re-export-start_thread.patch b/queue-4.4/x86-process-re-export-start_thread.patch
new file mode 100644 (file)
index 0000000..a4b6db6
--- /dev/null
@@ -0,0 +1,42 @@
+From dc76803e57cc86589c4efcb5362918f9b0c0436f Mon Sep 17 00:00:00 2001
+From: Rian Hunter <rian@alum.mit.edu>
+Date: Sun, 19 Aug 2018 16:08:53 -0700
+Subject: x86/process: Re-export start_thread()
+
+From: Rian Hunter <rian@alum.mit.edu>
+
+commit dc76803e57cc86589c4efcb5362918f9b0c0436f upstream.
+
+The consolidation of the start_thread() functions removed the export
+unintentionally. This breaks binfmt handlers built as a module.
+
+Add it back.
+
+Fixes: e634d8fc792c ("x86-64: merge the standard and compat start_thread() functions")
+Signed-off-by: Rian Hunter <rian@alum.mit.edu>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: "H. Peter Anvin" <hpa@zytor.com>
+Cc: Andy Lutomirski <luto@kernel.org>
+Cc: Borislav Petkov <bpetkov@suse.de>
+Cc: Vitaly Kuznetsov <vkuznets@redhat.com>
+Cc: Joerg Roedel <jroedel@suse.de>
+Cc: Dmitry Safonov <dima@arista.com>
+Cc: Josh Poimboeuf <jpoimboe@redhat.com>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20180819230854.7275-1-rian@alum.mit.edu
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/process_64.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -250,6 +250,7 @@ start_thread(struct pt_regs *regs, unsig
+       start_thread_common(regs, new_ip, new_sp,
+                           __USER_CS, __USER_DS, 0);
+ }
++EXPORT_SYMBOL_GPL(start_thread);
+ #ifdef CONFIG_COMPAT
+ void compat_start_thread(struct pt_regs *regs, u32 new_ip, u32 new_sp)
diff --git a/queue-4.4/x86-speculation-l1tf-fix-off-by-one-error-when-warning-that-system-has-too-much-ram.patch b/queue-4.4/x86-speculation-l1tf-fix-off-by-one-error-when-warning-that-system-has-too-much-ram.patch
new file mode 100644 (file)
index 0000000..5008739
--- /dev/null
@@ -0,0 +1,82 @@
+From b0a182f875689647b014bc01d36b340217792852 Mon Sep 17 00:00:00 2001
+From: Vlastimil Babka <vbabka@suse.cz>
+Date: Thu, 23 Aug 2018 15:44:18 +0200
+Subject: x86/speculation/l1tf: Fix off-by-one error when warning that system has too much RAM
+
+From: Vlastimil Babka <vbabka@suse.cz>
+
+commit b0a182f875689647b014bc01d36b340217792852 upstream.
+
+Two users have reported [1] that they have an "extremely unlikely" system
+with more than MAX_PA/2 memory and L1TF mitigation is not effective. In
+fact it's a CPU with 36bits phys limit (64GB) and 32GB memory, but due to
+holes in the e820 map, the main region is almost 500MB over the 32GB limit:
+
+[    0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000081effffff] usable
+
+Suggestions to use 'mem=32G' to enable the L1TF mitigation while losing the
+500MB revealed, that there's an off-by-one error in the check in
+l1tf_select_mitigation().
+
+l1tf_pfn_limit() returns the last usable pfn (inclusive) and the range
+check in the mitigation path does not take this into account.
+
+Instead of amending the range check, make l1tf_pfn_limit() return the first
+PFN which is over the limit which is less error prone. Adjust the other
+users accordingly.
+
+[1] https://bugzilla.suse.com/show_bug.cgi?id=1105536
+
+Fixes: 17dbca119312 ("x86/speculation/l1tf: Add sysfs reporting for l1tf")
+Reported-by: George Anchev <studio@anchev.net>
+Reported-by: Christopher Snowhill <kode54@gmail.com>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Cc: "H . Peter Anvin" <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20180823134418.17008-1-vbabka@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/processor.h |    2 +-
+ arch/x86/mm/init.c               |    2 +-
+ arch/x86/mm/mmap.c               |    2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -174,7 +174,7 @@ extern void cpu_detect(struct cpuinfo_x8
+ static inline unsigned long long l1tf_pfn_limit(void)
+ {
+-      return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT) - 1;
++      return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT);
+ }
+ extern void early_cpu_init(void);
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -779,7 +779,7 @@ unsigned long max_swapfile_size(void)
+       if (boot_cpu_has_bug(X86_BUG_L1TF)) {
+               /* Limit the swap file size to MAX_PA/2 for L1TF workaround */
+-              unsigned long long l1tf_limit = l1tf_pfn_limit() + 1;
++              unsigned long long l1tf_limit = l1tf_pfn_limit();
+               /*
+                * We encode swap offsets also with 3 bits below those for pfn
+                * which makes the usable limit higher.
+--- a/arch/x86/mm/mmap.c
++++ b/arch/x86/mm/mmap.c
+@@ -138,7 +138,7 @@ bool pfn_modify_allowed(unsigned long pf
+       /* If it's real memory always allow */
+       if (pfn_valid(pfn))
+               return true;
+-      if (pfn > l1tf_pfn_limit() && !capable(CAP_SYS_ADMIN))
++      if (pfn >= l1tf_pfn_limit() && !capable(CAP_SYS_ADMIN))
+               return false;
+       return true;
+ }
diff --git a/queue-4.4/x86-speculation-l1tf-fix-overflow-in-l1tf_pfn_limit-on-32bit.patch b/queue-4.4/x86-speculation-l1tf-fix-overflow-in-l1tf_pfn_limit-on-32bit.patch
new file mode 100644 (file)
index 0000000..18fb11d
--- /dev/null
@@ -0,0 +1,75 @@
+From 9df9516940a61d29aedf4d91b483ca6597e7d480 Mon Sep 17 00:00:00 2001
+From: Vlastimil Babka <vbabka@suse.cz>
+Date: Mon, 20 Aug 2018 11:58:35 +0200
+Subject: x86/speculation/l1tf: Fix overflow in l1tf_pfn_limit() on 32bit
+
+From: Vlastimil Babka <vbabka@suse.cz>
+
+commit 9df9516940a61d29aedf4d91b483ca6597e7d480 upstream.
+
+On 32bit PAE kernels on 64bit hardware with enough physical bits,
+l1tf_pfn_limit() will overflow unsigned long. This in turn affects
+max_swapfile_size() and can lead to swapon returning -EINVAL. This has been
+observed in a 32bit guest with 42 bits physical address size, where
+max_swapfile_size() overflows exactly to 1 << 32, thus zero, and produces
+the following warning to dmesg:
+
+[    6.396845] Truncating oversized swap area, only using 0k out of 2047996k
+
+Fix this by using unsigned long long instead.
+
+Fixes: 17dbca119312 ("x86/speculation/l1tf: Add sysfs reporting for l1tf")
+Fixes: 377eeaa8e11f ("x86/speculation/l1tf: Limit swap file size to MAX_PA/2")
+Reported-by: Dominique Leuenberger <dimstar@suse.de>
+Reported-by: Adrian Schroeter <adrian@suse.de>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Acked-by: Andi Kleen <ak@linux.intel.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: "H . Peter Anvin" <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: Michal Hocko <mhocko@kernel.org>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/20180820095835.5298-1-vbabka@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/processor.h |    4 ++--
+ arch/x86/mm/init.c               |    4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/arch/x86/include/asm/processor.h
++++ b/arch/x86/include/asm/processor.h
+@@ -172,9 +172,9 @@ extern const struct seq_operations cpuin
+ extern void cpu_detect(struct cpuinfo_x86 *c);
+-static inline unsigned long l1tf_pfn_limit(void)
++static inline unsigned long long l1tf_pfn_limit(void)
+ {
+-      return BIT(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT) - 1;
++      return BIT_ULL(boot_cpu_data.x86_phys_bits - 1 - PAGE_SHIFT) - 1;
+ }
+ extern void early_cpu_init(void);
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -779,7 +779,7 @@ unsigned long max_swapfile_size(void)
+       if (boot_cpu_has_bug(X86_BUG_L1TF)) {
+               /* Limit the swap file size to MAX_PA/2 for L1TF workaround */
+-              unsigned long l1tf_limit = l1tf_pfn_limit() + 1;
++              unsigned long long l1tf_limit = l1tf_pfn_limit() + 1;
+               /*
+                * We encode swap offsets also with 3 bits below those for pfn
+                * which makes the usable limit higher.
+@@ -787,7 +787,7 @@ unsigned long max_swapfile_size(void)
+ #if CONFIG_PGTABLE_LEVELS > 2
+               l1tf_limit <<= PAGE_SHIFT - SWP_OFFSET_FIRST_BIT;
+ #endif
+-              pages = min_t(unsigned long, l1tf_limit, pages);
++              pages = min_t(unsigned long long, l1tf_limit, pages);
+       }
+       return pages;
+ }
diff --git a/queue-4.4/x86-speculation-l1tf-suggest-what-to-do-on-systems-with-too-much-ram.patch b/queue-4.4/x86-speculation-l1tf-suggest-what-to-do-on-systems-with-too-much-ram.patch
new file mode 100644 (file)
index 0000000..2796e81
--- /dev/null
@@ -0,0 +1,46 @@
+From 6a012288d6906fee1dbc244050ade1dafe4a9c8d Mon Sep 17 00:00:00 2001
+From: Vlastimil Babka <vbabka@suse.cz>
+Date: Thu, 23 Aug 2018 16:21:29 +0200
+Subject: x86/speculation/l1tf: Suggest what to do on systems with too much RAM
+
+From: Vlastimil Babka <vbabka@suse.cz>
+
+commit 6a012288d6906fee1dbc244050ade1dafe4a9c8d upstream.
+
+Two users have reported [1] that they have an "extremely unlikely" system
+with more than MAX_PA/2 memory and L1TF mitigation is not effective.
+
+Make the warning more helpful by suggesting the proper mem=X kernel boot
+parameter to make it effective and a link to the L1TF document to help
+decide if the mitigation is worth the unusable RAM.
+
+[1] https://bugzilla.suse.com/show_bug.cgi?id=1105536
+
+Suggested-by: Michal Hocko <mhocko@suse.com>
+Signed-off-by: Vlastimil Babka <vbabka@suse.cz>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: "H . Peter Anvin" <hpa@zytor.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Andi Kleen <ak@linux.intel.com>
+Cc: Dave Hansen <dave.hansen@intel.com>
+Cc: stable@vger.kernel.org
+Link: https://lkml.kernel.org/r/966571f0-9d7f-43dc-92c6-a10eec7a1254@suse.cz
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kernel/cpu/bugs.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/arch/x86/kernel/cpu/bugs.c
++++ b/arch/x86/kernel/cpu/bugs.c
+@@ -654,6 +654,10 @@ static void __init l1tf_select_mitigatio
+       half_pa = (u64)l1tf_pfn_limit() << PAGE_SHIFT;
+       if (e820_any_mapped(half_pa, ULLONG_MAX - half_pa, E820_RAM)) {
+               pr_warn("System has more than MAX_PA/2 memory. L1TF mitigation not effective.\n");
++              pr_info("You may make it effective by booting the kernel with mem=%llu parameter.\n",
++                              half_pa);
++              pr_info("However, doing so will make a part of your RAM unusable.\n");
++              pr_info("Reading https://www.kernel.org/doc/html/latest/admin-guide/l1tf.html might help you decide.\n");
+               return;
+       }