--- /dev/null
+From 7e1d90f60a0d501c8503e636942ca704a454d910 Mon Sep 17 00:00:00 2001
+From: Daniel Mentz <danielmentz@google.com>
+Date: Mon, 14 Aug 2017 14:46:01 -0700
+Subject: ALSA: seq: 2nd attempt at fixing race creating a queue
+
+From: Daniel Mentz <danielmentz@google.com>
+
+commit 7e1d90f60a0d501c8503e636942ca704a454d910 upstream.
+
+commit 4842e98f26dd80be3623c4714a244ba52ea096a8 ("ALSA: seq: Fix race at
+creating a queue") attempted to fix a race reported by syzkaller. That
+fix has been described as follows:
+
+"
+When a sequencer queue is created in snd_seq_queue_alloc(),it adds the
+new queue element to the public list before referencing it. Thus the
+queue might be deleted before the call of snd_seq_queue_use(), and it
+results in the use-after-free error, as spotted by syzkaller.
+
+The fix is to reference the queue object at the right time.
+"
+
+Even with that fix in place, syzkaller reported a use-after-free error.
+It specifically pointed to the last instruction "return q->queue" in
+snd_seq_queue_alloc(). The pointer q is being used after kfree() has
+been called on it.
+
+It turned out that there is still a small window where a race can
+happen. The window opens at
+snd_seq_ioctl_create_queue()->snd_seq_queue_alloc()->queue_list_add()
+and closes at
+snd_seq_ioctl_create_queue()->queueptr()->snd_use_lock_use(). Between
+these two calls, a different thread could delete the queue and possibly
+re-create a different queue in the same location in queue_list.
+
+This change prevents this situation by calling snd_use_lock_use() from
+snd_seq_queue_alloc() prior to calling queue_list_add(). It is then the
+caller's responsibility to call snd_use_lock_free(&q->use_lock).
+
+Fixes: 4842e98f26dd ("ALSA: seq: Fix race at creating a queue")
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Daniel Mentz <danielmentz@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/core/seq/seq_clientmgr.c | 13 ++++---------
+ sound/core/seq/seq_queue.c | 14 +++++++++-----
+ sound/core/seq/seq_queue.h | 2 +-
+ 3 files changed, 14 insertions(+), 15 deletions(-)
+
+--- a/sound/core/seq/seq_clientmgr.c
++++ b/sound/core/seq/seq_clientmgr.c
+@@ -1502,16 +1502,11 @@ static int snd_seq_ioctl_unsubscribe_por
+ static int snd_seq_ioctl_create_queue(struct snd_seq_client *client, void *arg)
+ {
+ struct snd_seq_queue_info *info = arg;
+- int result;
+ struct snd_seq_queue *q;
+
+- result = snd_seq_queue_alloc(client->number, info->locked, info->flags);
+- if (result < 0)
+- return result;
+-
+- q = queueptr(result);
+- if (q == NULL)
+- return -EINVAL;
++ q = snd_seq_queue_alloc(client->number, info->locked, info->flags);
++ if (IS_ERR(q))
++ return PTR_ERR(q);
+
+ info->queue = q->queue;
+ info->locked = q->locked;
+@@ -1521,7 +1516,7 @@ static int snd_seq_ioctl_create_queue(st
+ if (!info->name[0])
+ snprintf(info->name, sizeof(info->name), "Queue-%d", q->queue);
+ strlcpy(q->name, info->name, sizeof(q->name));
+- queuefree(q);
++ snd_use_lock_free(&q->use_lock);
+
+ return 0;
+ }
+--- a/sound/core/seq/seq_queue.c
++++ b/sound/core/seq/seq_queue.c
+@@ -184,22 +184,26 @@ void __exit snd_seq_queues_delete(void)
+ static void queue_use(struct snd_seq_queue *queue, int client, int use);
+
+ /* allocate a new queue -
+- * return queue index value or negative value for error
++ * return pointer to new queue or ERR_PTR(-errno) for error
++ * The new queue's use_lock is set to 1. It is the caller's responsibility to
++ * call snd_use_lock_free(&q->use_lock).
+ */
+-int snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
++struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int info_flags)
+ {
+ struct snd_seq_queue *q;
+
+ q = queue_new(client, locked);
+ if (q == NULL)
+- return -ENOMEM;
++ return ERR_PTR(-ENOMEM);
+ q->info_flags = info_flags;
+ queue_use(q, client, 1);
++ snd_use_lock_use(&q->use_lock);
+ if (queue_list_add(q) < 0) {
++ snd_use_lock_free(&q->use_lock);
+ queue_delete(q);
+- return -ENOMEM;
++ return ERR_PTR(-ENOMEM);
+ }
+- return q->queue;
++ return q;
+ }
+
+ /* delete a queue - queue must be owned by the client */
+--- a/sound/core/seq/seq_queue.h
++++ b/sound/core/seq/seq_queue.h
+@@ -71,7 +71,7 @@ void snd_seq_queues_delete(void);
+
+
+ /* create new queue (constructor) */
+-int snd_seq_queue_alloc(int client, int locked, unsigned int flags);
++struct snd_seq_queue *snd_seq_queue_alloc(int client, int locked, unsigned int flags);
+
+ /* delete queue (destructor) */
+ int snd_seq_queue_delete(int client, int queueid);
--- /dev/null
+From 0f174b3525a43bd51f9397394763925e0ebe7bc7 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 16 Aug 2017 14:18:37 +0200
+Subject: ALSA: usb-audio: Add mute TLV for playback volumes on C-Media devices
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 0f174b3525a43bd51f9397394763925e0ebe7bc7 upstream.
+
+C-Media devices (at least some models) mute the playback stream when
+volumes are set to the minimum value. But this isn't informed via TLV
+and the user-space, typically PulseAudio, gets confused as if it's
+still played in a low volume.
+
+This patch adds the new flag, min_mute, to struct usb_mixer_elem_info
+for indicating that the mixer element is with the minimum-mute volume.
+This flag is set for known C-Media devices in
+snd_usb_mixer_fu_apply_quirk() in turn.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=196669
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/mixer.c | 2 ++
+ sound/usb/mixer.h | 1 +
+ sound/usb/mixer_quirks.c | 6 ++++++
+ 3 files changed, 9 insertions(+)
+
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -542,6 +542,8 @@ int snd_usb_mixer_vol_tlv(struct snd_kco
+
+ if (size < sizeof(scale))
+ return -ENOMEM;
++ if (cval->min_mute)
++ scale[0] = SNDRV_CTL_TLVT_DB_MINMAX_MUTE;
+ scale[2] = cval->dBmin;
+ scale[3] = cval->dBmax;
+ if (copy_to_user(_tlv, scale, sizeof(scale)))
+--- a/sound/usb/mixer.h
++++ b/sound/usb/mixer.h
+@@ -64,6 +64,7 @@ struct usb_mixer_elem_info {
+ int cached;
+ int cache_val[MAX_CHANNELS];
+ u8 initialized;
++ u8 min_mute;
+ void *private_data;
+ };
+
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -1873,6 +1873,12 @@ void snd_usb_mixer_fu_apply_quirk(struct
+ if (unitid == 7 && cval->control == UAC_FU_VOLUME)
+ snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
+ break;
++ /* lowest playback value is muted on C-Media devices */
++ case USB_ID(0x0d8c, 0x000c):
++ case USB_ID(0x0d8c, 0x0014):
++ if (strstr(kctl->id.name, "Playback"))
++ cval->min_mute = 1;
++ break;
+ }
+ }
+
--- /dev/null
+From a8e800fe0f68bc28ce309914f47e432742b865ed Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 14 Aug 2017 14:35:50 +0200
+Subject: ALSA: usb-audio: Apply sample rate quirk to Sennheiser headset
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit a8e800fe0f68bc28ce309914f47e432742b865ed upstream.
+
+A Senheisser headset requires the typical sample-rate quirk for
+avoiding spurious errors from inquiring the current sample rate like:
+ usb 1-1: 2:1: cannot get freq at ep 0x4
+ usb 1-1: 3:1: cannot get freq at ep 0x83
+
+The USB ID 1395:740a has to be added to the entries in
+snd_usb_get_sample_rate_quirk().
+
+Bugzilla: https://bugzilla.suse.com/show_bug.cgi?id=1052580
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/usb/quirks.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/sound/usb/quirks.c
++++ b/sound/usb/quirks.c
+@@ -1142,6 +1142,7 @@ bool snd_usb_get_sample_rate_quirk(struc
+ case USB_ID(0x0556, 0x0014): /* Phoenix Audio TMX320VC */
+ case USB_ID(0x05A3, 0x9420): /* ELP HD USB Camera */
+ case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
++ case USB_ID(0x1395, 0x740a): /* Sennheiser DECT */
+ case USB_ID(0x1901, 0x0191): /* GE B850V3 CP2114 audio interface */
+ case USB_ID(0x1de7, 0x0013): /* Phoenix Audio MT202exe */
+ case USB_ID(0x1de7, 0x0014): /* Phoenix Audio TMX320 */
--- /dev/null
+From 3010f876500f9ba921afaeccec30c45ca6584dc8 Mon Sep 17 00:00:00 2001
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+Date: Fri, 18 Aug 2017 15:16:05 -0700
+Subject: mm: discard memblock data later
+
+From: Pavel Tatashin <pasha.tatashin@oracle.com>
+
+commit 3010f876500f9ba921afaeccec30c45ca6584dc8 upstream.
+
+There is existing use after free bug when deferred struct pages are
+enabled:
+
+The memblock_add() allocates memory for the memory array if more than
+128 entries are needed. See comment in e820__memblock_setup():
+
+ * The bootstrap memblock region count maximum is 128 entries
+ * (INIT_MEMBLOCK_REGIONS), but EFI might pass us more E820 entries
+ * than that - so allow memblock resizing.
+
+This memblock memory is freed here:
+ free_low_memory_core_early()
+
+We access the freed memblock.memory later in boot when deferred pages
+are initialized in this path:
+
+ deferred_init_memmap()
+ for_each_mem_pfn_range()
+ __next_mem_pfn_range()
+ type = &memblock.memory;
+
+One possible explanation for why this use-after-free hasn't been hit
+before is that the limit of INIT_MEMBLOCK_REGIONS has never been
+exceeded at least on systems where deferred struct pages were enabled.
+
+Tested by reducing INIT_MEMBLOCK_REGIONS down to 4 from the current 128,
+and verifying in qemu that this code is getting excuted and that the
+freed pages are sane.
+
+Link: http://lkml.kernel.org/r/1502485554-318703-2-git-send-email-pasha.tatashin@oracle.com
+Fixes: 7e18adb4f80b ("mm: meminit: initialise remaining struct pages in parallel with kswapd")
+Signed-off-by: Pavel Tatashin <pasha.tatashin@oracle.com>
+Reviewed-by: Steven Sistare <steven.sistare@oracle.com>
+Reviewed-by: Daniel Jordan <daniel.m.jordan@oracle.com>
+Reviewed-by: Bob Picco <bob.picco@oracle.com>
+Acked-by: Michal Hocko <mhocko@suse.com>
+Cc: Mel Gorman <mgorman@techsingularity.net>
+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>
+
+---
+ include/linux/memblock.h | 6 ++++--
+ mm/memblock.c | 40 ++++++++++++++++++----------------------
+ mm/nobootmem.c | 16 ----------------
+ mm/page_alloc.c | 4 ++++
+ 4 files changed, 26 insertions(+), 40 deletions(-)
+
+--- a/include/linux/memblock.h
++++ b/include/linux/memblock.h
+@@ -64,6 +64,7 @@ extern bool movable_node_enabled;
+ #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
+ #define __init_memblock __meminit
+ #define __initdata_memblock __meminitdata
++void memblock_discard(void);
+ #else
+ #define __init_memblock
+ #define __initdata_memblock
+@@ -77,8 +78,6 @@ phys_addr_t memblock_find_in_range_node(
+ int nid, ulong flags);
+ phys_addr_t memblock_find_in_range(phys_addr_t start, phys_addr_t end,
+ phys_addr_t size, phys_addr_t align);
+-phys_addr_t get_allocated_memblock_reserved_regions_info(phys_addr_t *addr);
+-phys_addr_t get_allocated_memblock_memory_regions_info(phys_addr_t *addr);
+ void memblock_allow_resize(void);
+ int memblock_add_node(phys_addr_t base, phys_addr_t size, int nid);
+ int memblock_add(phys_addr_t base, phys_addr_t size);
+@@ -112,6 +111,9 @@ void __next_mem_range_rev(u64 *idx, int
+ void __next_reserved_mem_region(u64 *idx, phys_addr_t *out_start,
+ phys_addr_t *out_end);
+
++void __memblock_free_early(phys_addr_t base, phys_addr_t size);
++void __memblock_free_late(phys_addr_t base, phys_addr_t size);
++
+ /**
+ * for_each_mem_range - iterate through memblock areas from type_a and not
+ * included in type_b. Or just type_a if type_b is NULL.
+--- a/mm/memblock.c
++++ b/mm/memblock.c
+@@ -297,31 +297,27 @@ static void __init_memblock memblock_rem
+ }
+
+ #ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
+-
+-phys_addr_t __init_memblock get_allocated_memblock_reserved_regions_info(
+- phys_addr_t *addr)
+-{
+- if (memblock.reserved.regions == memblock_reserved_init_regions)
+- return 0;
+-
+- *addr = __pa(memblock.reserved.regions);
+-
+- return PAGE_ALIGN(sizeof(struct memblock_region) *
+- memblock.reserved.max);
+-}
+-
+-phys_addr_t __init_memblock get_allocated_memblock_memory_regions_info(
+- phys_addr_t *addr)
++/**
++ * Discard memory and reserved arrays if they were allocated
++ */
++void __init memblock_discard(void)
+ {
+- if (memblock.memory.regions == memblock_memory_init_regions)
+- return 0;
++ phys_addr_t addr, size;
+
+- *addr = __pa(memblock.memory.regions);
+-
+- return PAGE_ALIGN(sizeof(struct memblock_region) *
+- memblock.memory.max);
++ if (memblock.reserved.regions != memblock_reserved_init_regions) {
++ addr = __pa(memblock.reserved.regions);
++ size = PAGE_ALIGN(sizeof(struct memblock_region) *
++ memblock.reserved.max);
++ __memblock_free_late(addr, size);
++ }
++
++ if (memblock.memory.regions == memblock_memory_init_regions) {
++ addr = __pa(memblock.memory.regions);
++ size = PAGE_ALIGN(sizeof(struct memblock_region) *
++ memblock.memory.max);
++ __memblock_free_late(addr, size);
++ }
+ }
+-
+ #endif
+
+ /**
+--- a/mm/nobootmem.c
++++ b/mm/nobootmem.c
+@@ -146,22 +146,6 @@ static unsigned long __init free_low_mem
+ NULL)
+ count += __free_memory_core(start, end);
+
+-#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
+- {
+- phys_addr_t size;
+-
+- /* Free memblock.reserved array if it was allocated */
+- size = get_allocated_memblock_reserved_regions_info(&start);
+- if (size)
+- count += __free_memory_core(start, start + size);
+-
+- /* Free memblock.memory array if it was allocated */
+- size = get_allocated_memblock_memory_regions_info(&start);
+- if (size)
+- count += __free_memory_core(start, start + size);
+- }
+-#endif
+-
+ return count;
+ }
+
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1587,6 +1587,10 @@ void __init page_alloc_init_late(void)
+ /* Reinit limits that are based on free pages after the kernel is up */
+ files_maxfiles_init();
+ #endif
++#ifdef CONFIG_ARCH_DISCARD_MEMBLOCK
++ /* Discard memblock private memory */
++ memblock_discard();
++#endif
+
+ for_each_populated_zone(zone)
+ set_zone_contiguous(zone);
crypto-x86-sha1-fix-reads-beyond-the-number-of-blocks-passed.patch
input-elan_i2c-add-elan0608-to-the-acpi-table.patch
input-elan_i2c-add-antoher-lenovo-acpi-id-for-upcoming-lenovo-nb.patch
+alsa-seq-2nd-attempt-at-fixing-race-creating-a-queue.patch
+alsa-usb-audio-apply-sample-rate-quirk-to-sennheiser-headset.patch
+alsa-usb-audio-add-mute-tlv-for-playback-volumes-on-c-media-devices.patch
+mm-discard-memblock-data-later.patch