--- /dev/null
+From 60942f2f235ce7b817166cdf355eed729094834d Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Fri, 2 May 2014 15:38:39 -0400
+Subject: dcache: don't need rcu in shrink_dentry_list()
+
+From: Miklos Szeredi <mszeredi@suse.cz>
+
+commit 60942f2f235ce7b817166cdf355eed729094834d upstream.
+
+Since now the shrink list is private and nobody can free the dentry while
+it is on the shrink list, we can remove RCU protection from this.
+
+Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dcache.c | 27 ++++-----------------------
+ 1 file changed, 4 insertions(+), 23 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -797,23 +797,9 @@ static void shrink_dentry_list(struct li
+ {
+ struct dentry *dentry, *parent;
+
+- rcu_read_lock();
+- for (;;) {
+- dentry = list_entry_rcu(list->prev, struct dentry, d_lru);
+- if (&dentry->d_lru == list)
+- break; /* empty */
+-
+- /*
+- * Get the dentry lock, and re-verify that the dentry is
+- * this on the shrinking list. If it is, we know that
+- * DCACHE_SHRINK_LIST and DCACHE_LRU_LIST are set.
+- */
++ while (!list_empty(list)) {
++ dentry = list_entry(list->prev, struct dentry, d_lru);
+ spin_lock(&dentry->d_lock);
+- if (dentry != list_entry(list->prev, struct dentry, d_lru)) {
+- spin_unlock(&dentry->d_lock);
+- continue;
+- }
+-
+ /*
+ * The dispose list is isolated and dentries are not accounted
+ * to the LRU here, so we can simply remove it from the list
+@@ -829,23 +815,20 @@ static void shrink_dentry_list(struct li
+ spin_unlock(&dentry->d_lock);
+ continue;
+ }
+- rcu_read_unlock();
+
+ parent = dentry_kill(dentry, 0);
+ /*
+ * If dentry_kill returns NULL, we have nothing more to do.
+ */
+- if (!parent) {
+- rcu_read_lock();
++ if (!parent)
+ continue;
+- }
++
+ if (unlikely(parent == dentry)) {
+ /*
+ * trylocks have failed and d_lock has been held the
+ * whole time, so it could not have been added to any
+ * other lists. Just add it back to the shrink list.
+ */
+- rcu_read_lock();
+ d_shrink_add(dentry, list);
+ spin_unlock(&dentry->d_lock);
+ continue;
+@@ -859,9 +842,7 @@ static void shrink_dentry_list(struct li
+ dentry = parent;
+ while (dentry && !lockref_put_or_lock(&dentry->d_lockref))
+ dentry = dentry_kill(dentry, 1);
+- rcu_read_lock();
+ }
+- rcu_read_unlock();
+ }
+
+ static enum lru_status
--- /dev/null
+From 41edf278fc2f042f4e22a12ed87d19c5201210e1 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Thu, 1 May 2014 10:30:00 -0400
+Subject: dentry_kill(): don't try to remove from shrink list
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 41edf278fc2f042f4e22a12ed87d19c5201210e1 upstream.
+
+If the victim in on the shrink list, don't remove it from there.
+If shrink_dentry_list() manages to remove it from the list before
+we are done - fine, we'll just free it as usual. If not - mark
+it with new flag (DCACHE_MAY_FREE) and leave it there.
+
+Eventually, shrink_dentry_list() will get to it, remove the sucker
+from shrink list and call dentry_kill(dentry, 0). Which is where
+we'll deal with freeing.
+
+Since now dentry_kill(dentry, 0) may happen after or during
+dentry_kill(dentry, 1), we need to recognize that (by seeing
+DCACHE_DENTRY_KILLED already set), unlock everything
+and either free the sucker (in case DCACHE_MAY_FREE has been
+set) or leave it for ongoing dentry_kill(dentry, 1) to deal with.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dcache.c | 27 +++++++++++++++++++--------
+ include/linux/dcache.h | 2 ++
+ 2 files changed, 21 insertions(+), 8 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -466,7 +466,14 @@ dentry_kill(struct dentry *dentry, int u
+ __releases(dentry->d_lock)
+ {
+ struct inode *inode;
+- struct dentry *parent;
++ struct dentry *parent = NULL;
++ bool can_free = true;
++
++ if (unlikely(dentry->d_flags & DCACHE_DENTRY_KILLED)) {
++ can_free = dentry->d_flags & DCACHE_MAY_FREE;
++ spin_unlock(&dentry->d_lock);
++ goto out;
++ }
+
+ inode = dentry->d_inode;
+ if (inode && !spin_trylock(&inode->i_lock)) {
+@@ -477,9 +484,7 @@ relock:
+ }
+ return dentry; /* try again with same dentry */
+ }
+- if (IS_ROOT(dentry))
+- parent = NULL;
+- else
++ if (!IS_ROOT(dentry))
+ parent = dentry->d_parent;
+ if (parent && !spin_trylock(&parent->d_lock)) {
+ if (inode)
+@@ -502,8 +507,6 @@ relock:
+ if (dentry->d_flags & DCACHE_LRU_LIST) {
+ if (!(dentry->d_flags & DCACHE_SHRINK_LIST))
+ d_lru_del(dentry);
+- else
+- d_shrink_del(dentry);
+ }
+ /* if it was on the hash then remove it */
+ __d_drop(dentry);
+@@ -525,7 +528,15 @@ relock:
+ if (dentry->d_op && dentry->d_op->d_release)
+ dentry->d_op->d_release(dentry);
+
+- dentry_free(dentry);
++ spin_lock(&dentry->d_lock);
++ if (dentry->d_flags & DCACHE_SHRINK_LIST) {
++ dentry->d_flags |= DCACHE_MAY_FREE;
++ can_free = false;
++ }
++ spin_unlock(&dentry->d_lock);
++out:
++ if (likely(can_free))
++ dentry_free(dentry);
+ return parent;
+ }
+
+@@ -830,7 +841,7 @@ static void shrink_dentry_list(struct li
+ * We found an inuse dentry which was not removed from
+ * the LRU because of laziness during lookup. Do not free it.
+ */
+- if (dentry->d_lockref.count) {
++ if ((int)dentry->d_lockref.count > 0) {
+ spin_unlock(&dentry->d_lock);
+ continue;
+ }
+--- a/include/linux/dcache.h
++++ b/include/linux/dcache.h
+@@ -221,6 +221,8 @@ struct dentry_operations {
+ #define DCACHE_SYMLINK_TYPE 0x00300000 /* Symlink */
+ #define DCACHE_FILE_TYPE 0x00400000 /* Other file type */
+
++#define DCACHE_MAY_FREE 0x00800000
++
+ extern seqlock_t rename_lock;
+
+ static inline int dname_external(const struct dentry *dentry)
--- /dev/null
+From fe91522a7ba82ca1a51b07e19954b3825e4aaa22 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Sat, 3 May 2014 00:02:25 -0400
+Subject: don't remove from shrink list in select_collect()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit fe91522a7ba82ca1a51b07e19954b3825e4aaa22 upstream.
+
+ If we find something already on a shrink list, just increment
+data->found and do nothing else. Loops in shrink_dcache_parent() and
+check_submounts_and_drop() will do the right thing - everything we
+did put into our list will be evicted and if there had been nothing,
+but data->found got non-zero, well, we have somebody else shrinking
+those guys; just try again.
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dcache.c | 31 ++++++++++---------------------
+ 1 file changed, 10 insertions(+), 21 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -1231,34 +1231,23 @@ static enum d_walk_ret select_collect(vo
+ if (data->start == dentry)
+ goto out;
+
+- /*
+- * move only zero ref count dentries to the dispose list.
+- *
+- * Those which are presently on the shrink list, being processed
+- * by shrink_dentry_list(), shouldn't be moved. Otherwise the
+- * loop in shrink_dcache_parent() might not make any progress
+- * and loop forever.
+- */
+- if (dentry->d_lockref.count) {
+- dentry_lru_del(dentry);
+- } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
+- /*
+- * We can't use d_lru_shrink_move() because we
+- * need to get the global LRU lock and do the
+- * LRU accounting.
+- */
+- d_lru_del(dentry);
+- d_shrink_add(dentry, &data->dispose);
++ if (dentry->d_flags & DCACHE_SHRINK_LIST) {
+ data->found++;
+- ret = D_WALK_NORETRY;
++ } else {
++ if (dentry->d_flags & DCACHE_LRU_LIST)
++ d_lru_del(dentry);
++ if (!dentry->d_lockref.count) {
++ d_shrink_add(dentry, &data->dispose);
++ data->found++;
++ }
+ }
+ /*
+ * We can return to the caller if we have found some (this
+ * ensures forward progress). We'll be coming back to find
+ * the rest.
+ */
+- if (data->found && need_resched())
+- ret = D_WALK_QUIT;
++ if (!list_empty(&data->dispose))
++ ret = need_resched() ? D_WALK_QUIT : D_WALK_NORETRY;
+ out:
+ return ret;
+ }
--- /dev/null
+From ce40cd3fc7fa40a6119e5fe6c0f2bc0eb4541009 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Sat, 30 May 2015 14:31:24 +0200
+Subject: kvm: x86: fix kvm_apic_has_events to check for NULL pointer
+
+From: Paolo Bonzini <pbonzini@redhat.com>
+
+commit ce40cd3fc7fa40a6119e5fe6c0f2bc0eb4541009 upstream.
+
+Malicious (or egregiously buggy) userspace can trigger it, but it
+should never happen in normal operation.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Wang Kai <morgan.wang@huawei.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/kvm/lapic.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/x86/kvm/lapic.h
++++ b/arch/x86/kvm/lapic.h
+@@ -165,7 +165,7 @@ static inline u16 apic_logical_id(struct
+
+ static inline bool kvm_apic_has_events(struct kvm_vcpu *vcpu)
+ {
+- return vcpu->arch.apic->pending_events;
++ return kvm_vcpu_has_lapic(vcpu) && vcpu->arch.apic->pending_events;
+ }
+
+ bool kvm_apic_pending_eoi(struct kvm_vcpu *vcpu, int vector);
--- /dev/null
+From 9c8c10e262e0f62cb2530f1b076de979123183dd Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Fri, 2 May 2014 20:36:10 -0400
+Subject: more graceful recovery in umount_collect()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit 9c8c10e262e0f62cb2530f1b076de979123183dd upstream.
+
+Start with shrink_dcache_parent(), then scan what remains.
+
+First of all, BUG() is very much an overkill here; we are holding
+->s_umount, and hitting BUG() means that a lot of interesting stuff
+will be hanging after that point (sync(2), for example). Moreover,
+in cases when there had been more than one leak, we'll be better
+off reporting all of them. And more than just the last component
+of pathname - %pd is there for just such uses...
+
+That was the last user of dentry_lru_del(), so kill it off...
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Cc: "Nicholas A. Bellinger" <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/dcache.c | 101 ++++++++++++++----------------------------------------------
+ 1 file changed, 25 insertions(+), 76 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -393,22 +393,6 @@ static void dentry_lru_add(struct dentry
+ d_lru_add(dentry);
+ }
+
+-/*
+- * Remove a dentry with references from the LRU.
+- *
+- * If we are on the shrink list, then we can get to try_prune_one_dentry() and
+- * lose our last reference through the parent walk. In this case, we need to
+- * remove ourselves from the shrink list, not the LRU.
+- */
+-static void dentry_lru_del(struct dentry *dentry)
+-{
+- if (dentry->d_flags & DCACHE_LRU_LIST) {
+- if (dentry->d_flags & DCACHE_SHRINK_LIST)
+- return d_shrink_del(dentry);
+- d_lru_del(dentry);
+- }
+-}
+-
+ /**
+ * d_drop - drop a dentry
+ * @dentry: dentry to drop
+@@ -1277,45 +1261,35 @@ void shrink_dcache_parent(struct dentry
+ }
+ EXPORT_SYMBOL(shrink_dcache_parent);
+
+-static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry)
++static enum d_walk_ret umount_check(void *_data, struct dentry *dentry)
+ {
+- struct select_data *data = _data;
+- enum d_walk_ret ret = D_WALK_CONTINUE;
++ /* it has busy descendents; complain about those instead */
++ if (!list_empty(&dentry->d_subdirs))
++ return D_WALK_CONTINUE;
++
++ /* root with refcount 1 is fine */
++ if (dentry == _data && dentry->d_lockref.count == 1)
++ return D_WALK_CONTINUE;
+
+- if (dentry->d_lockref.count) {
+- dentry_lru_del(dentry);
+- if (likely(!list_empty(&dentry->d_subdirs)))
+- goto out;
+- if (dentry == data->start && dentry->d_lockref.count == 1)
+- goto out;
+- printk(KERN_ERR
+- "BUG: Dentry %p{i=%lx,n=%s}"
+- " still in use (%d)"
+- " [unmount of %s %s]\n",
++ printk(KERN_ERR "BUG: Dentry %p{i=%lx,n=%pd} "
++ " still in use (%d) [unmount of %s %s]\n",
+ dentry,
+ dentry->d_inode ?
+ dentry->d_inode->i_ino : 0UL,
+- dentry->d_name.name,
++ dentry,
+ dentry->d_lockref.count,
+ dentry->d_sb->s_type->name,
+ dentry->d_sb->s_id);
+- BUG();
+- } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) {
+- /*
+- * We can't use d_lru_shrink_move() because we
+- * need to get the global LRU lock and do the
+- * LRU accounting.
+- */
+- if (dentry->d_flags & DCACHE_LRU_LIST)
+- d_lru_del(dentry);
+- d_shrink_add(dentry, &data->dispose);
+- data->found++;
+- ret = D_WALK_NORETRY;
+- }
+-out:
+- if (data->found && need_resched())
+- ret = D_WALK_QUIT;
+- return ret;
++ WARN_ON(1);
++ return D_WALK_CONTINUE;
++}
++
++static void do_one_tree(struct dentry *dentry)
++{
++ shrink_dcache_parent(dentry);
++ d_walk(dentry, dentry, umount_check, NULL);
++ d_drop(dentry);
++ dput(dentry);
+ }
+
+ /*
+@@ -1325,40 +1299,15 @@ void shrink_dcache_for_umount(struct sup
+ {
+ struct dentry *dentry;
+
+- if (down_read_trylock(&sb->s_umount))
+- BUG();
++ WARN(down_read_trylock(&sb->s_umount), "s_umount should've been locked");
+
+ dentry = sb->s_root;
+ sb->s_root = NULL;
+- for (;;) {
+- struct select_data data;
+-
+- INIT_LIST_HEAD(&data.dispose);
+- data.start = dentry;
+- data.found = 0;
+-
+- d_walk(dentry, &data, umount_collect, NULL);
+- if (!data.found)
+- break;
+-
+- shrink_dentry_list(&data.dispose);
+- cond_resched();
+- }
+- d_drop(dentry);
+- dput(dentry);
++ do_one_tree(dentry);
+
+ while (!hlist_bl_empty(&sb->s_anon)) {
+- struct select_data data;
+- dentry = hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash);
+-
+- INIT_LIST_HEAD(&data.dispose);
+- data.start = NULL;
+- data.found = 0;
+-
+- d_walk(dentry, &data, umount_collect, NULL);
+- if (data.found)
+- shrink_dentry_list(&data.dispose);
+- cond_resched();
++ dentry = dget(hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash));
++ do_one_tree(dentry);
+ }
+ }
+
--- /dev/null
+From f15133df088ecadd141ea1907f2c96df67c729f0 Mon Sep 17 00:00:00 2001
+From: Al Viro <viro@zeniv.linux.org.uk>
+Date: Fri, 8 May 2015 22:53:15 -0400
+Subject: path_openat(): fix double fput()
+
+From: Al Viro <viro@zeniv.linux.org.uk>
+
+commit f15133df088ecadd141ea1907f2c96df67c729f0 upstream.
+
+path_openat() jumps to the wrong place after do_tmpfile() - it has
+already done path_cleanup() (as part of path_lookupat() called by
+do_tmpfile()), so doing that again can lead to double fput().
+
+Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/namei.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -3171,7 +3171,7 @@ static struct file *path_openat(int dfd,
+
+ if (unlikely(file->f_flags & __O_TMPFILE)) {
+ error = do_tmpfile(dfd, pathname, nd, flags, op, file, &opened);
+- goto out;
++ goto out2;
+ }
+
+ error = path_init(dfd, pathname->name, flags | LOOKUP_PARENT, nd, &base);
+@@ -3209,6 +3209,7 @@ out:
+ path_put(&nd->root);
+ if (base)
+ fput(base);
++out2:
+ if (!(opened & FILE_OPENED)) {
+ BUG_ON(!error);
+ put_filp(file);
fold-try_prune_one_dentry.patch
new-helper-dentry_free.patch
expand-the-call-of-dentry_lru_del-in-dentry_kill.patch
+dentry_kill-don-t-try-to-remove-from-shrink-list.patch
+don-t-remove-from-shrink-list-in-select_collect.patch
+more-graceful-recovery-in-umount_collect.patch
+dcache-don-t-need-rcu-in-shrink_dentry_list.patch
+kvm-x86-fix-kvm_apic_has_events-to-check-for-null-pointer.patch
+path_openat-fix-double-fput.patch