--- /dev/null
+From c0942f363b3af1f8cdc56ea2d3682647edceb514 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Nov 2019 14:48:11 -0800
+Subject: ASoC: pcm: update FE/BE trigger order based on the command
+
+From: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+
+[ Upstream commit acbf27746ecfa96b290b54cc7f05273482ea128a ]
+
+Currently, the trigger orders SND_SOC_DPCM_TRIGGER_PRE/POST
+determine the order in which FE DAI and BE DAI are triggered.
+In the case of SND_SOC_DPCM_TRIGGER_PRE, the FE DAI is
+triggered before the BE DAI and in the case of
+SND_SOC_DPCM_TRIGGER_POST, the BE DAI is triggered before
+the FE DAI. And this order remains the same irrespective of the
+trigger command.
+
+In the case of the SOF driver, during playback, the FW
+expects the BE DAI to be triggered before the FE DAI during
+the START trigger. The BE DAI trigger handles the starting of
+Link DMA and so it must be started before the FE DAI is started
+to prevent xruns during pause/release. This can be addressed
+by setting the trigger order for the FE dai link to
+SND_SOC_DPCM_TRIGGER_POST. But during the STOP trigger,
+the FW expects the FE DAI to be triggered before the BE DAI.
+Retaining the same order during the START and STOP commands,
+results in FW error as the DAI component in the FW is still
+active.
+
+The issue can be fixed by mirroring the trigger order of
+FE and BE DAI's during the START and STOP trigger. So, with the
+trigger order set to SND_SOC_DPCM_TRIGGER_PRE, the FE DAI will be
+trigger first during SNDRV_PCM_TRIGGER_START/STOP/RESUME
+and the BE DAI will be triggered first during the
+STOP/SUSPEND/PAUSE commands. Conversely, with the trigger order
+set to SND_SOC_DPCM_TRIGGER_POST, the BE DAI will be triggered
+first during the SNDRV_PCM_TRIGGER_START/STOP/RESUME commands
+and the FE DAI will be triggered first during the
+SNDRV_PCM_TRIGGER_STOP/SUSPEND/PAUSE commands.
+
+Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
+Link: https://lore.kernel.org/r/20191104224812.3393-2-ranjani.sridharan@linux.intel.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ sound/soc/soc-pcm.c | 95 ++++++++++++++++++++++++++++++++-------------
+ 1 file changed, 68 insertions(+), 27 deletions(-)
+
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 70e1a60a2e980..89f772ed47053 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -2123,42 +2123,81 @@ int dpcm_be_dai_trigger(struct snd_soc_pcm_runtime *fe, int stream,
+ }
+ EXPORT_SYMBOL_GPL(dpcm_be_dai_trigger);
+
++static int dpcm_dai_trigger_fe_be(struct snd_pcm_substream *substream,
++ int cmd, bool fe_first)
++{
++ struct snd_soc_pcm_runtime *fe = substream->private_data;
++ int ret;
++
++ /* call trigger on the frontend before the backend. */
++ if (fe_first) {
++ dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n",
++ fe->dai_link->name, cmd);
++
++ ret = soc_pcm_trigger(substream, cmd);
++ if (ret < 0)
++ return ret;
++
++ ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
++ return ret;
++ }
++
++ /* call trigger on the frontend after the backend. */
++ ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
++ if (ret < 0)
++ return ret;
++
++ dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",
++ fe->dai_link->name, cmd);
++
++ ret = soc_pcm_trigger(substream, cmd);
++
++ return ret;
++}
++
+ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
+ {
+ struct snd_soc_pcm_runtime *fe = substream->private_data;
+- int stream = substream->stream, ret;
++ int stream = substream->stream;
++ int ret = 0;
+ enum snd_soc_dpcm_trigger trigger = fe->dai_link->trigger[stream];
+
+ fe->dpcm[stream].runtime_update = SND_SOC_DPCM_UPDATE_FE;
+
+ switch (trigger) {
+ case SND_SOC_DPCM_TRIGGER_PRE:
+- /* call trigger on the frontend before the backend. */
+-
+- dev_dbg(fe->dev, "ASoC: pre trigger FE %s cmd %d\n",
+- fe->dai_link->name, cmd);
+-
+- ret = soc_pcm_trigger(substream, cmd);
+- if (ret < 0) {
+- dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
+- goto out;
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ ret = dpcm_dai_trigger_fe_be(substream, cmd, true);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ ret = dpcm_dai_trigger_fe_be(substream, cmd, false);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
+ }
+-
+- ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
+ break;
+ case SND_SOC_DPCM_TRIGGER_POST:
+- /* call trigger on the frontend after the backend. */
+-
+- ret = dpcm_be_dai_trigger(fe, substream->stream, cmd);
+- if (ret < 0) {
+- dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
+- goto out;
++ switch (cmd) {
++ case SNDRV_PCM_TRIGGER_START:
++ case SNDRV_PCM_TRIGGER_RESUME:
++ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
++ ret = dpcm_dai_trigger_fe_be(substream, cmd, false);
++ break;
++ case SNDRV_PCM_TRIGGER_STOP:
++ case SNDRV_PCM_TRIGGER_SUSPEND:
++ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
++ ret = dpcm_dai_trigger_fe_be(substream, cmd, true);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
+ }
+-
+- dev_dbg(fe->dev, "ASoC: post trigger FE %s cmd %d\n",
+- fe->dai_link->name, cmd);
+-
+- ret = soc_pcm_trigger(substream, cmd);
+ break;
+ case SND_SOC_DPCM_TRIGGER_BESPOKE:
+ /* bespoke trigger() - handles both FE and BEs */
+@@ -2167,10 +2206,6 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
+ fe->dai_link->name, cmd);
+
+ ret = soc_pcm_bespoke_trigger(substream, cmd);
+- if (ret < 0) {
+- dev_err(fe->dev,"ASoC: trigger FE failed %d\n", ret);
+- goto out;
+- }
+ break;
+ default:
+ dev_err(fe->dev, "ASoC: invalid trigger cmd %d for %s\n", cmd,
+@@ -2179,6 +2214,12 @@ static int dpcm_fe_dai_do_trigger(struct snd_pcm_substream *substream, int cmd)
+ goto out;
+ }
+
++ if (ret < 0) {
++ dev_err(fe->dev, "ASoC: trigger FE cmd: %d failed: %d\n",
++ cmd, ret);
++ goto out;
++ }
++
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+--
+2.20.1
+
--- /dev/null
+From d7c1e55fdece37f1454987722615dbc0c3c713ca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2020 03:08:18 +0000
+Subject: hv_sock: Remove the accept port restriction
+
+From: Sunil Muthuswamy <sunilmut@microsoft.com>
+
+[ Upstream commit c742c59e1fbd022b64d91aa9a0092b3a699d653c ]
+
+Currently, hv_sock restricts the port the guest socket can accept
+connections on. hv_sock divides the socket port namespace into two parts
+for server side (listening socket), 0-0x7FFFFFFF & 0x80000000-0xFFFFFFFF
+(there are no restrictions on client port namespace). The first part
+(0-0x7FFFFFFF) is reserved for sockets where connections can be accepted.
+The second part (0x80000000-0xFFFFFFFF) is reserved for allocating ports
+for the peer (host) socket, once a connection is accepted.
+This reservation of the port namespace is specific to hv_sock and not
+known by the generic vsock library (ex: af_vsock). This is problematic
+because auto-binds/ephemeral ports are handled by the generic vsock
+library and it has no knowledge of this port reservation and could
+allocate a port that is not compatible with hv_sock (and legitimately so).
+The issue hasn't surfaced so far because the auto-bind code of vsock
+(__vsock_bind_stream) prior to the change 'VSOCK: bind to random port for
+VMADDR_PORT_ANY' would start walking up from LAST_RESERVED_PORT (1023) and
+start assigning ports. That will take a large number of iterations to hit
+0x7FFFFFFF. But, after the above change to randomize port selection, the
+issue has started coming up more frequently.
+There has really been no good reason to have this port reservation logic
+in hv_sock from the get go. Reserving a local port for peer ports is not
+how things are handled generally. Peer ports should reflect the peer port.
+This fixes the issue by lifting the port reservation, and also returns the
+right peer port. Since the code converts the GUID to the peer port (by
+using the first 4 bytes), there is a possibility of conflicts, but that
+seems like a reasonable risk to take, given this is limited to vsock and
+that only applies to all local sockets.
+
+Signed-off-by: Sunil Muthuswamy <sunilmut@microsoft.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/vmw_vsock/hyperv_transport.c | 68 +++++---------------------------
+ 1 file changed, 9 insertions(+), 59 deletions(-)
+
+diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c
+index 6614512f81800..736b76ec8cf01 100644
+--- a/net/vmw_vsock/hyperv_transport.c
++++ b/net/vmw_vsock/hyperv_transport.c
+@@ -144,28 +144,15 @@ struct hvsock {
+ ****************************************************************************
+ * The only valid Service GUIDs, from the perspectives of both the host and *
+ * Linux VM, that can be connected by the other end, must conform to this *
+- * format: <port>-facb-11e6-bd58-64006a7986d3, and the "port" must be in *
+- * this range [0, 0x7FFFFFFF]. *
++ * format: <port>-facb-11e6-bd58-64006a7986d3. *
+ ****************************************************************************
+ *
+ * When we write apps on the host to connect(), the GUID ServiceID is used.
+ * When we write apps in Linux VM to connect(), we only need to specify the
+ * port and the driver will form the GUID and use that to request the host.
+ *
+- * From the perspective of Linux VM:
+- * 1. the local ephemeral port (i.e. the local auto-bound port when we call
+- * connect() without explicit bind()) is generated by __vsock_bind_stream(),
+- * and the range is [1024, 0xFFFFFFFF).
+- * 2. the remote ephemeral port (i.e. the auto-generated remote port for
+- * a connect request initiated by the host's connect()) is generated by
+- * hvs_remote_addr_init() and the range is [0x80000000, 0xFFFFFFFF).
+ */
+
+-#define MAX_LISTEN_PORT ((u32)0x7FFFFFFF)
+-#define MAX_VM_LISTEN_PORT MAX_LISTEN_PORT
+-#define MAX_HOST_LISTEN_PORT MAX_LISTEN_PORT
+-#define MIN_HOST_EPHEMERAL_PORT (MAX_HOST_LISTEN_PORT + 1)
+-
+ /* 00000000-facb-11e6-bd58-64006a7986d3 */
+ static const uuid_le srv_id_template =
+ UUID_LE(0x00000000, 0xfacb, 0x11e6, 0xbd, 0x58,
+@@ -188,33 +175,6 @@ static void hvs_addr_init(struct sockaddr_vm *addr, const uuid_le *svr_id)
+ vsock_addr_init(addr, VMADDR_CID_ANY, port);
+ }
+
+-static void hvs_remote_addr_init(struct sockaddr_vm *remote,
+- struct sockaddr_vm *local)
+-{
+- static u32 host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT;
+- struct sock *sk;
+-
+- vsock_addr_init(remote, VMADDR_CID_ANY, VMADDR_PORT_ANY);
+-
+- while (1) {
+- /* Wrap around ? */
+- if (host_ephemeral_port < MIN_HOST_EPHEMERAL_PORT ||
+- host_ephemeral_port == VMADDR_PORT_ANY)
+- host_ephemeral_port = MIN_HOST_EPHEMERAL_PORT;
+-
+- remote->svm_port = host_ephemeral_port++;
+-
+- sk = vsock_find_connected_socket(remote, local);
+- if (!sk) {
+- /* Found an available ephemeral port */
+- return;
+- }
+-
+- /* Release refcnt got in vsock_find_connected_socket */
+- sock_put(sk);
+- }
+-}
+-
+ static void hvs_set_channel_pending_send_size(struct vmbus_channel *chan)
+ {
+ set_channel_pending_send_size(chan,
+@@ -342,12 +302,7 @@ static void hvs_open_connection(struct vmbus_channel *chan)
+ if_type = &chan->offermsg.offer.if_type;
+ if_instance = &chan->offermsg.offer.if_instance;
+ conn_from_host = chan->offermsg.offer.u.pipe.user_def[0];
+-
+- /* The host or the VM should only listen on a port in
+- * [0, MAX_LISTEN_PORT]
+- */
+- if (!is_valid_srv_id(if_type) ||
+- get_port_by_srv_id(if_type) > MAX_LISTEN_PORT)
++ if (!is_valid_srv_id(if_type))
+ return;
+
+ hvs_addr_init(&addr, conn_from_host ? if_type : if_instance);
+@@ -372,6 +327,13 @@ static void hvs_open_connection(struct vmbus_channel *chan)
+
+ new->sk_state = TCP_SYN_SENT;
+ vnew = vsock_sk(new);
++
++ hvs_addr_init(&vnew->local_addr, if_type);
++
++ /* Remote peer is always the host */
++ vsock_addr_init(&vnew->remote_addr,
++ VMADDR_CID_HOST, VMADDR_PORT_ANY);
++ vnew->remote_addr.svm_port = get_port_by_srv_id(if_instance);
+ hvs_new = vnew->trans;
+ hvs_new->chan = chan;
+ } else {
+@@ -411,8 +373,6 @@ static void hvs_open_connection(struct vmbus_channel *chan)
+ sk->sk_ack_backlog++;
+
+ hvs_addr_init(&vnew->local_addr, if_type);
+- hvs_remote_addr_init(&vnew->remote_addr, &vnew->local_addr);
+-
+ hvs_new->vm_srv_id = *if_type;
+ hvs_new->host_srv_id = *if_instance;
+
+@@ -717,16 +677,6 @@ static bool hvs_stream_is_active(struct vsock_sock *vsk)
+
+ static bool hvs_stream_allow(u32 cid, u32 port)
+ {
+- /* The host's port range [MIN_HOST_EPHEMERAL_PORT, 0xFFFFFFFF) is
+- * reserved as ephemeral ports, which are used as the host's ports
+- * when the host initiates connections.
+- *
+- * Perform this check in the guest so an immediate error is produced
+- * instead of a timeout.
+- */
+- if (port > MAX_HOST_LISTEN_PORT)
+- return false;
+-
+ if (cid == VMADDR_CID_HOST)
+ return true;
+
+--
+2.20.1
+
clocksource-prevent-double-add_timer_on-for-watchdog_timer.patch
perf-core-fix-mlock-accounting-in-perf_mmap.patch
rxrpc-fix-service-call-disconnection.patch
+asoc-pcm-update-fe-be-trigger-order-based-on-the-com.patch
+hv_sock-remove-the-accept-port-restriction.patch