--- /dev/null
+From 62a6cfddcc0a5313e7da3e8311ba16226fe0ac10 Mon Sep 17 00:00:00 2001
+From: Sachin Prabhu <sprabhu@redhat.com>
+Date: Sun, 16 Apr 2017 20:37:24 +0100
+Subject: cifs: Do not send echoes before Negotiate is complete
+
+From: Sachin Prabhu <sprabhu@redhat.com>
+
+commit 62a6cfddcc0a5313e7da3e8311ba16226fe0ac10 upstream.
+
+commit 4fcd1813e640 ("Fix reconnect to not defer smb3 session reconnect
+long after socket reconnect") added support for Negotiate requests to
+be initiated by echo calls.
+
+To avoid delays in calling echo after a reconnect, I added the patch
+introduced by the commit b8c600120fc8 ("Call echo service immediately
+after socket reconnect").
+
+This has however caused a regression with cifs shares which do not have
+support for echo calls to trigger Negotiate requests. On connections
+which need to call Negotiation, the echo calls trigger an error which
+triggers a reconnect which in turn triggers another echo call. This
+results in a loop which is only broken when an operation is performed on
+the cifs share. For an idle share, it can DOS a server.
+
+The patch uses the smb_operation can_echo() for cifs so that it is
+called only if connection has been already been setup.
+
+kernel bz: 194531
+
+Signed-off-by: Sachin Prabhu <sprabhu@redhat.com>
+Tested-by: Jonathan Liu <net147@gmail.com>
+Acked-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/cifs/smb1ops.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/fs/cifs/smb1ops.c
++++ b/fs/cifs/smb1ops.c
+@@ -1015,6 +1015,15 @@ cifs_dir_needs_close(struct cifsFileInfo
+ return !cfile->srch_inf.endOfSearch && !cfile->invalidHandle;
+ }
+
++static bool
++cifs_can_echo(struct TCP_Server_Info *server)
++{
++ if (server->tcpStatus == CifsGood)
++ return true;
++
++ return false;
++}
++
+ struct smb_version_operations smb1_operations = {
+ .send_cancel = send_nt_cancel,
+ .compare_fids = cifs_compare_fids,
+@@ -1049,6 +1058,7 @@ struct smb_version_operations smb1_opera
+ .get_dfs_refer = CIFSGetDFSRefer,
+ .qfs_tcon = cifs_qfs_tcon,
+ .is_path_accessible = cifs_is_path_accessible,
++ .can_echo = cifs_can_echo,
+ .query_path_info = cifs_query_path_info,
+ .query_file_info = cifs_query_file_info,
+ .get_srv_inum = cifs_get_srv_inum,
--- /dev/null
+From a0918f1ce6a43ac980b42b300ec443c154970979 Mon Sep 17 00:00:00 2001
+From: Germano Percossi <germano.percossi@citrix.com>
+Date: Fri, 7 Apr 2017 12:29:37 +0100
+Subject: CIFS: remove bad_network_name flag
+
+From: Germano Percossi <germano.percossi@citrix.com>
+
+commit a0918f1ce6a43ac980b42b300ec443c154970979 upstream.
+
+STATUS_BAD_NETWORK_NAME can be received during node failover,
+causing the flag to be set and making the reconnect thread
+always unsuccessful, thereafter.
+
+Once the only place where it is set is removed, the remaining
+bits are rendered moot.
+
+Removing it does not prevent "mount" from failing when a non
+existent share is passed.
+
+What happens when the share really ceases to exist while the
+share is mounted is undefined now as much as it was before.
+
+Signed-off-by: Germano Percossi <germano.percossi@citrix.com>
+Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
+Signed-off-by: Steve French <smfrench@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+
+---
+ fs/cifs/cifsglob.h | 1 -
+ fs/cifs/smb2pdu.c | 5 -----
+ 2 files changed, 6 deletions(-)
+
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -933,7 +933,6 @@ struct cifs_tcon {
+ bool use_persistent:1; /* use persistent instead of durable handles */
+ #ifdef CONFIG_CIFS_SMB2
+ bool print:1; /* set if connection to printer share */
+- bool bad_network_name:1; /* set if ret status STATUS_BAD_NETWORK_NAME */
+ __le32 capabilities;
+ __u32 share_flags;
+ __u32 maximal_access;
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -1084,9 +1084,6 @@ SMB2_tcon(const unsigned int xid, struct
+ else
+ return -EIO;
+
+- if (tcon && tcon->bad_network_name)
+- return -ENOENT;
+-
+ if ((tcon && tcon->seal) &&
+ ((ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) == 0)) {
+ cifs_dbg(VFS, "encryption requested but no server support");
+@@ -1188,8 +1185,6 @@ tcon_exit:
+ tcon_error_exit:
+ if (rsp->hdr.Status == STATUS_BAD_NETWORK_NAME) {
+ cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree);
+- if (tcon)
+- tcon->bad_network_name = true;
+ }
+ goto tcon_exit;
+ }
--- /dev/null
+From 286f3f478796fb4f9e003e9f7d649f3c33f08d2f Mon Sep 17 00:00:00 2001
+From: Jason Gerecke <killertofu@gmail.com>
+Date: Thu, 13 Apr 2017 08:39:49 -0700
+Subject: HID: wacom: Treat HID_DG_TOOLSERIALNUMBER as unsigned
+
+From: Jason Gerecke <killertofu@gmail.com>
+
+commit 286f3f478796fb4f9e003e9f7d649f3c33f08d2f upstream.
+
+Because HID_DG_TOOLSERIALNUMBER doesn't first cast the value recieved from HID
+to an unsigned type, sign-extension rules can cause the value of
+wacom_wac->serial[0] to inadvertently wind up with all 32 of its highest bits
+set if the highest bit of "value" was set.
+
+This can cause problems for Tablet PC devices which use AES sensors and the
+xf86-input-wacom userspace driver. It is not uncommon for AES sensors to send a
+serial number of '0' while the pen is entering or leaving proximity. The
+xf86-input-wacom driver ignores events with a serial number of '0' since it
+cannot match them up to an in-use tool. To ensure the xf86-input-wacom driver
+does not ignore the final out-of-proximity event, the kernel does not send
+MSC_SERIAL events when the value of wacom_wac->serial[0] is '0'. If the highest
+bit of HID_DG_TOOLSERIALNUMBER is set by an in-prox pen which later leaves
+proximity and sends a '0' for HID_DG_TOOLSERIALNUMBER, then only the lowest 32
+bits of wacom_wac->serial[0] are actually cleared, causing the kernel to send
+an MSC_SERIAL event. Since the 'input_event' function takes an 'int' as
+argument, only those lowest (now-cleared) 32 bits of wacom_wac->serial[0] are
+sent to userspace, causing xf86-input-wacom to ignore the event. If the event
+was the final out-of-prox event, then xf86-input-wacom may remain in a state
+where it believes the pen is in proximity and refuses to allow other devices
+under its control (e.g. the touchscreen) to move the cursor.
+
+It should be noted that EMR devices and devices which use both the
+HID_DG_TOOLSERIALNUMBER and WACOM_HID_WD_SERIALHI usages (in that order) would
+be immune to this issue. It appears only AES devices are affected.
+
+Fixes: f85c9dc678a ("HID: wacom: generic: Support tool ID and additional tool types")
+Signed-off-by: Jason Gerecke <jason.gerecke@wacom.com>
+Acked-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/hid/wacom_wac.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -1798,7 +1798,7 @@ static void wacom_wac_pen_event(struct h
+ return;
+ case HID_DG_TOOLSERIALNUMBER:
+ wacom_wac->serial[0] = (wacom_wac->serial[0] & ~0xFFFFFFFFULL);
+- wacom_wac->serial[0] |= value;
++ wacom_wac->serial[0] |= (__u32)value;
+ return;
+ case WACOM_HID_WD_SENSE:
+ wacom_wac->hid_data.sense_state = value;
--- /dev/null
+From c1644fe041ebaf6519f6809146a77c3ead9193af Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Tue, 18 Apr 2017 15:31:08 +0100
+Subject: KEYS: Change the name of the dead type to ".dead" to prevent user access
+
+From: David Howells <dhowells@redhat.com>
+
+commit c1644fe041ebaf6519f6809146a77c3ead9193af upstream.
+
+This fixes CVE-2017-6951.
+
+Userspace should not be able to do things with the "dead" key type as it
+doesn't have some of the helper functions set upon it that the kernel
+needs. Attempting to use it may cause the kernel to crash.
+
+Fix this by changing the name of the type to ".dead" so that it's rejected
+up front on userspace syscalls by key_get_type_from_user().
+
+Though this doesn't seem to affect recent kernels, it does affect older
+ones, certainly those prior to:
+
+ commit c06cfb08b88dfbe13be44a69ae2fdc3a7c902d81
+ Author: David Howells <dhowells@redhat.com>
+ Date: Tue Sep 16 17:36:06 2014 +0100
+ KEYS: Remove key_type::match in favour of overriding default by match_preparse
+
+which went in before 3.18-rc1.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/gc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/security/keys/gc.c
++++ b/security/keys/gc.c
+@@ -46,7 +46,7 @@ static unsigned long key_gc_flags;
+ * immediately unlinked.
+ */
+ struct key_type key_type_dead = {
+- .name = "dead",
++ .name = ".dead",
+ };
+
+ /*
--- /dev/null
+From ee8f844e3c5a73b999edf733df1c529d6503ec2f Mon Sep 17 00:00:00 2001
+From: David Howells <dhowells@redhat.com>
+Date: Tue, 18 Apr 2017 15:31:07 +0100
+Subject: KEYS: Disallow keyrings beginning with '.' to be joined as session keyrings
+
+From: David Howells <dhowells@redhat.com>
+
+commit ee8f844e3c5a73b999edf733df1c529d6503ec2f upstream.
+
+This fixes CVE-2016-9604.
+
+Keyrings whose name begin with a '.' are special internal keyrings and so
+userspace isn't allowed to create keyrings by this name to prevent
+shadowing. However, the patch that added the guard didn't fix
+KEYCTL_JOIN_SESSION_KEYRING. Not only can that create dot-named keyrings,
+it can also subscribe to them as a session keyring if they grant SEARCH
+permission to the user.
+
+This, for example, allows a root process to set .builtin_trusted_keys as
+its session keyring, at which point it has full access because now the
+possessor permissions are added. This permits root to add extra public
+keys, thereby bypassing module verification.
+
+This also affects kexec and IMA.
+
+This can be tested by (as root):
+
+ keyctl session .builtin_trusted_keys
+ keyctl add user a a @s
+ keyctl list @s
+
+which on my test box gives me:
+
+ 2 keys in keyring:
+ 180010936: ---lswrv 0 0 asymmetric: Build time autogenerated kernel key: ae3d4a31b82daa8e1a75b49dc2bba949fd992a05
+ 801382539: --alswrv 0 0 user: a
+
+
+Fix this by rejecting names beginning with a '.' in the keyctl.
+
+Signed-off-by: David Howells <dhowells@redhat.com>
+Acked-by: Mimi Zohar <zohar@linux.vnet.ibm.com>
+cc: linux-ima-devel@lists.sourceforge.net
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/keyctl.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -271,7 +271,8 @@ error:
+ * Create and join an anonymous session keyring or join a named session
+ * keyring, creating it if necessary. A named session keyring must have Search
+ * permission for it to be joined. Session keyrings without this permit will
+- * be skipped over.
++ * be skipped over. It is not permitted for userspace to create or join
++ * keyrings whose name begin with a dot.
+ *
+ * If successful, the ID of the joined session keyring will be returned.
+ */
+@@ -288,12 +289,16 @@ long keyctl_join_session_keyring(const c
+ ret = PTR_ERR(name);
+ goto error;
+ }
++
++ ret = -EPERM;
++ if (name[0] == '.')
++ goto error_name;
+ }
+
+ /* join the session */
+ ret = join_session_keyring(name);
++error_name:
+ kfree(name);
+-
+ error:
+ return ret;
+ }
--- /dev/null
+From c9f838d104fed6f2f61d68164712e3204bf5271b Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Tue, 18 Apr 2017 15:31:09 +0100
+Subject: KEYS: fix keyctl_set_reqkey_keyring() to not leak thread keyrings
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit c9f838d104fed6f2f61d68164712e3204bf5271b upstream.
+
+This fixes CVE-2017-7472.
+
+Running the following program as an unprivileged user exhausts kernel
+memory by leaking thread keyrings:
+
+ #include <keyutils.h>
+
+ int main()
+ {
+ for (;;)
+ keyctl_set_reqkey_keyring(KEY_REQKEY_DEFL_THREAD_KEYRING);
+ }
+
+Fix it by only creating a new thread keyring if there wasn't one before.
+To make things more consistent, make install_thread_keyring_to_cred()
+and install_process_keyring_to_cred() both return 0 if the corresponding
+keyring is already present.
+
+Fixes: d84f4f992cbd ("CRED: Inaugurate COW credentials")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/keys/keyctl.c | 11 +++-------
+ security/keys/process_keys.c | 44 ++++++++++++++++++++++++++-----------------
+ 2 files changed, 31 insertions(+), 24 deletions(-)
+
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -1256,8 +1256,8 @@ error:
+ * Read or set the default keyring in which request_key() will cache keys and
+ * return the old setting.
+ *
+- * If a process keyring is specified then this will be created if it doesn't
+- * yet exist. The old setting will be returned if successful.
++ * If a thread or process keyring is specified then it will be created if it
++ * doesn't yet exist. The old setting will be returned if successful.
+ */
+ long keyctl_set_reqkey_keyring(int reqkey_defl)
+ {
+@@ -1282,11 +1282,8 @@ long keyctl_set_reqkey_keyring(int reqke
+
+ case KEY_REQKEY_DEFL_PROCESS_KEYRING:
+ ret = install_process_keyring_to_cred(new);
+- if (ret < 0) {
+- if (ret != -EEXIST)
+- goto error;
+- ret = 0;
+- }
++ if (ret < 0)
++ goto error;
+ goto set;
+
+ case KEY_REQKEY_DEFL_DEFAULT:
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -127,13 +127,18 @@ error:
+ }
+
+ /*
+- * Install a fresh thread keyring directly to new credentials. This keyring is
+- * allowed to overrun the quota.
++ * Install a thread keyring to the given credentials struct if it didn't have
++ * one already. This is allowed to overrun the quota.
++ *
++ * Return: 0 if a thread keyring is now present; -errno on failure.
+ */
+ int install_thread_keyring_to_cred(struct cred *new)
+ {
+ struct key *keyring;
+
++ if (new->thread_keyring)
++ return 0;
++
+ keyring = keyring_alloc("_tid", new->uid, new->gid, new,
+ KEY_POS_ALL | KEY_USR_VIEW,
+ KEY_ALLOC_QUOTA_OVERRUN,
+@@ -146,7 +151,9 @@ int install_thread_keyring_to_cred(struc
+ }
+
+ /*
+- * Install a fresh thread keyring, discarding the old one.
++ * Install a thread keyring to the current task if it didn't have one already.
++ *
++ * Return: 0 if a thread keyring is now present; -errno on failure.
+ */
+ static int install_thread_keyring(void)
+ {
+@@ -157,8 +164,6 @@ static int install_thread_keyring(void)
+ if (!new)
+ return -ENOMEM;
+
+- BUG_ON(new->thread_keyring);
+-
+ ret = install_thread_keyring_to_cred(new);
+ if (ret < 0) {
+ abort_creds(new);
+@@ -169,17 +174,17 @@ static int install_thread_keyring(void)
+ }
+
+ /*
+- * Install a process keyring directly to a credentials struct.
++ * Install a process keyring to the given credentials struct if it didn't have
++ * one already. This is allowed to overrun the quota.
+ *
+- * Returns -EEXIST if there was already a process keyring, 0 if one installed,
+- * and other value on any other error
++ * Return: 0 if a process keyring is now present; -errno on failure.
+ */
+ int install_process_keyring_to_cred(struct cred *new)
+ {
+ struct key *keyring;
+
+ if (new->process_keyring)
+- return -EEXIST;
++ return 0;
+
+ keyring = keyring_alloc("_pid", new->uid, new->gid, new,
+ KEY_POS_ALL | KEY_USR_VIEW,
+@@ -193,11 +198,9 @@ int install_process_keyring_to_cred(stru
+ }
+
+ /*
+- * Make sure a process keyring is installed for the current process. The
+- * existing process keyring is not replaced.
++ * Install a process keyring to the current task if it didn't have one already.
+ *
+- * Returns 0 if there is a process keyring by the end of this function, some
+- * error otherwise.
++ * Return: 0 if a process keyring is now present; -errno on failure.
+ */
+ static int install_process_keyring(void)
+ {
+@@ -211,14 +214,18 @@ static int install_process_keyring(void)
+ ret = install_process_keyring_to_cred(new);
+ if (ret < 0) {
+ abort_creds(new);
+- return ret != -EEXIST ? ret : 0;
++ return ret;
+ }
+
+ return commit_creds(new);
+ }
+
+ /*
+- * Install a session keyring directly to a credentials struct.
++ * Install the given keyring as the session keyring of the given credentials
++ * struct, replacing the existing one if any. If the given keyring is NULL,
++ * then install a new anonymous session keyring.
++ *
++ * Return: 0 on success; -errno on failure.
+ */
+ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
+ {
+@@ -253,8 +260,11 @@ int install_session_keyring_to_cred(stru
+ }
+
+ /*
+- * Install a session keyring, discarding the old one. If a keyring is not
+- * supplied, an empty one is invented.
++ * Install the given keyring as the session keyring of the current task,
++ * replacing the existing one if any. If the given keyring is NULL, then
++ * install a new anonymous session keyring.
++ *
++ * Return: 0 on success; -errno on failure.
+ */
+ static int install_session_keyring(struct key *keyring)
+ {
--- /dev/null
+From fc280fe871449ead4bdbd1665fa52c7c01c64765 Mon Sep 17 00:00:00 2001
+From: Rabin Vincent <rabinv@axis.com>
+Date: Thu, 20 Apr 2017 14:37:46 -0700
+Subject: mm: prevent NR_ISOLATE_* stats from going negative
+
+From: Rabin Vincent <rabinv@axis.com>
+
+commit fc280fe871449ead4bdbd1665fa52c7c01c64765 upstream.
+
+Commit 6afcf8ef0ca0 ("mm, compaction: fix NR_ISOLATED_* stats for pfn
+based migration") moved the dec_node_page_state() call (along with the
+page_is_file_cache() call) to after putback_lru_page().
+
+But page_is_file_cache() can change after putback_lru_page() is called,
+so it should be called before putback_lru_page(), as it was before that
+patch, to prevent NR_ISOLATE_* stats from going negative.
+
+Without this fix, non-CONFIG_SMP kernels end up hanging in the
+while(too_many_isolated()) { congestion_wait() } loop in
+shrink_active_list() due to the negative stats.
+
+ Mem-Info:
+ active_anon:32567 inactive_anon:121 isolated_anon:1
+ active_file:6066 inactive_file:6639 isolated_file:4294967295
+ ^^^^^^^^^^
+ unevictable:0 dirty:115 writeback:0 unstable:0
+ slab_reclaimable:2086 slab_unreclaimable:3167
+ mapped:3398 shmem:18366 pagetables:1145 bounce:0
+ free:1798 free_pcp:13 free_cma:0
+
+Fixes: 6afcf8ef0ca0 ("mm, compaction: fix NR_ISOLATED_* stats for pfn based migration")
+Link: http://lkml.kernel.org/r/1492683865-27549-1-git-send-email-rabin.vincent@axis.com
+Signed-off-by: Rabin Vincent <rabinv@axis.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Ming Ling <ming.ling@spreadtrum.com>
+Cc: Minchan Kim <minchan@kernel.org>
+Cc: Vlastimil Babka <vbabka@suse.cz>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/migrate.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -183,9 +183,9 @@ void putback_movable_pages(struct list_h
+ unlock_page(page);
+ put_page(page);
+ } else {
+- putback_lru_page(page);
+ dec_node_page_state(page, NR_ISOLATED_ANON +
+ page_is_file_cache(page));
++ putback_lru_page(page);
+ }
+ }
+ }
--- /dev/null
+From 78f7a45dac2a2d2002f98a3a95f7979867868d73 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Wed, 19 Apr 2017 14:29:46 -0400
+Subject: ring-buffer: Have ring_buffer_iter_empty() return true when empty
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit 78f7a45dac2a2d2002f98a3a95f7979867868d73 upstream.
+
+I noticed that reading the snapshot file when it is empty no longer gives a
+status. It suppose to show the status of the snapshot buffer as well as how
+to allocate and use it. For example:
+
+ ># cat snapshot
+ # tracer: nop
+ #
+ #
+ # * Snapshot is allocated *
+ #
+ # Snapshot commands:
+ # echo 0 > snapshot : Clears and frees snapshot buffer
+ # echo 1 > snapshot : Allocates snapshot buffer, if not already allocated.
+ # Takes a snapshot of the main buffer.
+ # echo 2 > snapshot : Clears snapshot buffer (but does not allocate or free)
+ # (Doesn't have to be '2' works with any number that
+ # is not a '0' or '1')
+
+But instead it just showed an empty buffer:
+
+ ># cat snapshot
+ # tracer: nop
+ #
+ # entries-in-buffer/entries-written: 0/0 #P:4
+ #
+ # _-----=> irqs-off
+ # / _----=> need-resched
+ # | / _---=> hardirq/softirq
+ # || / _--=> preempt-depth
+ # ||| / delay
+ # TASK-PID CPU# |||| TIMESTAMP FUNCTION
+ # | | | |||| | |
+
+What happened was that it was using the ring_buffer_iter_empty() function to
+see if it was empty, and if it was, it showed the status. But that function
+was returning false when it was empty. The reason was that the iter header
+page was on the reader page, and the reader page was empty, but so was the
+buffer itself. The check only tested to see if the iter was on the commit
+page, but the commit page was no longer pointing to the reader page, but as
+all pages were empty, the buffer is also.
+
+Fixes: 651e22f2701b ("ring-buffer: Always reset iterator to reader page")
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/ring_buffer.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -3404,11 +3404,23 @@ EXPORT_SYMBOL_GPL(ring_buffer_iter_reset
+ int ring_buffer_iter_empty(struct ring_buffer_iter *iter)
+ {
+ struct ring_buffer_per_cpu *cpu_buffer;
++ struct buffer_page *reader;
++ struct buffer_page *head_page;
++ struct buffer_page *commit_page;
++ unsigned commit;
+
+ cpu_buffer = iter->cpu_buffer;
+
+- return iter->head_page == cpu_buffer->commit_page &&
+- iter->head == rb_commit_index(cpu_buffer);
++ /* Remember, trace recording is off when iterator is in use */
++ reader = cpu_buffer->reader_page;
++ head_page = cpu_buffer->head_page;
++ commit_page = cpu_buffer->commit_page;
++ commit = rb_page_commit(commit_page);
++
++ return ((iter->head_page == commit_page && iter->head == commit) ||
++ (iter->head_page == reader && commit_page == head_page &&
++ head_page->read == commit &&
++ iter->head == rb_page_commit(cpu_buffer->reader_page)));
+ }
+ EXPORT_SYMBOL_GPL(ring_buffer_iter_empty);
+
--- /dev/null
+From df62db5be2e5f070ecd1a5ece5945b590ee112e0 Mon Sep 17 00:00:00 2001
+From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
+Date: Wed, 19 Apr 2017 12:07:08 -0400
+Subject: tracing: Allocate the snapshot buffer before enabling probe
+
+From: Steven Rostedt (VMware) <rostedt@goodmis.org>
+
+commit df62db5be2e5f070ecd1a5ece5945b590ee112e0 upstream.
+
+Currently the snapshot trigger enables the probe and then allocates the
+snapshot. If the probe triggers before the allocation, it could cause the
+snapshot to fail and turn tracing off. It's best to allocate the snapshot
+buffer first, and then enable the trigger. If something goes wrong in the
+enabling of the trigger, the snapshot buffer is still allocated, but it can
+also be freed by the user by writting zero into the snapshot buffer file.
+
+Also add a check of the return status of alloc_snapshot().
+
+Fixes: 77fd5c15e3 ("tracing: Add snapshot trigger to function probes")
+Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/trace.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/kernel/trace/trace.c
++++ b/kernel/trace/trace.c
+@@ -6740,11 +6740,13 @@ ftrace_trace_snapshot_callback(struct ft
+ return ret;
+
+ out_reg:
+- ret = register_ftrace_function_probe(glob, ops, count);
++ ret = alloc_snapshot(&global_trace);
++ if (ret < 0)
++ goto out;
+
+- if (ret >= 0)
+- alloc_snapshot(&global_trace);
++ ret = register_ftrace_function_probe(glob, ops, count);
+
++ out:
+ return ret < 0 ? ret : 0;
+ }
+