[PATCH v4 15/24] ASoC: qdsp6: q6core: Add q6core driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to core apr service, which is used to query
status of other static and dynamic services on the dsp.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig|   4 +
 sound/soc/qcom/qdsp6/Makefile |   1 +
 sound/soc/qcom/qdsp6/q6core.c | 381 ++
 sound/soc/qcom/qdsp6/q6core.h |  15 ++
 4 files changed, 401 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/q6core.c
 create mode 100644 sound/soc/qcom/qdsp6/q6core.h

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index a07181290624..488ee93ee084 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -56,6 +56,9 @@ config SND_SOC_QDSP6_ADM
 config SND_SOC_QDSP6_ASM
tristate
 
+config SND_SOC_QDSP6_CORE
+   tristate
+
 config SND_SOC_QDSP6
tristate "SoC ALSA audio driver for QDSP6"
depends on QCOM_APR && HAS_DMA
@@ -63,6 +66,7 @@ config SND_SOC_QDSP6
select SND_SOC_QDSP6_AFE
select SND_SOC_QDSP6_ADM
select SND_SOC_QDSP6_ASM
+   select SND_SOC_QDSP6_CORE
help
 To add support for MSM QDSP6 Soc Audio.
 This will enable sound soc platform specific
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index eea962315ab3..61f089bc0d25 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
 obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o
 obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
 obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
+obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
diff --git a/sound/soc/qcom/qdsp6/q6core.c b/sound/soc/qcom/qdsp6/q6core.c
new file mode 100644
index ..0d9cef4b7544
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6core.c
@@ -0,0 +1,381 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2017, The Linux Foundation
+// Copyright (c) 2018, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "q6core.h"
+#include "q6dsp-errno.h"
+
+#define ADSP_STATE_READY_TIMEOUT_MS3000
+#define Q6_READY_TIMEOUT_MS 100
+#define AVCS_CMD_ADSP_EVENT_GET_STATE  0x0001290C
+#define AVCS_CMDRSP_ADSP_EVENT_GET_STATE   0x0001290D
+#define AVCS_GET_VERSIONS   0x00012905
+#define AVCS_GET_VERSIONS_RSP   0x00012906
+#define AVCS_CMD_GET_FWK_VERSION   0x001292c
+#define AVCS_CMDRSP_GET_FWK_VERSION0x001292d
+
+struct avcs_svc_info {
+   uint32_t service_id;
+   uint32_t version;
+} __packed;
+
+struct avcs_cmdrsp_get_version {
+   uint32_t build_id;
+   uint32_t num_services;
+   struct avcs_svc_info svc_api_info[];
+} __packed;
+
+/* for ADSP2.8 and above */
+struct avcs_svc_api_info {
+   uint32_t service_id;
+   uint32_t api_version;
+   uint32_t api_branch_version;
+} __packed;
+
+struct avcs_cmdrsp_get_fwk_version {
+   uint32_t build_major_version;
+   uint32_t build_minor_version;
+   uint32_t build_branch_version;
+   uint32_t build_subbranch_version;
+   uint32_t num_services;
+   struct avcs_svc_api_info svc_api_info[];
+} __packed;
+
+struct q6core {
+   struct apr_device *adev;
+   wait_queue_head_t wait;
+   uint32_t avcs_state;
+   struct mutex lock;
+   bool resp_received;
+   uint32_t num_services;
+   struct avcs_cmdrsp_get_fwk_version *fwk_version;
+   struct avcs_cmdrsp_get_version *svc_version;
+   bool fwk_version_supported;
+   bool get_state_supported;
+   bool get_version_supported;
+   bool is_version_requested;
+};
+
+struct q6core *g_core;
+
+static int q6core_callback(struct apr_device *adev,
+struct apr_client_message *data)
+{
+   struct q6core *core = dev_get_drvdata(>dev);
+   struct aprv2_ibasic_rsp_result_t *result;
+
+   result = data->payload;
+   switch (data->opcode) {
+   case APR_BASIC_RSP_RESULT:{
+   result = data->payload;
+   switch (result->opcode) {
+   case AVCS_GET_VERSIONS:
+   if (result->status == ADSP_EUNSUPPORTED)
+   core->get_version_supported = false;
+   core->resp_received = true;
+   break;
+   case AVCS_CMD_GET_FWK_VERSION:
+   if (result->status == ADSP_EUNSUPPORTED)
+   core->fwk_version_supported = false;
+   core->resp_received = true;
+   break;
+   case AVCS_CMD_ADSP_EVENT_GET_STATE:
+   if (result->status == ADSP_EUNSUPPORTED)
+   core->get_state_supported = false;
+   core->resp_received = true;
+   break;
+   }
+   break;
+   }
+   case AVCS_CMDRSP_GET_FWK_VERSION: {
+ 

[PATCH v4 13/24] ASoC: qdsp6: q6asm: Add support to memory map and unmap

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to memory map and unmap regions commands in
q6asm module.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/qdsp6/q6asm.c | 338 +++
 sound/soc/qcom/qdsp6/q6asm.h |   5 +
 2 files changed, 343 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 4ed64d32c6b0..8a2ca2ff9ce8 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -17,10 +17,47 @@
 #include "q6dsp-errno.h"
 #include "q6dsp-common.h"
 
+#define ASM_CMD_SHARED_MEM_MAP_REGIONS 0x00010D92
+#define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS  0x00010D93
+#define ASM_CMD_SHARED_MEM_UNMAP_REGIONS   0x00010D94
+
 #define ASM_SYNC_IO_MODE   0x0001
 #define ASM_ASYNC_IO_MODE  0x0002
 #define ASM_TUN_READ_IO_MODE   0x0004  /* tunnel read write mode */
 #define ASM_TUN_WRITE_IO_MODE  0x0008  /* tunnel read write mode */
+#define ASM_SHIFT_GAPLESS_MODE_FLAG31
+#define ADSP_MEMORY_MAP_SHMEM8_4K_POOL 3
+
+struct avs_cmd_shared_mem_map_regions {
+   struct apr_hdr hdr;
+   u16 mem_pool_id;
+   u16 num_regions;
+   u32 property_flag;
+} __packed;
+
+struct avs_shared_map_region_payload {
+   u32 shm_addr_lsw;
+   u32 shm_addr_msw;
+   u32 mem_size_bytes;
+} __packed;
+
+struct avs_cmd_shared_mem_unmap_regions {
+   struct apr_hdr hdr;
+   u32 mem_map_handle;
+} __packed;
+
+struct audio_buffer {
+   phys_addr_t phys;
+   uint32_t used;
+   uint32_t size;  /* size of buffer */
+};
+
+struct audio_port_data {
+   struct audio_buffer *buf;
+   uint32_t num_periods;
+   uint32_t dsp_buf;
+   uint32_t mem_map_handle;
+};
 
 struct audio_client {
int session;
@@ -29,6 +66,9 @@ struct audio_client {
uint32_t io_mode;
struct apr_device *adev;
struct mutex lock;
+   spinlock_t buf_lock;
+   /* idx:1 out port, 0: in port */
+   struct audio_port_data port[2];
wait_queue_head_t cmd_wait;
struct aprv2_ibasic_rsp_result_t result;
int perf_mode;
@@ -62,6 +102,268 @@ static bool q6asm_is_valid_audio_client(struct 
audio_client *ac)
return false;
 }
 
+static inline void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
+uint32_t pkt_size, bool cmd_flg,
+uint32_t stream_id)
+{
+   hdr->hdr_field = APR_SEQ_CMD_HDR_FIELD;
+   hdr->src_svc = ac->adev->svc_id;
+   hdr->src_domain = APR_DOMAIN_APPS;
+   hdr->dest_svc = APR_SVC_ASM;
+   hdr->dest_domain = APR_DOMAIN_ADSP;
+   hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id);
+   hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id);
+   hdr->pkt_size = pkt_size;
+   if (cmd_flg)
+   hdr->token = ac->session;
+}
+
+static int q6asm_apr_send_session_pkt(struct q6asm *a, struct audio_client *ac,
+ void *data, uint32_t rsp_opcode)
+{
+   struct apr_hdr *hdr = data;
+   int rc;
+
+   mutex_lock(>lock);
+   ac->result.opcode = 0;
+   ac->result.status = 0;
+   rc = apr_send_pkt(a->adev, data);
+   if (rc < 0)
+   goto err;
+
+   if (rsp_opcode)
+   rc = wait_event_timeout(a->mem_wait,
+   (ac->result.opcode == hdr->opcode) ||
+   (ac->result.opcode == rsp_opcode),
+   5 * HZ);
+   else
+   rc = wait_event_timeout(a->mem_wait,
+   (ac->result.opcode == hdr->opcode),
+   5 * HZ);
+
+   if (!rc) {
+   dev_err(a->dev, "CMD timeout\n");
+   rc = -ETIMEDOUT;
+   } else if (ac->result.status > 0) {
+   dev_err(a->dev, "DSP returned error[%x]\n",
+   ac->result.status);
+   rc = -EINVAL;
+   }
+
+err:
+   mutex_unlock(>lock);
+   return rc;
+}
+
+static int __q6asm_memory_unmap(struct audio_client *ac,
+   phys_addr_t buf_add, int dir)
+{
+   struct avs_cmd_shared_mem_unmap_regions mem_unmap;
+   struct q6asm *a = dev_get_drvdata(ac->dev->parent);
+   int rc;
+
+   if (ac->port[dir].mem_map_handle == 0) {
+   dev_err(ac->dev, "invalid mem handle\n");
+   return -EINVAL;
+   }
+
+   mem_unmap.hdr.hdr_field = APR_SEQ_CMD_HDR_FIELD;
+   mem_unmap.hdr.src_port = 0;
+   mem_unmap.hdr.dest_port = 0;
+   mem_unmap.hdr.pkt_size = sizeof(mem_unmap);
+   mem_unmap.hdr.token = ((ac->session << 8) | dir);
+
+   mem_unmap.hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS;
+   mem_unmap.mem_map_handle = ac->port[dir].mem_map_handle;
+
+   rc = q6asm_apr_send_session_pkt(a, ac, _unmap, 0);
+   if 

[PATCH v4 16/24] ASoC: qdsp6: q6routing: Add q6routing driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to q6 routing driver which configures route
between ASM and AFE module using ADM apis.

This driver uses dapm widgets to setup the matrix between AFE ports and
ASM streams.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   4 +
 sound/soc/qcom/qdsp6/Makefile|   1 +
 sound/soc/qcom/qdsp6/q6routing.c | 392 +++
 sound/soc/qcom/qdsp6/q6routing.h |   9 +
 4 files changed, 406 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/q6routing.c
 create mode 100644 sound/soc/qcom/qdsp6/q6routing.h

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 488ee93ee084..7a868a6fac1b 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -53,6 +53,9 @@ config SND_SOC_QDSP6_AFE
 config SND_SOC_QDSP6_ADM
tristate
 
+config SND_SOC_QDSP6_ROUTING
+   tristate
+
 config SND_SOC_QDSP6_ASM
tristate
 
@@ -65,6 +68,7 @@ config SND_SOC_QDSP6
select SND_SOC_QDSP6_COMMON
select SND_SOC_QDSP6_AFE
select SND_SOC_QDSP6_ADM
+   select SND_SOC_QDSP6_ROUTING
select SND_SOC_QDSP6_ASM
select SND_SOC_QDSP6_CORE
help
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index 61f089bc0d25..6640bceccc18 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
 obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o
 obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
+obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o
 obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
 obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
new file mode 100644
index ..b72bd9045fea
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2017, The Linux Foundation
+// Copyright (c) 2018, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "q6afe.h"
+#include "q6asm.h"
+#include "q6adm.h"
+#include "q6routing.h"
+
+struct session_data {
+   int state;
+   int port_id;
+   int path_type;
+   int app_type;
+   int acdb_id;
+   int sample_rate;
+   int bits_per_sample;
+   int channels;
+   int perf_mode;
+   int numcopps;
+   int fedai_id;
+   unsigned long copp_map;
+};
+
+struct msm_routing_data {
+   struct session_data sessions[MAX_SESSIONS];
+   struct session_data port_data[AFE_MAX_PORTS];
+   struct device *dev;
+   struct mutex lock;
+};
+
+static struct msm_routing_data *routing_data;
+
+/**
+ * q6routing_stream_open() - Register a new stream for route setup
+ *
+ * @fedai_id: Frontend dai id.
+ * @perf_mode: Performance mode.
+ * @stream_id: ASM stream id to map.
+ * @stream_type: Direction of stream
+ *
+ * Return: Will be an negative on error or a zero on success.
+ */
+int q6routing_stream_open(int fedai_id, int perf_mode,
+  int stream_id, int stream_type)
+{
+   int j, topology, num_copps = 0;
+   struct route_payload payload;
+   int copp_idx;
+   struct session_data *session, *pdata;
+
+   if (!routing_data) {
+   pr_err("Routing driver not yet ready\n");
+   return -EINVAL;
+   }
+
+   session = _data->sessions[stream_id - 1];
+   pdata = _data->port_data[session->port_id];
+
+   mutex_lock(_data->lock);
+   session->fedai_id = fedai_id;
+
+   session->path_type = pdata->path_type;
+   session->sample_rate = pdata->sample_rate;
+   session->channels = pdata->channels;
+   session->bits_per_sample = pdata->bits_per_sample;
+
+   payload.num_copps = 0; /* only RX needs to use payload */
+   topology = NULL_COPP_TOPOLOGY;
+   copp_idx = q6adm_open(routing_data->dev, session->port_id,
+ session->path_type, session->sample_rate,
+ session->channels, topology, perf_mode,
+ session->bits_per_sample, 0, 0);
+
+   if (copp_idx < 0) {
+   mutex_unlock(_data->lock);
+   return -EINVAL;
+   }
+
+   set_bit(copp_idx, >copp_map);
+
+   for_each_set_bit(j, >copp_map, MAX_COPPS_PER_PORT) {
+   payload.port_id[num_copps] = session->port_id;
+   payload.copp_idx[num_copps] = j;
+   num_copps++;
+   }
+
+   if (num_copps) {
+   payload.num_copps = num_copps;
+   payload.session_id = stream_id;
+   q6adm_matrix_map(routing_data->dev, session->path_type,
+payload, perf_mode);
+   }

[PATCH v4 16/24] ASoC: qdsp6: q6routing: Add q6routing driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to q6 routing driver which configures route
between ASM and AFE module using ADM apis.

This driver uses dapm widgets to setup the matrix between AFE ports and
ASM streams.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   4 +
 sound/soc/qcom/qdsp6/Makefile|   1 +
 sound/soc/qcom/qdsp6/q6routing.c | 392 +++
 sound/soc/qcom/qdsp6/q6routing.h |   9 +
 4 files changed, 406 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/q6routing.c
 create mode 100644 sound/soc/qcom/qdsp6/q6routing.h

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 488ee93ee084..7a868a6fac1b 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -53,6 +53,9 @@ config SND_SOC_QDSP6_AFE
 config SND_SOC_QDSP6_ADM
tristate
 
+config SND_SOC_QDSP6_ROUTING
+   tristate
+
 config SND_SOC_QDSP6_ASM
tristate
 
@@ -65,6 +68,7 @@ config SND_SOC_QDSP6
select SND_SOC_QDSP6_COMMON
select SND_SOC_QDSP6_AFE
select SND_SOC_QDSP6_ADM
+   select SND_SOC_QDSP6_ROUTING
select SND_SOC_QDSP6_ASM
select SND_SOC_QDSP6_CORE
help
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index 61f089bc0d25..6640bceccc18 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
 obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o
 obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
+obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o
 obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
 obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
new file mode 100644
index ..b72bd9045fea
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -0,0 +1,392 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2017, The Linux Foundation
+// Copyright (c) 2018, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "q6afe.h"
+#include "q6asm.h"
+#include "q6adm.h"
+#include "q6routing.h"
+
+struct session_data {
+   int state;
+   int port_id;
+   int path_type;
+   int app_type;
+   int acdb_id;
+   int sample_rate;
+   int bits_per_sample;
+   int channels;
+   int perf_mode;
+   int numcopps;
+   int fedai_id;
+   unsigned long copp_map;
+};
+
+struct msm_routing_data {
+   struct session_data sessions[MAX_SESSIONS];
+   struct session_data port_data[AFE_MAX_PORTS];
+   struct device *dev;
+   struct mutex lock;
+};
+
+static struct msm_routing_data *routing_data;
+
+/**
+ * q6routing_stream_open() - Register a new stream for route setup
+ *
+ * @fedai_id: Frontend dai id.
+ * @perf_mode: Performance mode.
+ * @stream_id: ASM stream id to map.
+ * @stream_type: Direction of stream
+ *
+ * Return: Will be an negative on error or a zero on success.
+ */
+int q6routing_stream_open(int fedai_id, int perf_mode,
+  int stream_id, int stream_type)
+{
+   int j, topology, num_copps = 0;
+   struct route_payload payload;
+   int copp_idx;
+   struct session_data *session, *pdata;
+
+   if (!routing_data) {
+   pr_err("Routing driver not yet ready\n");
+   return -EINVAL;
+   }
+
+   session = _data->sessions[stream_id - 1];
+   pdata = _data->port_data[session->port_id];
+
+   mutex_lock(_data->lock);
+   session->fedai_id = fedai_id;
+
+   session->path_type = pdata->path_type;
+   session->sample_rate = pdata->sample_rate;
+   session->channels = pdata->channels;
+   session->bits_per_sample = pdata->bits_per_sample;
+
+   payload.num_copps = 0; /* only RX needs to use payload */
+   topology = NULL_COPP_TOPOLOGY;
+   copp_idx = q6adm_open(routing_data->dev, session->port_id,
+ session->path_type, session->sample_rate,
+ session->channels, topology, perf_mode,
+ session->bits_per_sample, 0, 0);
+
+   if (copp_idx < 0) {
+   mutex_unlock(_data->lock);
+   return -EINVAL;
+   }
+
+   set_bit(copp_idx, >copp_map);
+
+   for_each_set_bit(j, >copp_map, MAX_COPPS_PER_PORT) {
+   payload.port_id[num_copps] = session->port_id;
+   payload.copp_idx[num_copps] = j;
+   num_copps++;
+   }
+
+   if (num_copps) {
+   payload.num_copps = num_copps;
+   payload.session_id = stream_id;
+   q6adm_matrix_map(routing_data->dev, session->path_type,
+payload, perf_mode);
+   }
+   mutex_unlock(_data->lock);
+
+   return 0;
+}

[PATCH v4 18/24] ASoC: qdsp6: q6routing: Add support to MI2S Mixers

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch add support to MI2S mixers required to select path between
ASM stream and AFE ports.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/qdsp6/q6routing.c | 329 +++
 1 file changed, 329 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index c6be775167b8..710c2ae652c7 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -232,6 +232,103 @@ static const struct snd_kcontrol_new 
hdmi_mixer_controls[] = {
   msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new 

[PATCH v4 18/24] ASoC: qdsp6: q6routing: Add support to MI2S Mixers

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch add support to MI2S mixers required to select path between
ASM stream and AFE ports.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/qdsp6/q6routing.c | 329 +++
 1 file changed, 329 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index c6be775167b8..710c2ae652c7 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -232,6 +232,103 @@ static const struct snd_kcontrol_new 
hdmi_mixer_controls[] = {
   msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new primary_mi2s_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", PRIMARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new secondary_mi2s_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SECONDARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new quaternary_mi2s_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", QUATERNARY_MI2S_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new tertiary_mi2s_rx_mixer_controls[] = {
+   

[PATCH v4 19/24] ASoC: qdsp6: q6afe: Add q6afe dai driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to q6afe backend dais driver.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   4 +
 sound/soc/qcom/qdsp6/Makefile|   1 +
 sound/soc/qcom/qdsp6/q6afe-dai.c | 746 +++
 3 files changed, 751 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/q6afe-dai.c

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 7a868a6fac1b..9b630686eb19 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -50,6 +50,9 @@ config SND_SOC_QDSP6_COMMON
 config SND_SOC_QDSP6_AFE
tristate
 
+config SND_SOC_QDSP6_AFE_DAI
+   tristate
+
 config SND_SOC_QDSP6_ADM
tristate
 
@@ -67,6 +70,7 @@ config SND_SOC_QDSP6
depends on QCOM_APR && HAS_DMA
select SND_SOC_QDSP6_COMMON
select SND_SOC_QDSP6_AFE
+   select SND_SOC_QDSP6_AFE_DAI
select SND_SOC_QDSP6_ADM
select SND_SOC_QDSP6_ROUTING
select SND_SOC_QDSP6_ASM
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index 6640bceccc18..6a8ae698f22f 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
 obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o
+obj-$(CONFIG_SND_SOC_QDSP6_AFE_DAI) += q6afe-dai.o
 obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
 obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o
 obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c
new file mode 100644
index ..5cb8b59a8cd9
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
@@ -0,0 +1,746 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2016, The Linux Foundation
+// Copyright (c) 2018, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "q6afe.h"
+
+struct q6afe_dai_priv_data {
+   uint32_t sd_line_mask;
+};
+
+struct q6afe_dai_data {
+   struct q6afe_port *port[AFE_PORT_MAX];
+   struct q6afe_port_config port_config[AFE_PORT_MAX];
+   bool is_port_started[AFE_PORT_MAX];
+   struct q6afe_dai_priv_data priv[AFE_PORT_MAX];
+};
+
+static int q6slim_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params,
+   struct snd_soc_dai *dai)
+{
+
+   struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
+   struct q6afe_slim_cfg *slim = _data->port_config[dai->id].slim;
+
+   slim->num_channels = params_channels(params);
+   slim->sample_rate = params_rate(params);
+
+   switch (params_format(params)) {
+   case SNDRV_PCM_FORMAT_S16_LE:
+   case SNDRV_PCM_FORMAT_SPECIAL:
+   slim->bit_width = 16;
+   break;
+   case SNDRV_PCM_FORMAT_S24_LE:
+   slim->bit_width = 24;
+   break;
+   case SNDRV_PCM_FORMAT_S32_LE:
+   slim->bit_width = 32;
+   break;
+   default:
+   pr_err("%s: format %d\n",
+   __func__, params_format(params));
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params,
+   struct snd_soc_dai *dai)
+{
+   struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
+   int channels = params_channels(params);
+   struct q6afe_hdmi_cfg *hdmi = _data->port_config[dai->id].hdmi;
+
+   hdmi->sample_rate = params_rate(params);
+   switch (params_format(params)) {
+   case SNDRV_PCM_FORMAT_S16_LE:
+   hdmi->bit_width = 16;
+   break;
+   case SNDRV_PCM_FORMAT_S24_LE:
+   hdmi->bit_width = 24;
+   break;
+   }
+
+   /* HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4 */
+   switch (channels) {
+   case 2:
+   hdmi->channel_allocation = 0;
+   break;
+   case 3:
+   hdmi->channel_allocation = 0x02;
+   break;
+   case 4:
+   hdmi->channel_allocation = 0x06;
+   break;
+   case 5:
+   hdmi->channel_allocation = 0x0A;
+   break;
+   case 6:
+   hdmi->channel_allocation = 0x0B;
+   break;
+   case 7:
+   hdmi->channel_allocation = 0x12;
+   break;
+   case 8:
+   hdmi->channel_allocation = 0x13;
+   break;
+   default:
+   dev_err(dai->dev, "invalid Channels = %u\n", channels);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int q6i2s_hw_params(struct snd_pcm_substream *substream,
+  struct snd_pcm_hw_params 

[PATCH v4 14/24] ASoC: qdsp6: q6asm: Add support to audio stream apis

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to open, write and media format commands
in the q6asm module.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/qdsp6/q6asm.c | 744 ++-
 sound/soc/qcom/qdsp6/q6asm.h |  49 +++
 2 files changed, 792 insertions(+), 1 deletion(-)

diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 8a2ca2ff9ce8..ddbf526358bd 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -9,6 +9,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -17,10 +19,36 @@
 #include "q6dsp-errno.h"
 #include "q6dsp-common.h"
 
+#define ASM_STREAM_CMD_CLOSE   0x00010BCD
+#define ASM_STREAM_CMD_FLUSH   0x00010BCE
+#define ASM_SESSION_CMD_PAUSE  0x00010BD3
+#define ASM_DATA_CMD_EOS   0x00010BDB
+#define ASM_DEFAULT_POPP_TOPOLOGY  0x00010BE4
+#define ASM_STREAM_CMD_FLUSH_READBUFS  0x00010C09
+#define ASM_STREAM_CMD_SET_ENCDEC_PARAM0x00010C10
+#define ASM_STREAM_POSTPROC_TOPO_ID_NONE   0x00010C68
 #define ASM_CMD_SHARED_MEM_MAP_REGIONS 0x00010D92
 #define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS  0x00010D93
 #define ASM_CMD_SHARED_MEM_UNMAP_REGIONS   0x00010D94
-
+#define ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2   0x00010D98
+#define ASM_DATA_EVENT_WRITE_DONE_V2   0x00010D99
+#define ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 0x00010DA3
+#define ASM_SESSION_CMD_RUN_V2 0x00010DAA
+#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5
+#define ASM_DATA_CMD_WRITE_V2  0x00010DAB
+#define ASM_DATA_CMD_READ_V2   0x00010DAC
+#define ASM_SESSION_CMD_SUSPEND0x00010DEC
+#define ASM_STREAM_CMD_OPEN_WRITE_V3   0x00010DB3
+#define ASM_STREAM_CMD_OPEN_READ_V3 0x00010DB4
+#define ASM_DATA_EVENT_READ_DONE_V2 0x00010D9A
+#define ASM_STREAM_CMD_OPEN_READWRITE_V20x00010D8D
+
+
+#define ASM_LEGACY_STREAM_SESSION  0
+/* Bit shift for the stream_perf_mode subfield. */
+#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ  29
+#define ASM_END_POINT_DEVICE_MATRIX0
+#define ASM_DEFAULT_APP_TYPE   0
 #define ASM_SYNC_IO_MODE   0x0001
 #define ASM_ASYNC_IO_MODE  0x0002
 #define ASM_TUN_READ_IO_MODE   0x0004  /* tunnel read write mode */
@@ -46,6 +74,96 @@ struct avs_cmd_shared_mem_unmap_regions {
u32 mem_map_handle;
 } __packed;
 
+struct asm_data_cmd_media_fmt_update_v2 {
+   u32 fmt_blk_size;
+} __packed;
+
+struct asm_multi_channel_pcm_fmt_blk_v2 {
+   struct apr_hdr hdr;
+   struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
+   u16 num_channels;
+   u16 bits_per_sample;
+   u32 sample_rate;
+   u16 is_signed;
+   u16 reserved;
+   u8 channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];
+} __packed;
+
+struct asm_stream_cmd_set_encdec_param {
+   u32  param_id;
+   u32  param_size;
+} __packed;
+
+struct asm_enc_cfg_blk_param_v2 {
+   u32  frames_per_buf;
+   u32  enc_cfg_blk_size;
+} __packed;
+
+struct asm_multi_channel_pcm_enc_cfg_v2 {
+   struct apr_hdr hdr;
+   struct asm_stream_cmd_set_encdec_param  encdec;
+   struct asm_enc_cfg_blk_param_v2 encblk;
+   uint16_t  num_channels;
+   uint16_t  bits_per_sample;
+   uint32_t  sample_rate;
+   uint16_t  is_signed;
+   uint16_t  reserved;
+   uint8_t   channel_mapping[8];
+} __packed;
+
+struct asm_data_cmd_read_v2 {
+   struct apr_hdr   hdr;
+   u32  buf_addr_lsw;
+   u32  buf_addr_msw;
+   u32  mem_map_handle;
+   u32  buf_size;
+   u32  seq_id;
+} __packed;
+
+struct asm_data_cmd_read_v2_done {
+   u32 status;
+   u32 buf_addr_lsw;
+   u32 buf_addr_msw;
+};
+
+struct asm_stream_cmd_open_read_v3 {
+   struct apr_hdr hdr;
+   u32mode_flags;
+   u32src_endpointype;
+   u32preprocopo_id;
+   u32enc_cfg_id;
+   u16bits_per_sample;
+   u16reserved;
+} __packed;
+
+struct asm_data_cmd_write_v2 {
+   struct apr_hdr hdr;
+   u32 buf_addr_lsw;
+   u32 buf_addr_msw;
+   u32 mem_map_handle;
+   u32 buf_size;
+   u32 seq_id;
+   u32 timestamp_lsw;
+   u32 timestamp_msw;
+   u32 flags;
+} __packed;
+
+struct asm_stream_cmd_open_write_v3 {
+   struct apr_hdr hdr;
+   uint32_t mode_flags;
+   uint16_t sink_endpointype;
+   uint16_t bits_per_sample;
+   uint32_t postprocopo_id;
+   uint32_t dec_fmt_id;
+} __packed;
+

[PATCH v4 19/24] ASoC: qdsp6: q6afe: Add q6afe dai driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to q6afe backend dais driver.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   4 +
 sound/soc/qcom/qdsp6/Makefile|   1 +
 sound/soc/qcom/qdsp6/q6afe-dai.c | 746 +++
 3 files changed, 751 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/q6afe-dai.c

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 7a868a6fac1b..9b630686eb19 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -50,6 +50,9 @@ config SND_SOC_QDSP6_COMMON
 config SND_SOC_QDSP6_AFE
tristate
 
+config SND_SOC_QDSP6_AFE_DAI
+   tristate
+
 config SND_SOC_QDSP6_ADM
tristate
 
@@ -67,6 +70,7 @@ config SND_SOC_QDSP6
depends on QCOM_APR && HAS_DMA
select SND_SOC_QDSP6_COMMON
select SND_SOC_QDSP6_AFE
+   select SND_SOC_QDSP6_AFE_DAI
select SND_SOC_QDSP6_ADM
select SND_SOC_QDSP6_ROUTING
select SND_SOC_QDSP6_ASM
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index 6640bceccc18..6a8ae698f22f 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -1,5 +1,6 @@
 obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
 obj-$(CONFIG_SND_SOC_QDSP6_AFE) += q6afe.o
+obj-$(CONFIG_SND_SOC_QDSP6_AFE_DAI) += q6afe-dai.o
 obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
 obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o
 obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
diff --git a/sound/soc/qcom/qdsp6/q6afe-dai.c b/sound/soc/qcom/qdsp6/q6afe-dai.c
new file mode 100644
index ..5cb8b59a8cd9
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6afe-dai.c
@@ -0,0 +1,746 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2016, The Linux Foundation
+// Copyright (c) 2018, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "q6afe.h"
+
+struct q6afe_dai_priv_data {
+   uint32_t sd_line_mask;
+};
+
+struct q6afe_dai_data {
+   struct q6afe_port *port[AFE_PORT_MAX];
+   struct q6afe_port_config port_config[AFE_PORT_MAX];
+   bool is_port_started[AFE_PORT_MAX];
+   struct q6afe_dai_priv_data priv[AFE_PORT_MAX];
+};
+
+static int q6slim_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params,
+   struct snd_soc_dai *dai)
+{
+
+   struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
+   struct q6afe_slim_cfg *slim = _data->port_config[dai->id].slim;
+
+   slim->num_channels = params_channels(params);
+   slim->sample_rate = params_rate(params);
+
+   switch (params_format(params)) {
+   case SNDRV_PCM_FORMAT_S16_LE:
+   case SNDRV_PCM_FORMAT_SPECIAL:
+   slim->bit_width = 16;
+   break;
+   case SNDRV_PCM_FORMAT_S24_LE:
+   slim->bit_width = 24;
+   break;
+   case SNDRV_PCM_FORMAT_S32_LE:
+   slim->bit_width = 32;
+   break;
+   default:
+   pr_err("%s: format %d\n",
+   __func__, params_format(params));
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int q6hdmi_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params,
+   struct snd_soc_dai *dai)
+{
+   struct q6afe_dai_data *dai_data = dev_get_drvdata(dai->dev);
+   int channels = params_channels(params);
+   struct q6afe_hdmi_cfg *hdmi = _data->port_config[dai->id].hdmi;
+
+   hdmi->sample_rate = params_rate(params);
+   switch (params_format(params)) {
+   case SNDRV_PCM_FORMAT_S16_LE:
+   hdmi->bit_width = 16;
+   break;
+   case SNDRV_PCM_FORMAT_S24_LE:
+   hdmi->bit_width = 24;
+   break;
+   }
+
+   /* HDMI spec CEA-861-E: Table 28 Audio InfoFrame Data Byte 4 */
+   switch (channels) {
+   case 2:
+   hdmi->channel_allocation = 0;
+   break;
+   case 3:
+   hdmi->channel_allocation = 0x02;
+   break;
+   case 4:
+   hdmi->channel_allocation = 0x06;
+   break;
+   case 5:
+   hdmi->channel_allocation = 0x0A;
+   break;
+   case 6:
+   hdmi->channel_allocation = 0x0B;
+   break;
+   case 7:
+   hdmi->channel_allocation = 0x12;
+   break;
+   case 8:
+   hdmi->channel_allocation = 0x13;
+   break;
+   default:
+   dev_err(dai->dev, "invalid Channels = %u\n", channels);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int q6i2s_hw_params(struct snd_pcm_substream *substream,
+  struct snd_pcm_hw_params *params,
+  struct snd_soc_dai *dai)
+{

[PATCH v4 14/24] ASoC: qdsp6: q6asm: Add support to audio stream apis

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to open, write and media format commands
in the q6asm module.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/qdsp6/q6asm.c | 744 ++-
 sound/soc/qcom/qdsp6/q6asm.h |  49 +++
 2 files changed, 792 insertions(+), 1 deletion(-)

diff --git a/sound/soc/qcom/qdsp6/q6asm.c b/sound/soc/qcom/qdsp6/q6asm.c
index 8a2ca2ff9ce8..ddbf526358bd 100644
--- a/sound/soc/qcom/qdsp6/q6asm.c
+++ b/sound/soc/qcom/qdsp6/q6asm.c
@@ -9,6 +9,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 
 #include 
@@ -17,10 +19,36 @@
 #include "q6dsp-errno.h"
 #include "q6dsp-common.h"
 
+#define ASM_STREAM_CMD_CLOSE   0x00010BCD
+#define ASM_STREAM_CMD_FLUSH   0x00010BCE
+#define ASM_SESSION_CMD_PAUSE  0x00010BD3
+#define ASM_DATA_CMD_EOS   0x00010BDB
+#define ASM_DEFAULT_POPP_TOPOLOGY  0x00010BE4
+#define ASM_STREAM_CMD_FLUSH_READBUFS  0x00010C09
+#define ASM_STREAM_CMD_SET_ENCDEC_PARAM0x00010C10
+#define ASM_STREAM_POSTPROC_TOPO_ID_NONE   0x00010C68
 #define ASM_CMD_SHARED_MEM_MAP_REGIONS 0x00010D92
 #define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS  0x00010D93
 #define ASM_CMD_SHARED_MEM_UNMAP_REGIONS   0x00010D94
-
+#define ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2   0x00010D98
+#define ASM_DATA_EVENT_WRITE_DONE_V2   0x00010D99
+#define ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2 0x00010DA3
+#define ASM_SESSION_CMD_RUN_V2 0x00010DAA
+#define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2 0x00010DA5
+#define ASM_DATA_CMD_WRITE_V2  0x00010DAB
+#define ASM_DATA_CMD_READ_V2   0x00010DAC
+#define ASM_SESSION_CMD_SUSPEND0x00010DEC
+#define ASM_STREAM_CMD_OPEN_WRITE_V3   0x00010DB3
+#define ASM_STREAM_CMD_OPEN_READ_V3 0x00010DB4
+#define ASM_DATA_EVENT_READ_DONE_V2 0x00010D9A
+#define ASM_STREAM_CMD_OPEN_READWRITE_V20x00010D8D
+
+
+#define ASM_LEGACY_STREAM_SESSION  0
+/* Bit shift for the stream_perf_mode subfield. */
+#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ  29
+#define ASM_END_POINT_DEVICE_MATRIX0
+#define ASM_DEFAULT_APP_TYPE   0
 #define ASM_SYNC_IO_MODE   0x0001
 #define ASM_ASYNC_IO_MODE  0x0002
 #define ASM_TUN_READ_IO_MODE   0x0004  /* tunnel read write mode */
@@ -46,6 +74,96 @@ struct avs_cmd_shared_mem_unmap_regions {
u32 mem_map_handle;
 } __packed;
 
+struct asm_data_cmd_media_fmt_update_v2 {
+   u32 fmt_blk_size;
+} __packed;
+
+struct asm_multi_channel_pcm_fmt_blk_v2 {
+   struct apr_hdr hdr;
+   struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
+   u16 num_channels;
+   u16 bits_per_sample;
+   u32 sample_rate;
+   u16 is_signed;
+   u16 reserved;
+   u8 channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];
+} __packed;
+
+struct asm_stream_cmd_set_encdec_param {
+   u32  param_id;
+   u32  param_size;
+} __packed;
+
+struct asm_enc_cfg_blk_param_v2 {
+   u32  frames_per_buf;
+   u32  enc_cfg_blk_size;
+} __packed;
+
+struct asm_multi_channel_pcm_enc_cfg_v2 {
+   struct apr_hdr hdr;
+   struct asm_stream_cmd_set_encdec_param  encdec;
+   struct asm_enc_cfg_blk_param_v2 encblk;
+   uint16_t  num_channels;
+   uint16_t  bits_per_sample;
+   uint32_t  sample_rate;
+   uint16_t  is_signed;
+   uint16_t  reserved;
+   uint8_t   channel_mapping[8];
+} __packed;
+
+struct asm_data_cmd_read_v2 {
+   struct apr_hdr   hdr;
+   u32  buf_addr_lsw;
+   u32  buf_addr_msw;
+   u32  mem_map_handle;
+   u32  buf_size;
+   u32  seq_id;
+} __packed;
+
+struct asm_data_cmd_read_v2_done {
+   u32 status;
+   u32 buf_addr_lsw;
+   u32 buf_addr_msw;
+};
+
+struct asm_stream_cmd_open_read_v3 {
+   struct apr_hdr hdr;
+   u32mode_flags;
+   u32src_endpointype;
+   u32preprocopo_id;
+   u32enc_cfg_id;
+   u16bits_per_sample;
+   u16reserved;
+} __packed;
+
+struct asm_data_cmd_write_v2 {
+   struct apr_hdr hdr;
+   u32 buf_addr_lsw;
+   u32 buf_addr_msw;
+   u32 mem_map_handle;
+   u32 buf_size;
+   u32 seq_id;
+   u32 timestamp_lsw;
+   u32 timestamp_msw;
+   u32 flags;
+} __packed;
+
+struct asm_stream_cmd_open_write_v3 {
+   struct apr_hdr hdr;
+   uint32_t mode_flags;
+   uint16_t sink_endpointype;
+   uint16_t bits_per_sample;
+   uint32_t postprocopo_id;
+   uint32_t dec_fmt_id;
+} __packed;
+
+struct asm_session_cmd_run_v2 {
+   struct apr_hdr hdr;
+  

[PATCH v4 22/24] ASoC: qcom: apq8096: Add db820c machine driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to DB820c machine driver.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   9 ++
 sound/soc/qcom/Makefile  |   2 +
 sound/soc/qcom/apq8096.c | 235 +++
 3 files changed, 246 insertions(+)
 create mode 100644 sound/soc/qcom/apq8096.c

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 5bdf39f6003f..9d8007e2f3cf 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -84,3 +84,12 @@ config SND_SOC_QDSP6
 This will enable sound soc platform specific
 audio drivers. This includes q6asm, q6adm,
 q6afe interfaces to DSP using apr.
+
+config SND_SOC_MSM8996
+   tristate "SoC Machine driver for MSM8996 and APQ8096 boards"
+   depends on QCOM_APR
+   select SND_SOC_QDSP6
+   help
+  Support for Qualcomm Technologies LPASS audio block in
+  APQ8096 SoC-based systems.
+  Say Y if you want to use audio device on this SoCs
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 0276717917c0..206945bb9ba1 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -13,9 +13,11 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += 
snd-soc-lpass-apq8016.o
 # Machine
 snd-soc-storm-objs := storm.o
 snd-soc-apq8016-sbc-objs := apq8016_sbc.o
+snd-soc-apq8096-objs := apq8096.o
 
 obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
 obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
+obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-apq8096.o
 
 #DSP lib
 obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/
diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
new file mode 100644
index ..e9b61dc0aa63
--- /dev/null
+++ b/sound/soc/qcom/apq8096.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+   struct snd_interval *rate = hw_param_interval(params,
+   SNDRV_PCM_HW_PARAM_RATE);
+   struct snd_interval *channels = hw_param_interval(params,
+   SNDRV_PCM_HW_PARAM_CHANNELS);
+
+   rate->min = rate->max = 48000;
+   channels->min = channels->max = 2;
+
+   return 0;
+}
+
+static int apq8096_sbc_parse_of(struct snd_soc_card *card)
+{
+   struct device_node *np, *codec, *platform, *cpu, *node;
+   struct device *dev = card->dev;
+   struct snd_soc_dai_link *link;
+   int ret, num_links;
+
+   ret = snd_soc_of_parse_card_name(card, "qcom,model");
+   if (ret) {
+   dev_err(dev, "Error parsing card name: %d\n", ret);
+   return ret;
+   }
+
+   node = dev->of_node;
+
+   /* DAPM routes */
+   if (of_property_read_bool(node, "qcom,audio-routing")) {
+   ret = snd_soc_of_parse_audio_routing(card,
+   "qcom,audio-routing");
+   if (ret)
+   return ret;
+   }
+
+   /* Populate links */
+   num_links = of_get_child_count(node);
+
+   /* Allocate the DAI link array */
+   card->dai_link = kcalloc(num_links, sizeof(*link), GFP_KERNEL);
+   if (!card->dai_link)
+   return -ENOMEM;
+
+   card->num_links = num_links;
+   link = card->dai_link;
+
+   for_each_child_of_node(node, np) {
+   cpu = of_get_child_by_name(np, "cpu");
+   platform = of_get_child_by_name(np, "platform");
+   codec = of_get_child_by_name(np, "codec");
+
+   if (!cpu) {
+   dev_err(dev, "Can't find cpu DT node\n");
+   return -EINVAL;
+   }
+
+   link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
+   if (!link->cpu_of_node) {
+   dev_err(card->dev, "error getting cpu phandle\n");
+   return -EINVAL;
+   }
+
+   link->platform_of_node = of_parse_phandle(platform,
+ "sound-dai", 0);
+   if (!link->platform_of_node) {
+   dev_err(card->dev, "error getting platform phandle\n");
+   return -EINVAL;
+   }
+
+   ret = snd_soc_of_get_dai_name(cpu, >cpu_dai_name);
+   if (ret) {
+   dev_err(card->dev, "error getting cpu dai name\n");
+   return ret;
+   }
+
+   if (codec) {
+   ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
+
+   if (ret < 0) {
+   dev_err(card->dev, 

[PATCH v4 22/24] ASoC: qcom: apq8096: Add db820c machine driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to DB820c machine driver.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   9 ++
 sound/soc/qcom/Makefile  |   2 +
 sound/soc/qcom/apq8096.c | 235 +++
 3 files changed, 246 insertions(+)
 create mode 100644 sound/soc/qcom/apq8096.c

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 5bdf39f6003f..9d8007e2f3cf 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -84,3 +84,12 @@ config SND_SOC_QDSP6
 This will enable sound soc platform specific
 audio drivers. This includes q6asm, q6adm,
 q6afe interfaces to DSP using apr.
+
+config SND_SOC_MSM8996
+   tristate "SoC Machine driver for MSM8996 and APQ8096 boards"
+   depends on QCOM_APR
+   select SND_SOC_QDSP6
+   help
+  Support for Qualcomm Technologies LPASS audio block in
+  APQ8096 SoC-based systems.
+  Say Y if you want to use audio device on this SoCs
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 0276717917c0..206945bb9ba1 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -13,9 +13,11 @@ obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += 
snd-soc-lpass-apq8016.o
 # Machine
 snd-soc-storm-objs := storm.o
 snd-soc-apq8016-sbc-objs := apq8016_sbc.o
+snd-soc-apq8096-objs := apq8096.o
 
 obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o
 obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o
+obj-$(CONFIG_SND_SOC_MSM8996) += snd-soc-apq8096.o
 
 #DSP lib
 obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/
diff --git a/sound/soc/qcom/apq8096.c b/sound/soc/qcom/apq8096.c
new file mode 100644
index ..e9b61dc0aa63
--- /dev/null
+++ b/sound/soc/qcom/apq8096.c
@@ -0,0 +1,235 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2018, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+static int apq8096_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+   struct snd_interval *rate = hw_param_interval(params,
+   SNDRV_PCM_HW_PARAM_RATE);
+   struct snd_interval *channels = hw_param_interval(params,
+   SNDRV_PCM_HW_PARAM_CHANNELS);
+
+   rate->min = rate->max = 48000;
+   channels->min = channels->max = 2;
+
+   return 0;
+}
+
+static int apq8096_sbc_parse_of(struct snd_soc_card *card)
+{
+   struct device_node *np, *codec, *platform, *cpu, *node;
+   struct device *dev = card->dev;
+   struct snd_soc_dai_link *link;
+   int ret, num_links;
+
+   ret = snd_soc_of_parse_card_name(card, "qcom,model");
+   if (ret) {
+   dev_err(dev, "Error parsing card name: %d\n", ret);
+   return ret;
+   }
+
+   node = dev->of_node;
+
+   /* DAPM routes */
+   if (of_property_read_bool(node, "qcom,audio-routing")) {
+   ret = snd_soc_of_parse_audio_routing(card,
+   "qcom,audio-routing");
+   if (ret)
+   return ret;
+   }
+
+   /* Populate links */
+   num_links = of_get_child_count(node);
+
+   /* Allocate the DAI link array */
+   card->dai_link = kcalloc(num_links, sizeof(*link), GFP_KERNEL);
+   if (!card->dai_link)
+   return -ENOMEM;
+
+   card->num_links = num_links;
+   link = card->dai_link;
+
+   for_each_child_of_node(node, np) {
+   cpu = of_get_child_by_name(np, "cpu");
+   platform = of_get_child_by_name(np, "platform");
+   codec = of_get_child_by_name(np, "codec");
+
+   if (!cpu) {
+   dev_err(dev, "Can't find cpu DT node\n");
+   return -EINVAL;
+   }
+
+   link->cpu_of_node = of_parse_phandle(cpu, "sound-dai", 0);
+   if (!link->cpu_of_node) {
+   dev_err(card->dev, "error getting cpu phandle\n");
+   return -EINVAL;
+   }
+
+   link->platform_of_node = of_parse_phandle(platform,
+ "sound-dai", 0);
+   if (!link->platform_of_node) {
+   dev_err(card->dev, "error getting platform phandle\n");
+   return -EINVAL;
+   }
+
+   ret = snd_soc_of_get_dai_name(cpu, >cpu_dai_name);
+   if (ret) {
+   dev_err(card->dev, "error getting cpu dai name\n");
+   return ret;
+   }
+
+   if (codec) {
+   ret = snd_soc_of_get_dai_link_codecs(dev, codec, link);
+
+   if (ret < 0) {
+   dev_err(card->dev, "error getting codec dai 
name\n");
+  

[PATCH v4 24/24] MAINTAINERS: Add myself as co-maintainer of qcom audio

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Add myself as co-maintainer of qcom audio drivers

Signed-off-by: Srinivas Kandagatla 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 93a12af4f180..7463122a1184 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11343,6 +11343,7 @@ F:  drivers/crypto/qat/
 QCOM AUDIO (ASoC) DRIVERS
 M: Patrick Lai 
 M: Banajit Goswami 
+M: Srinivas Kandagatla 
 L: alsa-de...@alsa-project.org (moderated for non-subscribers)
 S: Supported
 F: sound/soc/qcom/
-- 
2.15.1



[PATCH v4 24/24] MAINTAINERS: Add myself as co-maintainer of qcom audio

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Add myself as co-maintainer of qcom audio drivers

Signed-off-by: Srinivas Kandagatla 
---
 MAINTAINERS | 1 +
 1 file changed, 1 insertion(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 93a12af4f180..7463122a1184 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11343,6 +11343,7 @@ F:  drivers/crypto/qat/
 QCOM AUDIO (ASoC) DRIVERS
 M: Patrick Lai 
 M: Banajit Goswami 
+M: Srinivas Kandagatla 
 L: alsa-de...@alsa-project.org (moderated for non-subscribers)
 S: Supported
 F: sound/soc/qcom/
-- 
2.15.1



[PATCH v4 21/24] ASoC: qdsp6: dt-bindings: Add apq8096 machine bindings

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Add devicetree bindings documentation file for Qualcomm apq8096 sound card.

Signed-off-by: Srinivas Kandagatla 
---
 .../devicetree/bindings/sound/qcom,apq8096.txt | 80 ++
 1 file changed, 80 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/qcom,apq8096.txt

diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8096.txt 
b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
new file mode 100644
index ..fddc9f0ce3a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
@@ -0,0 +1,80 @@
+* Qualcomm Technologies APQ8096 ASoC sound card driver
+
+This binding describes the APQ8096 sound card, which uses qdsp for audio.
+
+- compatible:
+   Usage: required
+   Value type: 
+   Definition: must be "qcom,apq8096-sndcard"
+
+- qcom,audio-routing:
+   Usage: Optional
+   Value type: 
+   Definition:  A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the
+ connection's sink, the second being the connection's
+ source. Valid names could be power supplies, MicBias
+ of codec and the jacks on the board:
+
+= dailinks
+Each subnode of sndcard represents either a dailink, and subnodes of each
+dailinks would be cpu/codec/platform dais.
+
+- link-name:
+   Usage: required
+   Value type: 
+   Definition: User friendly name for dai link
+
+= CPU, PLATFORM, CODEC dais subnodes
+- cpu:
+   Usage: required
+   Value type: 
+   Definition: cpu dai sub-node
+
+- codec:
+   Usage: required
+   Value type: 
+   Definition: codec dai sub-node
+
+- platform:
+   Usage: opional
+   Value type: 
+   Definition: platform dai sub-node
+
+- sound-dai:
+   Usage: required
+   Value type: 
+   Definition: dai phandle/s and port of CPU/CODEC/PLATFORM node.
+
+Example:
+
+audio {
+   compatible = "qcom,apq8096-sndcard";
+   qcom,model = "DB820c";
+   com,audio-routing = "RX_BIAS", "MCLK";
+
+   mm1-dai-link {
+   link-name = "MultiMedia1";
+   cpu {
+   sound-dai = < MSM_FRONTEND_DAI_MULTIMEDIA1>;
+   };
+   platform {
+   sound-dai = <>;
+   };
+   };
+
+   hdmi-dai-link {
+   link-name = "HDMI Playback";
+   cpu {
+   sound-dai = < HDMI_RX>;
+   };
+
+   platform {
+   sound-dai = <>;
+   };
+
+   codec {
+   sound-dai = < 0>;
+   };
+   };
+};
-- 
2.15.1



[PATCH v4 21/24] ASoC: qdsp6: dt-bindings: Add apq8096 machine bindings

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

Add devicetree bindings documentation file for Qualcomm apq8096 sound card.

Signed-off-by: Srinivas Kandagatla 
---
 .../devicetree/bindings/sound/qcom,apq8096.txt | 80 ++
 1 file changed, 80 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/qcom,apq8096.txt

diff --git a/Documentation/devicetree/bindings/sound/qcom,apq8096.txt 
b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
new file mode 100644
index ..fddc9f0ce3a5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,apq8096.txt
@@ -0,0 +1,80 @@
+* Qualcomm Technologies APQ8096 ASoC sound card driver
+
+This binding describes the APQ8096 sound card, which uses qdsp for audio.
+
+- compatible:
+   Usage: required
+   Value type: 
+   Definition: must be "qcom,apq8096-sndcard"
+
+- qcom,audio-routing:
+   Usage: Optional
+   Value type: 
+   Definition:  A list of the connections between audio components.
+ Each entry is a pair of strings, the first being the
+ connection's sink, the second being the connection's
+ source. Valid names could be power supplies, MicBias
+ of codec and the jacks on the board:
+
+= dailinks
+Each subnode of sndcard represents either a dailink, and subnodes of each
+dailinks would be cpu/codec/platform dais.
+
+- link-name:
+   Usage: required
+   Value type: 
+   Definition: User friendly name for dai link
+
+= CPU, PLATFORM, CODEC dais subnodes
+- cpu:
+   Usage: required
+   Value type: 
+   Definition: cpu dai sub-node
+
+- codec:
+   Usage: required
+   Value type: 
+   Definition: codec dai sub-node
+
+- platform:
+   Usage: opional
+   Value type: 
+   Definition: platform dai sub-node
+
+- sound-dai:
+   Usage: required
+   Value type: 
+   Definition: dai phandle/s and port of CPU/CODEC/PLATFORM node.
+
+Example:
+
+audio {
+   compatible = "qcom,apq8096-sndcard";
+   qcom,model = "DB820c";
+   com,audio-routing = "RX_BIAS", "MCLK";
+
+   mm1-dai-link {
+   link-name = "MultiMedia1";
+   cpu {
+   sound-dai = < MSM_FRONTEND_DAI_MULTIMEDIA1>;
+   };
+   platform {
+   sound-dai = <>;
+   };
+   };
+
+   hdmi-dai-link {
+   link-name = "HDMI Playback";
+   cpu {
+   sound-dai = < HDMI_RX>;
+   };
+
+   platform {
+   sound-dai = <>;
+   };
+
+   codec {
+   sound-dai = < 0>;
+   };
+   };
+};
-- 
2.15.1



[PATCH v4 23/24] arm64: dts: db820c: add sound card dt entry

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a sound card entry for basic hdmi playback using adsp.

Signed-off-by: Srinivas Kandagatla 
---
 arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 34 +
 arch/arm64/boot/dts/qcom/msm8996.dtsi| 75 +++-
 2 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi 
b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
index 0be734be95f9..d69ffd042835 100644
--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
@@ -18,6 +18,8 @@
 #include "apq8096-db820c-pmic-pins.dtsi"
 #include 
 #include 
+#include 
+#include 
 
 / {
aliases {
@@ -222,6 +224,7 @@
 
core-vdda-supply = <_l12>;
core-vcc-supply = <_s4>;
+   #sound-dai-cells = <1>;
};
};
};
@@ -397,3 +400,34 @@
};
};
 };
+
+ {
+   compatible = "qcom,apq8096-sndcard";
+   qcom,model = "DB820c";
+   qcom,audio-routing =
+   "RX_BIAS", "MCLK";
+   mm1-dai-link {
+   link-name = "MultiMedia1";
+   cpu {
+   sound-dai = <  MSM_FRONTEND_DAI_MULTIMEDIA1>;
+   };
+   platform {
+   sound-dai = <>;
+   };
+   };
+
+   hdmi-dai-link {
+   link-name = "HDMI Playback";
+   cpu {
+   sound-dai = < HDMI_RX>;
+   };
+
+   platform {
+   sound-dai = <>;
+   };
+
+   codec {
+   sound-dai = < 0>;
+   };
+   };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 6e04827879c0..8fc9354e84c5 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
model = "Qualcomm Technologies, Inc. MSM8996";
@@ -1560,6 +1561,37 @@
  "ref_clk";
};
};
+
+   lpass_q6_smmu: arm,smmu-lpass_q6@160 {
+   compatible = "qcom,msm8996-smmu-v2";
+   reg = <0x160 0x2>;
+   #iommu-cells = <1>;
+power-domains = < HLOS1_VOTE_LPASS_CORE_GDSC>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ;
+
+   clocks = < GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK>,
+< GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK>;
+   clock-names = "iface", "bus";
+status = "okay";
+   };
+   };
+
+   sound: sound {
+
};
 
adsp-pil {
@@ -1583,11 +1615,52 @@
 
smd-edge {
interrupts = ;
-
label = "lpass";
qcom,ipc = < 16 8>;
qcom,smd-edge = <1>;
qcom,remote-pid = <2>;
+
+   apr {
+   compatible = "qcom,apr-v2";
+   qcom,smd-channels = "apr_audio_svc";
+   qcom,apr-dest-domain-id = ;
+
+   q6core {
+   qcom,apr-svc-name = "CORE";
+   qcom,apr-svc-id = ;
+   compatible = "qcom,q6core";
+   };
+
+   q6afe: q6afe {
+   compatible = "qcom,q6afe";
+   qcom,apr-svc-name = "AFE";
+   qcom,apr-svc-id = ;
+   q6afedai: dais {
+   #sound-dai-cells = <1>;
+   };
+   };
+
+   q6asm: q6asm {
+   compatible = "qcom,q6asm";
+   qcom,apr-svc-name = "ASM";
+   qcom,apr-svc-id = ;
+   q6asmdai: dais {
+   

[PATCH v4 23/24] arm64: dts: db820c: add sound card dt entry

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds a sound card entry for basic hdmi playback using adsp.

Signed-off-by: Srinivas Kandagatla 
---
 arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi | 34 +
 arch/arm64/boot/dts/qcom/msm8996.dtsi| 75 +++-
 2 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi 
b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
index 0be734be95f9..d69ffd042835 100644
--- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
+++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
@@ -18,6 +18,8 @@
 #include "apq8096-db820c-pmic-pins.dtsi"
 #include 
 #include 
+#include 
+#include 
 
 / {
aliases {
@@ -222,6 +224,7 @@
 
core-vdda-supply = <_l12>;
core-vcc-supply = <_s4>;
+   #sound-dai-cells = <1>;
};
};
};
@@ -397,3 +400,34 @@
};
};
 };
+
+ {
+   compatible = "qcom,apq8096-sndcard";
+   qcom,model = "DB820c";
+   qcom,audio-routing =
+   "RX_BIAS", "MCLK";
+   mm1-dai-link {
+   link-name = "MultiMedia1";
+   cpu {
+   sound-dai = <  MSM_FRONTEND_DAI_MULTIMEDIA1>;
+   };
+   platform {
+   sound-dai = <>;
+   };
+   };
+
+   hdmi-dai-link {
+   link-name = "HDMI Playback";
+   cpu {
+   sound-dai = < HDMI_RX>;
+   };
+
+   platform {
+   sound-dai = <>;
+   };
+
+   codec {
+   sound-dai = < 0>;
+   };
+   };
+};
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi 
b/arch/arm64/boot/dts/qcom/msm8996.dtsi
index 6e04827879c0..8fc9354e84c5 100644
--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi
+++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 
 / {
model = "Qualcomm Technologies, Inc. MSM8996";
@@ -1560,6 +1561,37 @@
  "ref_clk";
};
};
+
+   lpass_q6_smmu: arm,smmu-lpass_q6@160 {
+   compatible = "qcom,msm8996-smmu-v2";
+   reg = <0x160 0x2>;
+   #iommu-cells = <1>;
+power-domains = < HLOS1_VOTE_LPASS_CORE_GDSC>;
+
+   #global-interrupts = <1>;
+   interrupts = ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ,
+   ;
+
+   clocks = < GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK>,
+< GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK>;
+   clock-names = "iface", "bus";
+status = "okay";
+   };
+   };
+
+   sound: sound {
+
};
 
adsp-pil {
@@ -1583,11 +1615,52 @@
 
smd-edge {
interrupts = ;
-
label = "lpass";
qcom,ipc = < 16 8>;
qcom,smd-edge = <1>;
qcom,remote-pid = <2>;
+
+   apr {
+   compatible = "qcom,apr-v2";
+   qcom,smd-channels = "apr_audio_svc";
+   qcom,apr-dest-domain-id = ;
+
+   q6core {
+   qcom,apr-svc-name = "CORE";
+   qcom,apr-svc-id = ;
+   compatible = "qcom,q6core";
+   };
+
+   q6afe: q6afe {
+   compatible = "qcom,q6afe";
+   qcom,apr-svc-name = "AFE";
+   qcom,apr-svc-id = ;
+   q6afedai: dais {
+   #sound-dai-cells = <1>;
+   };
+   };
+
+   q6asm: q6asm {
+   compatible = "qcom,q6asm";
+   qcom,apr-svc-name = "ASM";
+   qcom,apr-svc-id = ;
+   q6asmdai: dais {
+   #sound-dai-cells = <1>;
+   

[PATCH v4 17/24] ASoC: qdsp6: q6routing: Add support to all SLIMBus Mixers

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to SLIMBus related mixers to control mux between
ASM stream and AFE port.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/qdsp6/q6routing.c | 261 +++
 1 file changed, 261 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index b72bd9045fea..c6be775167b8 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -232,6 +232,180 @@ static const struct snd_kcontrol_new 
hdmi_mixer_controls[] = {
   msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_3_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 

[PATCH v4 17/24] ASoC: qdsp6: q6routing: Add support to all SLIMBus Mixers

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to SLIMBus related mixers to control mux between
ASM stream and AFE port.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/qdsp6/q6routing.c | 261 +++
 1 file changed, 261 insertions(+)

diff --git a/sound/soc/qcom/qdsp6/q6routing.c b/sound/soc/qcom/qdsp6/q6routing.c
index b72bd9045fea..c6be775167b8 100644
--- a/sound/soc/qcom/qdsp6/q6routing.c
+++ b/sound/soc/qcom/qdsp6/q6routing.c
@@ -232,6 +232,180 @@ static const struct snd_kcontrol_new 
hdmi_mixer_controls[] = {
   msm_routing_put_audio_mixer),
 };
 
+static const struct snd_kcontrol_new slimbus_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_0_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new slimbus_1_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_1_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia2", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia3", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia4", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia5", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia6", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia7", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+   SOC_SINGLE_EXT("MultiMedia8", SLIMBUS_2_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+   msm_routing_put_audio_mixer),
+};
+
+static const struct snd_kcontrol_new slimbus_3_rx_mixer_controls[] = {
+   SOC_SINGLE_EXT("MultiMedia1", SLIMBUS_3_RX,
+   MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+   

[PATCH v4 20/24] ASoC: qdsp6: q6asm: Add q6asm dai driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to q6asm dai driver which configures Q6ASM streams
to pass pcm data.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   4 +
 sound/soc/qcom/qdsp6/Makefile|   1 +
 sound/soc/qcom/qdsp6/q6asm-dai.c | 632 +++
 3 files changed, 637 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/q6asm-dai.c

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 9b630686eb19..5bdf39f6003f 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -62,6 +62,9 @@ config SND_SOC_QDSP6_ROUTING
 config SND_SOC_QDSP6_ASM
tristate
 
+config SND_SOC_QDSP6_ASM_DAI
+   tristate
+
 config SND_SOC_QDSP6_CORE
tristate
 
@@ -74,6 +77,7 @@ config SND_SOC_QDSP6
select SND_SOC_QDSP6_ADM
select SND_SOC_QDSP6_ROUTING
select SND_SOC_QDSP6_ASM
+   select SND_SOC_QDSP6_ASM_DAI
select SND_SOC_QDSP6_CORE
help
 To add support for MSM QDSP6 Soc Audio.
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index 6a8ae698f22f..af44711eba24 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_SND_SOC_QDSP6_AFE_DAI) += q6afe-dai.o
 obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
 obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o
 obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
+obj-$(CONFIG_SND_SOC_QDSP6_ASM_DAI) += q6asm-dai.o
 obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
new file mode 100644
index ..c411070b67eb
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -0,0 +1,632 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2016, The Linux Foundation
+// Copyright (c) 2017, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "q6asm.h"
+#include "q6routing.h"
+#include "q6dsp-errno.h"
+
+#define PLAYBACK_MIN_NUM_PERIODS2
+#define PLAYBACK_MAX_NUM_PERIODS   8
+#define PLAYBACK_MAX_PERIOD_SIZE65536
+#define PLAYBACK_MIN_PERIOD_SIZE128
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 8
+#define CAPTURE_MAX_PERIOD_SIZE 4096
+#define CAPTURE_MIN_PERIOD_SIZE 320
+#define SID_MASK_DEFAULT   0xFF
+
+enum stream_state {
+   Q6ASM_STREAM_IDLE = 0,
+   Q6ASM_STREAM_STOPPED,
+   Q6ASM_STREAM_RUNNING,
+};
+
+struct q6asm_dai_rtd {
+   struct snd_pcm_substream *substream;
+   phys_addr_t phys;
+   unsigned int pcm_size;
+   unsigned int pcm_count;
+   unsigned int pcm_irq_pos;   /* IRQ position */
+   unsigned int periods;
+   uint16_t bits_per_sample;
+   uint16_t source; /* Encoding source bit mask */
+   struct audio_client *audio_client;
+   uint16_t session_id;
+   enum stream_state state;
+};
+
+struct q6asm_dai_data {
+   long long int sid;
+};
+
+static struct snd_pcm_hardware q6asm_dai_hardware_capture = {
+   .info = (SNDRV_PCM_INFO_MMAP |
+   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+   SNDRV_PCM_INFO_MMAP_VALID |
+   SNDRV_PCM_INFO_INTERLEAVED |
+   SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+   .formats =  (SNDRV_PCM_FMTBIT_S16_LE |
+   SNDRV_PCM_FMTBIT_S24_LE),
+   .rates =SNDRV_PCM_RATE_8000_48000,
+   .rate_min = 8000,
+   .rate_max = 48000,
+   .channels_min = 1,
+   .channels_max = 4,
+   .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
+   CAPTURE_MAX_PERIOD_SIZE,
+   .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+   .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+   .periods_min =  CAPTURE_MIN_NUM_PERIODS,
+   .periods_max =  CAPTURE_MAX_NUM_PERIODS,
+   .fifo_size =0,
+};
+
+static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
+   .info = (SNDRV_PCM_INFO_MMAP |
+   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+   SNDRV_PCM_INFO_MMAP_VALID |
+   SNDRV_PCM_INFO_INTERLEAVED |
+   SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+   .formats =  (SNDRV_PCM_FMTBIT_S16_LE |
+   SNDRV_PCM_FMTBIT_S24_LE),
+   .rates =SNDRV_PCM_RATE_8000_192000,
+   .rate_min = 8000,
+   .rate_max = 192000,
+   .channels_min = 1,
+   .channels_max = 8,
+   .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS *
+   

[PATCH v4 03/24] ASoC: qdsp6: q6common: Add qdsp6 helper functions

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds some common helper functions like translating dsp error
to linux error codes and channel mappings etc.

These functions are used in all the following qdsp6 drivers.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig  | 13 
 sound/soc/qcom/qdsp6/Makefile   |  1 +
 sound/soc/qcom/qdsp6/q6dsp-common.c | 66 +
 sound/soc/qcom/qdsp6/q6dsp-common.h | 24 ++
 sound/soc/qcom/qdsp6/q6dsp-errno.h  | 51 
 5 files changed, 155 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/Makefile
 create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.c
 create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.h
 create mode 100644 sound/soc/qcom/qdsp6/q6dsp-errno.h

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 8ec9a074b38b..8247ade16dbe 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -43,3 +43,16 @@ config SND_SOC_APQ8016_SBC
   Support for Qualcomm Technologies LPASS audio block in
   APQ8016 SOC-based systems.
   Say Y if you want to use audio devices on MI2S.
+
+config SND_SOC_QDSP6_COMMON
+   tristate
+
+config SND_SOC_QDSP6
+   tristate "SoC ALSA audio driver for QDSP6"
+   depends on QCOM_APR && HAS_DMA
+   select SND_SOC_QDSP6_COMMON
+   help
+To add support for MSM QDSP6 Soc Audio.
+This will enable sound soc platform specific
+audio drivers. This includes q6asm, q6adm,
+q6afe interfaces to DSP using apr.
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
new file mode 100644
index ..accebdb49306
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.c 
b/sound/soc/qcom/qdsp6/q6dsp-common.c
new file mode 100644
index ..c342a073144c
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6dsp-common.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2017, The Linux Foundation
+// Copyright (c) 2018, Linaro Limited
+
+#include "q6dsp-common.h"
+#include 
+#include 
+#include 
+#include 
+
+int q6dsp_map_channels(u8 ch_map[PCM_FORMAT_MAX_NUM_CHANNEL], int ch)
+{
+   memset(ch_map, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
+
+   switch (ch) {
+   case 1:
+   ch_map[0] = PCM_CHANNEL_FC;
+   break;
+   case 2:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   break;
+   case 3:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_FC;
+   break;
+   case 4:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_LS;
+   ch_map[3] = PCM_CHANNEL_RS;
+   break;
+   case 5:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_FC;
+   ch_map[3] = PCM_CHANNEL_LS;
+   ch_map[4] = PCM_CHANNEL_RS;
+   break;
+   case 6:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_LFE;
+   ch_map[3] = PCM_CHANNEL_FC;
+   ch_map[4] = PCM_CHANNEL_LS;
+   ch_map[5] = PCM_CHANNEL_RS;
+   break;
+   case 8:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_LFE;
+   ch_map[3] = PCM_CHANNEL_FC;
+   ch_map[4] = PCM_CHANNEL_LS;
+   ch_map[5] = PCM_CHANNEL_RS;
+   ch_map[6] = PCM_CHANNEL_LB;
+   ch_map[7] = PCM_CHANNEL_RB;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(q6dsp_map_channels);
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.h 
b/sound/soc/qcom/qdsp6/q6dsp-common.h
new file mode 100644
index ..32386f4a6432
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6dsp-common.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef __Q6DSP_COMMON_H__
+#define __Q6DSP_COMMON_H__
+
+#include 
+
+#define PCM_FORMAT_MAX_NUM_CHANNEL  8
+#define PCM_CHANNEL_NULL 0
+
+#define PCM_CHANNEL_FL1/* Front left channel. */
+#define PCM_CHANNEL_FR2/* Front right channel. */
+#define PCM_CHANNEL_FC3/* Front center channel. */
+#define PCM_CHANNEL_LS   4 /* Left surround channel. */
+#define PCM_CHANNEL_RS   5 /* Right surround channel. */
+#define PCM_CHANNEL_LFE  6 /* Low frequency effect channel. */
+#define PCM_CHANNEL_CS   7 /* Center surround channel; Rear center 

[PATCH v4 20/24] ASoC: qdsp6: q6asm: Add q6asm dai driver

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds support to q6asm dai driver which configures Q6ASM streams
to pass pcm data.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig   |   4 +
 sound/soc/qcom/qdsp6/Makefile|   1 +
 sound/soc/qcom/qdsp6/q6asm-dai.c | 632 +++
 3 files changed, 637 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/q6asm-dai.c

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 9b630686eb19..5bdf39f6003f 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -62,6 +62,9 @@ config SND_SOC_QDSP6_ROUTING
 config SND_SOC_QDSP6_ASM
tristate
 
+config SND_SOC_QDSP6_ASM_DAI
+   tristate
+
 config SND_SOC_QDSP6_CORE
tristate
 
@@ -74,6 +77,7 @@ config SND_SOC_QDSP6
select SND_SOC_QDSP6_ADM
select SND_SOC_QDSP6_ROUTING
select SND_SOC_QDSP6_ASM
+   select SND_SOC_QDSP6_ASM_DAI
select SND_SOC_QDSP6_CORE
help
 To add support for MSM QDSP6 Soc Audio.
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
index 6a8ae698f22f..af44711eba24 100644
--- a/sound/soc/qcom/qdsp6/Makefile
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -4,4 +4,5 @@ obj-$(CONFIG_SND_SOC_QDSP6_AFE_DAI) += q6afe-dai.o
 obj-$(CONFIG_SND_SOC_QDSP6_ADM) += q6adm.o
 obj-$(CONFIG_SND_SOC_QDSP6_ROUTING) += q6routing.o
 obj-$(CONFIG_SND_SOC_QDSP6_ASM) += q6asm.o
+obj-$(CONFIG_SND_SOC_QDSP6_ASM_DAI) += q6asm-dai.o
 obj-$(CONFIG_SND_SOC_QDSP6_CORE) += q6core.o
diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-dai.c
new file mode 100644
index ..c411070b67eb
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6asm-dai.c
@@ -0,0 +1,632 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2016, The Linux Foundation
+// Copyright (c) 2017, Linaro Limited
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "q6asm.h"
+#include "q6routing.h"
+#include "q6dsp-errno.h"
+
+#define PLAYBACK_MIN_NUM_PERIODS2
+#define PLAYBACK_MAX_NUM_PERIODS   8
+#define PLAYBACK_MAX_PERIOD_SIZE65536
+#define PLAYBACK_MIN_PERIOD_SIZE128
+#define CAPTURE_MIN_NUM_PERIODS 2
+#define CAPTURE_MAX_NUM_PERIODS 8
+#define CAPTURE_MAX_PERIOD_SIZE 4096
+#define CAPTURE_MIN_PERIOD_SIZE 320
+#define SID_MASK_DEFAULT   0xFF
+
+enum stream_state {
+   Q6ASM_STREAM_IDLE = 0,
+   Q6ASM_STREAM_STOPPED,
+   Q6ASM_STREAM_RUNNING,
+};
+
+struct q6asm_dai_rtd {
+   struct snd_pcm_substream *substream;
+   phys_addr_t phys;
+   unsigned int pcm_size;
+   unsigned int pcm_count;
+   unsigned int pcm_irq_pos;   /* IRQ position */
+   unsigned int periods;
+   uint16_t bits_per_sample;
+   uint16_t source; /* Encoding source bit mask */
+   struct audio_client *audio_client;
+   uint16_t session_id;
+   enum stream_state state;
+};
+
+struct q6asm_dai_data {
+   long long int sid;
+};
+
+static struct snd_pcm_hardware q6asm_dai_hardware_capture = {
+   .info = (SNDRV_PCM_INFO_MMAP |
+   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+   SNDRV_PCM_INFO_MMAP_VALID |
+   SNDRV_PCM_INFO_INTERLEAVED |
+   SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+   .formats =  (SNDRV_PCM_FMTBIT_S16_LE |
+   SNDRV_PCM_FMTBIT_S24_LE),
+   .rates =SNDRV_PCM_RATE_8000_48000,
+   .rate_min = 8000,
+   .rate_max = 48000,
+   .channels_min = 1,
+   .channels_max = 4,
+   .buffer_bytes_max = CAPTURE_MAX_NUM_PERIODS *
+   CAPTURE_MAX_PERIOD_SIZE,
+   .period_bytes_min = CAPTURE_MIN_PERIOD_SIZE,
+   .period_bytes_max = CAPTURE_MAX_PERIOD_SIZE,
+   .periods_min =  CAPTURE_MIN_NUM_PERIODS,
+   .periods_max =  CAPTURE_MAX_NUM_PERIODS,
+   .fifo_size =0,
+};
+
+static struct snd_pcm_hardware q6asm_dai_hardware_playback = {
+   .info = (SNDRV_PCM_INFO_MMAP |
+   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+   SNDRV_PCM_INFO_MMAP_VALID |
+   SNDRV_PCM_INFO_INTERLEAVED |
+   SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
+   .formats =  (SNDRV_PCM_FMTBIT_S16_LE |
+   SNDRV_PCM_FMTBIT_S24_LE),
+   .rates =SNDRV_PCM_RATE_8000_192000,
+   .rate_min = 8000,
+   .rate_max = 192000,
+   .channels_min = 1,
+   .channels_max = 8,
+   .buffer_bytes_max = (PLAYBACK_MAX_NUM_PERIODS *
+   PLAYBACK_MAX_PERIOD_SIZE),
+   

[PATCH v4 03/24] ASoC: qdsp6: q6common: Add qdsp6 helper functions

2018-03-09 Thread srinivas . kandagatla
From: Srinivas Kandagatla 

This patch adds some common helper functions like translating dsp error
to linux error codes and channel mappings etc.

These functions are used in all the following qdsp6 drivers.

Signed-off-by: Srinivas Kandagatla 
---
 sound/soc/qcom/Kconfig  | 13 
 sound/soc/qcom/qdsp6/Makefile   |  1 +
 sound/soc/qcom/qdsp6/q6dsp-common.c | 66 +
 sound/soc/qcom/qdsp6/q6dsp-common.h | 24 ++
 sound/soc/qcom/qdsp6/q6dsp-errno.h  | 51 
 5 files changed, 155 insertions(+)
 create mode 100644 sound/soc/qcom/qdsp6/Makefile
 create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.c
 create mode 100644 sound/soc/qcom/qdsp6/q6dsp-common.h
 create mode 100644 sound/soc/qcom/qdsp6/q6dsp-errno.h

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 8ec9a074b38b..8247ade16dbe 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -43,3 +43,16 @@ config SND_SOC_APQ8016_SBC
   Support for Qualcomm Technologies LPASS audio block in
   APQ8016 SOC-based systems.
   Say Y if you want to use audio devices on MI2S.
+
+config SND_SOC_QDSP6_COMMON
+   tristate
+
+config SND_SOC_QDSP6
+   tristate "SoC ALSA audio driver for QDSP6"
+   depends on QCOM_APR && HAS_DMA
+   select SND_SOC_QDSP6_COMMON
+   help
+To add support for MSM QDSP6 Soc Audio.
+This will enable sound soc platform specific
+audio drivers. This includes q6asm, q6adm,
+q6afe interfaces to DSP using apr.
diff --git a/sound/soc/qcom/qdsp6/Makefile b/sound/soc/qcom/qdsp6/Makefile
new file mode 100644
index ..accebdb49306
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SND_SOC_QDSP6_COMMON) += q6dsp-common.o
diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.c 
b/sound/soc/qcom/qdsp6/q6dsp-common.c
new file mode 100644
index ..c342a073144c
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6dsp-common.c
@@ -0,0 +1,66 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2011-2017, The Linux Foundation
+// Copyright (c) 2018, Linaro Limited
+
+#include "q6dsp-common.h"
+#include 
+#include 
+#include 
+#include 
+
+int q6dsp_map_channels(u8 ch_map[PCM_FORMAT_MAX_NUM_CHANNEL], int ch)
+{
+   memset(ch_map, 0, PCM_FORMAT_MAX_NUM_CHANNEL);
+
+   switch (ch) {
+   case 1:
+   ch_map[0] = PCM_CHANNEL_FC;
+   break;
+   case 2:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   break;
+   case 3:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_FC;
+   break;
+   case 4:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_LS;
+   ch_map[3] = PCM_CHANNEL_RS;
+   break;
+   case 5:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_FC;
+   ch_map[3] = PCM_CHANNEL_LS;
+   ch_map[4] = PCM_CHANNEL_RS;
+   break;
+   case 6:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_LFE;
+   ch_map[3] = PCM_CHANNEL_FC;
+   ch_map[4] = PCM_CHANNEL_LS;
+   ch_map[5] = PCM_CHANNEL_RS;
+   break;
+   case 8:
+   ch_map[0] = PCM_CHANNEL_FL;
+   ch_map[1] = PCM_CHANNEL_FR;
+   ch_map[2] = PCM_CHANNEL_LFE;
+   ch_map[3] = PCM_CHANNEL_FC;
+   ch_map[4] = PCM_CHANNEL_LS;
+   ch_map[5] = PCM_CHANNEL_RS;
+   ch_map[6] = PCM_CHANNEL_LB;
+   ch_map[7] = PCM_CHANNEL_RB;
+   break;
+   default:
+   return -EINVAL;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(q6dsp_map_channels);
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/qcom/qdsp6/q6dsp-common.h 
b/sound/soc/qcom/qdsp6/q6dsp-common.h
new file mode 100644
index ..32386f4a6432
--- /dev/null
+++ b/sound/soc/qcom/qdsp6/q6dsp-common.h
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#ifndef __Q6DSP_COMMON_H__
+#define __Q6DSP_COMMON_H__
+
+#include 
+
+#define PCM_FORMAT_MAX_NUM_CHANNEL  8
+#define PCM_CHANNEL_NULL 0
+
+#define PCM_CHANNEL_FL1/* Front left channel. */
+#define PCM_CHANNEL_FR2/* Front right channel. */
+#define PCM_CHANNEL_FC3/* Front center channel. */
+#define PCM_CHANNEL_LS   4 /* Left surround channel. */
+#define PCM_CHANNEL_RS   5 /* Right surround channel. */
+#define PCM_CHANNEL_LFE  6 /* Low frequency effect channel. */
+#define PCM_CHANNEL_CS   7 /* Center surround channel; Rear center ch */
+#define PCM_CHANNEL_LB   8 /* Left back channel; 

[PATCH] f2fs: align memory boundary for bitops

2018-03-09 Thread Jaegeuk Kim
For example, in arm64, free_nid_bitmap should be aligned to word size in order
to use bit operations.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/f2fs.h  |  2 +-
 fs/f2fs/node.c  | 20 +---
 include/linux/f2fs_fs.h |  4 
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 88f2b420de27..641b4b98d373 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -766,7 +766,7 @@ struct f2fs_nm_info {
unsigned int nid_cnt[MAX_NID_STATE];/* the number of free node id */
spinlock_t nid_list_lock;   /* protect nid lists ops */
struct mutex build_lock;/* lock for build free nids */
-   unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE];
+   unsigned char **free_nid_bitmap;
unsigned char *nat_block_bitmap;
unsigned short *free_nid_count; /* free nid count of NAT block */
 
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index b86e2b15b619..f7886b46478d 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2708,12 +2708,20 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
 static int init_free_nid_cache(struct f2fs_sb_info *sbi)
 {
struct f2fs_nm_info *nm_i = NM_I(sbi);
+   int i;
 
-   nm_i->free_nid_bitmap = f2fs_kvzalloc(sbi, nm_i->nat_blocks *
-   NAT_ENTRY_BITMAP_SIZE, GFP_KERNEL);
+   nm_i->free_nid_bitmap = f2fs_kzalloc(sbi, nm_i->nat_blocks *
+   sizeof(unsigned char *), GFP_KERNEL);
if (!nm_i->free_nid_bitmap)
return -ENOMEM;
 
+   for (i = 0; i < nm_i->nat_blocks; i++) {
+   nm_i->free_nid_bitmap[i] = f2fs_kvzalloc(sbi,
+   NAT_ENTRY_BITMAP_SIZE_ALIGNED, GFP_KERNEL);
+   if (!nm_i->free_nid_bitmap)
+   return -ENOMEM;
+   }
+
nm_i->nat_block_bitmap = f2fs_kvzalloc(sbi, nm_i->nat_blocks / 8,
GFP_KERNEL);
if (!nm_i->nat_block_bitmap)
@@ -2804,7 +2812,13 @@ void destroy_node_manager(struct f2fs_sb_info *sbi)
up_write(_i->nat_tree_lock);
 
kvfree(nm_i->nat_block_bitmap);
-   kvfree(nm_i->free_nid_bitmap);
+   if (nm_i->free_nid_bitmap) {
+   int i;
+
+   for (i = 0; i < nm_i->nat_blocks; i++)
+   kvfree(nm_i->free_nid_bitmap[i]);
+   kfree(nm_i->free_nid_bitmap);
+   }
kvfree(nm_i->free_nid_count);
 
kfree(nm_i->nat_bitmap);
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 124787e8db58..aa5db8b5521a 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -305,6 +305,10 @@ struct f2fs_node {
  */
 #define NAT_ENTRY_PER_BLOCK (PAGE_SIZE / sizeof(struct f2fs_nat_entry))
 #define NAT_ENTRY_BITMAP_SIZE  ((NAT_ENTRY_PER_BLOCK + 7) / 8)
+#define NAT_ENTRY_BITMAP_SIZE_ALIGNED  \
+   ((NAT_ENTRY_BITMAP_SIZE + BITS_PER_LONG - 1) /  \
+   BITS_PER_LONG * BITS_PER_LONG)
+
 
 struct f2fs_nat_entry {
__u8 version;   /* latest version of cached nat entry */
-- 
2.15.0.531.g2ccb3012c9-goog



[PATCH] f2fs: align memory boundary for bitops

2018-03-09 Thread Jaegeuk Kim
For example, in arm64, free_nid_bitmap should be aligned to word size in order
to use bit operations.

Signed-off-by: Jaegeuk Kim 
---
 fs/f2fs/f2fs.h  |  2 +-
 fs/f2fs/node.c  | 20 +---
 include/linux/f2fs_fs.h |  4 
 3 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 88f2b420de27..641b4b98d373 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -766,7 +766,7 @@ struct f2fs_nm_info {
unsigned int nid_cnt[MAX_NID_STATE];/* the number of free node id */
spinlock_t nid_list_lock;   /* protect nid lists ops */
struct mutex build_lock;/* lock for build free nids */
-   unsigned char (*free_nid_bitmap)[NAT_ENTRY_BITMAP_SIZE];
+   unsigned char **free_nid_bitmap;
unsigned char *nat_block_bitmap;
unsigned short *free_nid_count; /* free nid count of NAT block */
 
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index b86e2b15b619..f7886b46478d 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2708,12 +2708,20 @@ static int init_node_manager(struct f2fs_sb_info *sbi)
 static int init_free_nid_cache(struct f2fs_sb_info *sbi)
 {
struct f2fs_nm_info *nm_i = NM_I(sbi);
+   int i;
 
-   nm_i->free_nid_bitmap = f2fs_kvzalloc(sbi, nm_i->nat_blocks *
-   NAT_ENTRY_BITMAP_SIZE, GFP_KERNEL);
+   nm_i->free_nid_bitmap = f2fs_kzalloc(sbi, nm_i->nat_blocks *
+   sizeof(unsigned char *), GFP_KERNEL);
if (!nm_i->free_nid_bitmap)
return -ENOMEM;
 
+   for (i = 0; i < nm_i->nat_blocks; i++) {
+   nm_i->free_nid_bitmap[i] = f2fs_kvzalloc(sbi,
+   NAT_ENTRY_BITMAP_SIZE_ALIGNED, GFP_KERNEL);
+   if (!nm_i->free_nid_bitmap)
+   return -ENOMEM;
+   }
+
nm_i->nat_block_bitmap = f2fs_kvzalloc(sbi, nm_i->nat_blocks / 8,
GFP_KERNEL);
if (!nm_i->nat_block_bitmap)
@@ -2804,7 +2812,13 @@ void destroy_node_manager(struct f2fs_sb_info *sbi)
up_write(_i->nat_tree_lock);
 
kvfree(nm_i->nat_block_bitmap);
-   kvfree(nm_i->free_nid_bitmap);
+   if (nm_i->free_nid_bitmap) {
+   int i;
+
+   for (i = 0; i < nm_i->nat_blocks; i++)
+   kvfree(nm_i->free_nid_bitmap[i]);
+   kfree(nm_i->free_nid_bitmap);
+   }
kvfree(nm_i->free_nid_count);
 
kfree(nm_i->nat_bitmap);
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 124787e8db58..aa5db8b5521a 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -305,6 +305,10 @@ struct f2fs_node {
  */
 #define NAT_ENTRY_PER_BLOCK (PAGE_SIZE / sizeof(struct f2fs_nat_entry))
 #define NAT_ENTRY_BITMAP_SIZE  ((NAT_ENTRY_PER_BLOCK + 7) / 8)
+#define NAT_ENTRY_BITMAP_SIZE_ALIGNED  \
+   ((NAT_ENTRY_BITMAP_SIZE + BITS_PER_LONG - 1) /  \
+   BITS_PER_LONG * BITS_PER_LONG)
+
 
 struct f2fs_nat_entry {
__u8 version;   /* latest version of cached nat entry */
-- 
2.15.0.531.g2ccb3012c9-goog



Re: [PATCH net-next] modules: allow modprobe load regular elf binaries

2018-03-09 Thread Alexei Starovoitov

On 3/9/18 11:37 AM, Andy Lutomirski wrote:

On Fri, Mar 9, 2018 at 6:55 PM, David Miller  wrote:

From: Alexei Starovoitov 
Date: Fri, 9 Mar 2018 10:50:49 -0800


On 3/9/18 10:23 AM, Andy Lutomirski wrote:

It might not be totally crazy to back it by tmpfs.


interesting. how do you propose to do it?
Something like:
- create /umh_module_tempxxx dir
- mount tmpfs there
- copy elf into it and exec it?


I think the idea is that it's an internal tmpfs mount that only
the kernel has access too.


That's what I was imagining.  There's precedent.  For example, there's
a very short piece of code that does it in
drivers/gpu/drm/i915/i915_gemfs.c.


I can do "monkey see monkey do" approach which will look like:
type = get_fs_type("tmpfs");
fs = kern_mount(type);

/* for each request_umh("foo") */
file = shmem_file_setup_with_mnt(fs, "umh_foo");
do {
  pagecache_write_begin(file,...);
  memcpy()
  pagecache_write_end();
} while (umh_elf_size);
do_execve_file(file);
fput(file);

while keeping fs mounted forever?
is there better way?



Re: [PATCH net-next] modules: allow modprobe load regular elf binaries

2018-03-09 Thread Alexei Starovoitov

On 3/9/18 11:37 AM, Andy Lutomirski wrote:

On Fri, Mar 9, 2018 at 6:55 PM, David Miller  wrote:

From: Alexei Starovoitov 
Date: Fri, 9 Mar 2018 10:50:49 -0800


On 3/9/18 10:23 AM, Andy Lutomirski wrote:

It might not be totally crazy to back it by tmpfs.


interesting. how do you propose to do it?
Something like:
- create /umh_module_tempxxx dir
- mount tmpfs there
- copy elf into it and exec it?


I think the idea is that it's an internal tmpfs mount that only
the kernel has access too.


That's what I was imagining.  There's precedent.  For example, there's
a very short piece of code that does it in
drivers/gpu/drm/i915/i915_gemfs.c.


I can do "monkey see monkey do" approach which will look like:
type = get_fs_type("tmpfs");
fs = kern_mount(type);

/* for each request_umh("foo") */
file = shmem_file_setup_with_mnt(fs, "umh_foo");
do {
  pagecache_write_begin(file,...);
  memcpy()
  pagecache_write_end();
} while (umh_elf_size);
do_execve_file(file);
fput(file);

while keeping fs mounted forever?
is there better way?



Re: [PATCH v3] kernel.h: Skip single-eval logic on literals in min()/max()

2018-03-09 Thread Kees Cook
On Fri, Mar 9, 2018 at 5:30 PM, Kees Cook  wrote:
> --
> Kees Cook
> Pixel SecurityOn
> [...]

WTF, gmail just blasted HTML into my explicitly plain-text email?! Apologies...

-- 
Kees Cook
Pixel SecurityOn
Fri, Mar 9, 2018 at 5:30 PM, Kees Cook mailto:keesc...@chromium.org;
target="_blank">keesc...@chromium.org
wrote:On
Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds
mailto:torva...@linux-foundation.org;>torva...@linux-foundation.org
wrote:
 On Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton mailto:a...@linux-foundation.org;>a...@linux-foundation.org
wrote:

 I wonder which gcc versions actually accept Kees's addition.

Ah, my old nemesis, gcc 4.4.4. *sob*

 Note that we already do have this pattern, as seen by:

 git grep -2 __builtin_choose_expr | grep -2
__builtin_constant_p

 which show drivers/pinctrl/intel/pinctrl-intel.h, so the pattern
 already exists current kernels and _works_ - it apparently just
 doesn't work in slightly more complicated cases.

Fun. Yeah, so all the PIN_GROUP() callers have either a literal or an
array name for that argument, so the argument to
__builtin_constant_p() isn't complex.

git grep '\bPIN_GROUP\b' | egrep -v '(1|2|3|true|false)\)'

 It's one reason why I wondered if simplifying the expression to have
 just that single __builtin_constant_p() might not end up working..

Yeah, it seems like it doesn't bail out as "false" for complex
expressions given to __builtin_constant_p().

If no magic solution, then which of these?

- go back to my original "multi-eval max only for constants" macro (meh)
- add gcc version checks around this and similarly for -Wvla in the
future (eww)
- raise gcc version (yikes)

-Kees

--
Kees Cook
Pixel Securitydiv class="gmail_extra"brdiv
class="gmail_quote"On
Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds span
dir="ltr"lt;a
href="mailto:mailto:torva...@linux-foundation.org;>torvalds@linux-foundation.org"
target="_blank"mailto:torva...@linux-foundation.org;>torvalds@linux-foundation.org/agt;/span
wrote:brblockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex"span
class=""On
Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton lt;a
href="mailto:mailto:a...@linux-foundation.org;>akpm@linux-foundation.org"mailto:a...@linux-foundation.org;>akpm@linux-foundation.org/agt;
wrote:br
gt;br
gt; I wonder which gcc versions actually accept Kees's
addition.br
br
/spanNote that we already do have this pattern, as seen
by:br
br
nbsp; git grep -2nbsp; __builtin_choose_expr | grep -2
__builtin_constant_pbr
br
which show drivers/pinctrl/intel/pinctrl-wbrintel.h, so
the patternbr
already exists current kernels and _works_ - it apparently justbr
doesn't work in slightly more complicated cases.br
br
It's one reason why I wondered if simplifying the expression to
havebr
just that single __builtin_constant_p() might not end up working..br
span
class="HOEnZb"font color="#88"br
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;
nbsp; Linusbr
/font/span/blockquote/divbrbr
clear="all"divbr/div--
brdiv class="gmail_signature"
data-smartmail="gmail_signature"Kees
CookbrPixel Security/div
/div
--
Kees
CookPixel Security



Re: [PATCH v3] kernel.h: Skip single-eval logic on literals in min()/max()

2018-03-09 Thread Kees Cook
On Fri, Mar 9, 2018 at 5:30 PM, Kees Cook  wrote:
> --
> Kees Cook
> Pixel SecurityOn
> [...]

WTF, gmail just blasted HTML into my explicitly plain-text email?! Apologies...

-- 
Kees Cook
Pixel SecurityOn
Fri, Mar 9, 2018 at 5:30 PM, Kees Cook mailto:keesc...@chromium.org;
target="_blank">keesc...@chromium.org
wrote:On
Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds
mailto:torva...@linux-foundation.org;>torva...@linux-foundation.org
wrote:
 On Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton mailto:a...@linux-foundation.org;>a...@linux-foundation.org
wrote:

 I wonder which gcc versions actually accept Kees's addition.

Ah, my old nemesis, gcc 4.4.4. *sob*

 Note that we already do have this pattern, as seen by:

 git grep -2 __builtin_choose_expr | grep -2
__builtin_constant_p

 which show drivers/pinctrl/intel/pinctrl-intel.h, so the pattern
 already exists current kernels and _works_ - it apparently just
 doesn't work in slightly more complicated cases.

Fun. Yeah, so all the PIN_GROUP() callers have either a literal or an
array name for that argument, so the argument to
__builtin_constant_p() isn't complex.

git grep '\bPIN_GROUP\b' | egrep -v '(1|2|3|true|false)\)'

 It's one reason why I wondered if simplifying the expression to have
 just that single __builtin_constant_p() might not end up working..

Yeah, it seems like it doesn't bail out as "false" for complex
expressions given to __builtin_constant_p().

If no magic solution, then which of these?

- go back to my original "multi-eval max only for constants" macro (meh)
- add gcc version checks around this and similarly for -Wvla in the
future (eww)
- raise gcc version (yikes)

-Kees

--
Kees Cook
Pixel Securitydiv class="gmail_extra"brdiv
class="gmail_quote"On
Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds span
dir="ltr"lt;a
href="mailto:mailto:torva...@linux-foundation.org;>torvalds@linux-foundation.org"
target="_blank"mailto:torva...@linux-foundation.org;>torvalds@linux-foundation.org/agt;/span
wrote:brblockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex"span
class=""On
Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton lt;a
href="mailto:mailto:a...@linux-foundation.org;>akpm@linux-foundation.org"mailto:a...@linux-foundation.org;>akpm@linux-foundation.org/agt;
wrote:br
gt;br
gt; I wonder which gcc versions actually accept Kees's
addition.br
br
/spanNote that we already do have this pattern, as seen
by:br
br
nbsp; git grep -2nbsp; __builtin_choose_expr | grep -2
__builtin_constant_pbr
br
which show drivers/pinctrl/intel/pinctrl-wbrintel.h, so
the patternbr
already exists current kernels and _works_ - it apparently justbr
doesn't work in slightly more complicated cases.br
br
It's one reason why I wondered if simplifying the expression to
havebr
just that single __builtin_constant_p() might not end up working..br
span
class="HOEnZb"font color="#88"br
nbsp; nbsp; nbsp; nbsp; nbsp; nbsp;
nbsp; Linusbr
/font/span/blockquote/divbrbr
clear="all"divbr/div--
brdiv class="gmail_signature"
data-smartmail="gmail_signature"Kees
CookbrPixel Security/div
/div
--
Kees
CookPixel Security



Re: [PATCH v3] kernel.h: Skip single-eval logic on literals in min()/max()

2018-03-09 Thread Kees Cook
On Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds
 wrote:
> On Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton  
> wrote:
>>
>> I wonder which gcc versions actually accept Kees's addition.

Ah, my old nemesis, gcc 4.4.4. *sob*

> Note that we already do have this pattern, as seen by:
>
>   git grep -2  __builtin_choose_expr | grep -2 __builtin_constant_p
>
> which show drivers/pinctrl/intel/pinctrl-intel.h, so the pattern
> already exists current kernels and _works_ - it apparently just
> doesn't work in slightly more complicated cases.

Fun. Yeah, so all the PIN_GROUP() callers have either a literal or an
array name for that argument, so the argument to
__builtin_constant_p() isn't complex.

git grep '\bPIN_GROUP\b' | egrep -v '(1|2|3|true|false)\)'

> It's one reason why I wondered if simplifying the expression to have
> just that single __builtin_constant_p() might not end up working..

Yeah, it seems like it doesn't bail out as "false" for complex
expressions given to __builtin_constant_p().

If no magic solution, then which of these?

- go back to my original "multi-eval max only for constants" macro (meh)
- add gcc version checks around this and similarly for -Wvla in the future (eww)
- raise gcc version (yikes)

-Kees

-- 
Kees Cook
Pixel SecurityOn
Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds mailto:torva...@linux-foundation.org;
target="_blank">torva...@linux-foundation.org
wrote:On
Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton mailto:a...@linux-foundation.org;>a...@linux-foundation.org
wrote:

 I wonder which gcc versions actually accept Kees's addition.

Note that we already do have this pattern, as seen by:

 git grep -2 __builtin_choose_expr | grep -2
__builtin_constant_p

which show drivers/pinctrl/intel/pinctrl-intel.h, so the pattern
already exists current kernels and _works_ - it apparently just
doesn't work in slightly more complicated cases.

It's one reason why I wondered if simplifying the expression to have
just that single __builtin_constant_p() might not end up working..

   Linus
--
Kees
CookPixel Security



Re: [PATCH v3] kernel.h: Skip single-eval logic on literals in min()/max()

2018-03-09 Thread Kees Cook
On Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds
 wrote:
> On Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton  
> wrote:
>>
>> I wonder which gcc versions actually accept Kees's addition.

Ah, my old nemesis, gcc 4.4.4. *sob*

> Note that we already do have this pattern, as seen by:
>
>   git grep -2  __builtin_choose_expr | grep -2 __builtin_constant_p
>
> which show drivers/pinctrl/intel/pinctrl-intel.h, so the pattern
> already exists current kernels and _works_ - it apparently just
> doesn't work in slightly more complicated cases.

Fun. Yeah, so all the PIN_GROUP() callers have either a literal or an
array name for that argument, so the argument to
__builtin_constant_p() isn't complex.

git grep '\bPIN_GROUP\b' | egrep -v '(1|2|3|true|false)\)'

> It's one reason why I wondered if simplifying the expression to have
> just that single __builtin_constant_p() might not end up working..

Yeah, it seems like it doesn't bail out as "false" for complex
expressions given to __builtin_constant_p().

If no magic solution, then which of these?

- go back to my original "multi-eval max only for constants" macro (meh)
- add gcc version checks around this and similarly for -Wvla in the future (eww)
- raise gcc version (yikes)

-Kees

-- 
Kees Cook
Pixel SecurityOn
Fri, Mar 9, 2018 at 4:38 PM, Linus Torvalds mailto:torva...@linux-foundation.org;
target="_blank">torva...@linux-foundation.org
wrote:On
Fri, Mar 9, 2018 at 4:32 PM, Andrew Morton mailto:a...@linux-foundation.org;>a...@linux-foundation.org
wrote:

 I wonder which gcc versions actually accept Kees's addition.

Note that we already do have this pattern, as seen by:

 git grep -2 __builtin_choose_expr | grep -2
__builtin_constant_p

which show drivers/pinctrl/intel/pinctrl-intel.h, so the pattern
already exists current kernels and _works_ - it apparently just
doesn't work in slightly more complicated cases.

It's one reason why I wondered if simplifying the expression to have
just that single __builtin_constant_p() might not end up working..

   Linus
--
Kees
CookPixel Security



Re: [PATCH 1/2] of: unittest: remove unneeded local return value variables

2018-03-09 Thread Frank Rowand
On 03/09/18 16:02, Rob Herring wrote:
> On Thu, Mar 08, 2018 at 02:39:04PM -0800, frowand.l...@gmail.com wrote:
>> From: Frank Rowand 
>>
>> A common pattern in many unittest functions is to save the return
>> value of a function in a local variable, then test the value of
>> the local variable, without using that return value for any further
>> purpose.  Remove the local return value variable for these cases.
>>
>> A second common pattern is:
>>
>>ret = some_test_function(many, parameters, ...);
>>if (unittest(ret == 0, "error message format", ...))
>>   return;
>>
>> This pattern is more clear when the local variable 'ret' is used, due
>> to the long lines caused by the parameters to the test function and
>> the long format and data parameters of unittest().  The local
>> variable is retained in these cases.
>>
>> Signed-off-by: Frank Rowand 
>> ---
>>  drivers/of/unittest.c | 89 
>> ++-
>>  1 file changed, 24 insertions(+), 65 deletions(-)
> 
> Doesn't apply. What's it based on?
> 
> Rob
> 

Sorry, I guess I should have mentioned that.

Based on top of of_overlay_fdt_apply() v7 for 4.17.

It applies with or without Dan's "[PATCH] of: unittest: fix
an error test in of_unittest_overlay_8()", which made me notice
the common pattern.

-Frank


Re: [PATCH 1/2] of: unittest: remove unneeded local return value variables

2018-03-09 Thread Frank Rowand
On 03/09/18 16:02, Rob Herring wrote:
> On Thu, Mar 08, 2018 at 02:39:04PM -0800, frowand.l...@gmail.com wrote:
>> From: Frank Rowand 
>>
>> A common pattern in many unittest functions is to save the return
>> value of a function in a local variable, then test the value of
>> the local variable, without using that return value for any further
>> purpose.  Remove the local return value variable for these cases.
>>
>> A second common pattern is:
>>
>>ret = some_test_function(many, parameters, ...);
>>if (unittest(ret == 0, "error message format", ...))
>>   return;
>>
>> This pattern is more clear when the local variable 'ret' is used, due
>> to the long lines caused by the parameters to the test function and
>> the long format and data parameters of unittest().  The local
>> variable is retained in these cases.
>>
>> Signed-off-by: Frank Rowand 
>> ---
>>  drivers/of/unittest.c | 89 
>> ++-
>>  1 file changed, 24 insertions(+), 65 deletions(-)
> 
> Doesn't apply. What's it based on?
> 
> Rob
> 

Sorry, I guess I should have mentioned that.

Based on top of of_overlay_fdt_apply() v7 for 4.17.

It applies with or without Dan's "[PATCH] of: unittest: fix
an error test in of_unittest_overlay_8()", which made me notice
the common pattern.

-Frank


Re: [PATCH v5 1/3] of: cache phandle nodes to reduce cost of of_find_node_by_phandle()

2018-03-09 Thread Frank Rowand
On 03/09/18 15:03, Rob Herring wrote:
> On Sun, Mar 04, 2018 at 04:14:47PM -0800, frowand.l...@gmail.com wrote:
>> From: Frank Rowand 
>>
>> Create a cache of the nodes that contain a phandle property.  Use this
>> cache to find the node for a given phandle value instead of scanning
>> the devicetree to find the node.  If the phandle value is not found
>> in the cache, of_find_node_by_phandle() will fall back to the tree
>> scan algorithm.
>>
>> The cache is initialized in of_core_init().
>>
>> The cache is freed via a late_initcall_sync() if modules are not
>> enabled.
>>
>> If the devicetree is created by the dtc compiler, with all phandle
>> property values auto generated, then the size required by the cache
>> could be 4 * (1 + number of phandles) bytes.  This results in an O(1)
>> node lookup cost for a given phandle value.  Due to a concern that the
>> phandle property values might not be consistent with what is generated
>> by the dtc compiler, a mask has been added to the cache lookup algorithm.
>> To maintain the O(1) node lookup cost, the size of the cache has been
>> increased by rounding the number of entries up to the next power of
>> two.
>>
>> The overhead of finding the devicetree node containing a given phandle
>> value has been noted by several people in the recent past, in some cases
>> with a patch to add a hashed index of devicetree nodes, based on the
>> phandle value of the node.  One concern with this approach is the extra
>> space added to each node.  This patch takes advantage of the phandle
>> property values auto generated by the dtc compiler, which begin with
>> one and monotonically increase by one, resulting in a range of 1..n
>> for n phandle values.  This implementation should also provide a good
>> reduction of overhead for any range of phandle values that are mostly
>> in a monotonic range.
>>
>> Performance measurements by Chintan Pandya 
>> of several implementations of patches that are similar to this one
>> suggest an expected reduction of boot time by ~400ms for his test
>> system.  If the cache size was decreased to 64 entries, the boot
>> time was reduced by ~340 ms.  The measurements were on a 4.9.73 kernel
>> for arch/arm64/boot/dts/qcom/sda670-mtp.dts, contains 2371 nodes and
>> 814 phandle values.
>>
>> Reported-by: Chintan Pandya 
>> Signed-off-by: Frank Rowand 
>> ---
> 
> I've applied this one, but not the others.
> 
> Rob
> 

Thank you.  I'll let the other two disappear into a distant memory.

-Frank


Re: [PATCH v5 1/3] of: cache phandle nodes to reduce cost of of_find_node_by_phandle()

2018-03-09 Thread Frank Rowand
On 03/09/18 15:03, Rob Herring wrote:
> On Sun, Mar 04, 2018 at 04:14:47PM -0800, frowand.l...@gmail.com wrote:
>> From: Frank Rowand 
>>
>> Create a cache of the nodes that contain a phandle property.  Use this
>> cache to find the node for a given phandle value instead of scanning
>> the devicetree to find the node.  If the phandle value is not found
>> in the cache, of_find_node_by_phandle() will fall back to the tree
>> scan algorithm.
>>
>> The cache is initialized in of_core_init().
>>
>> The cache is freed via a late_initcall_sync() if modules are not
>> enabled.
>>
>> If the devicetree is created by the dtc compiler, with all phandle
>> property values auto generated, then the size required by the cache
>> could be 4 * (1 + number of phandles) bytes.  This results in an O(1)
>> node lookup cost for a given phandle value.  Due to a concern that the
>> phandle property values might not be consistent with what is generated
>> by the dtc compiler, a mask has been added to the cache lookup algorithm.
>> To maintain the O(1) node lookup cost, the size of the cache has been
>> increased by rounding the number of entries up to the next power of
>> two.
>>
>> The overhead of finding the devicetree node containing a given phandle
>> value has been noted by several people in the recent past, in some cases
>> with a patch to add a hashed index of devicetree nodes, based on the
>> phandle value of the node.  One concern with this approach is the extra
>> space added to each node.  This patch takes advantage of the phandle
>> property values auto generated by the dtc compiler, which begin with
>> one and monotonically increase by one, resulting in a range of 1..n
>> for n phandle values.  This implementation should also provide a good
>> reduction of overhead for any range of phandle values that are mostly
>> in a monotonic range.
>>
>> Performance measurements by Chintan Pandya 
>> of several implementations of patches that are similar to this one
>> suggest an expected reduction of boot time by ~400ms for his test
>> system.  If the cache size was decreased to 64 entries, the boot
>> time was reduced by ~340 ms.  The measurements were on a 4.9.73 kernel
>> for arch/arm64/boot/dts/qcom/sda670-mtp.dts, contains 2371 nodes and
>> 814 phandle values.
>>
>> Reported-by: Chintan Pandya 
>> Signed-off-by: Frank Rowand 
>> ---
> 
> I've applied this one, but not the others.
> 
> Rob
> 

Thank you.  I'll let the other two disappear into a distant memory.

-Frank


Re: [PATCH 1/2] x86/mm: Give each mm a unique ID

2018-03-09 Thread Greg Kroah-Hartman
On Fri, Mar 09, 2018 at 05:04:39PM -0800, Tim Chen wrote:
> On 03/08/2018 10:23 AM, Tim Chen wrote:
> > On 03/07/2018 09:30 AM, Greg Kroah-Hartman wrote:
> >> On Fri, Mar 02, 2018 at 01:32:09PM -0800, Tim Chen wrote:
> >>> From: Andy Lutomirski 
> >>> commit: f39681ed0f48498b80455095376f11535feea332
> >>>
> >>> This adds a new variable to mmu_context_t: ctx_id.
> >>> ctx_id uniquely identifies the mm_struct and will never be reused.
> >>>
> >>> Signed-off-by: Andy Lutomirski 
> >>> Reviewed-by: Nadav Amit 
> >>> Reviewed-by: Thomas Gleixner 
> >>> Cc: Andrew Morton 
> >>> Cc: Arjan van de Ven 
> >>> Cc: Borislav Petkov 
> >>> Cc: Dave Hansen 
> >>> Cc: Linus Torvalds 
> >>> Cc: Mel Gorman 
> >>> Cc: Peter Zijlstra 
> >>> Cc: Rik van Riel 
> >>> Cc: linux...@kvack.org
> >>> Link: 
> >>> http://lkml.kernel.org/r/413a91c24dab3ed0caa5f4e4d017d87b0857f920.1498751203.git.l...@kernel.org
> >>> Signed-off-by: Ingo Molnar 
> >>> Signed-off-by: Tim Chen 
> >>> ---
> >>>  arch/x86/include/asm/mmu.h | 15 +--
> >>>  arch/x86/include/asm/mmu_context.h |  5 +
> >>>  arch/x86/mm/tlb.c  |  2 ++
> >>>  3 files changed, 20 insertions(+), 2 deletions(-)
> >>>
> >>
> >> Does not apply to 4.4.y :(
> >>
> >> Can you provide a working backport for that tree?
> >>
> > 
> > Okay. Will do.  Thanks.
> > 
> 
> 
> Greg,
> 
> I actually found that there are a number of dependent IBPB related patches 
> that haven't been
> backported yet to 4.4:
> 
> x86/cpufeatures: Add AMD feature bits for Speculation Control
> (cherry picked from commit 5d10cbc91d9eb5537998b65608441b592eec65e7)
> 
> x86/msr: Add definitions for new speculation control MSRs
> (cherry picked from commit 1e340c60d0dd3ae07b5bedc16a0469c14b9f3410)
> 
> x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) 
> support
> (cherry picked from commit 20ffa1caecca4db8f79fe665acdeaa5af815a24d)
> 
> x86/cpufeatures: Clean up Spectre v2 related CPUID flags
> (cherry picked from commit 2961298efe1ea1b6fc0d7ee8b76018fa6c0bcef2)
> 
> And probably and a few more.
> You have plans to backport these patches?

I don't, but I think someone from Amazon was looking into it, but I
haven't heard from them in a few weeks.  I'll gladly take patches if you
have them, or at the worse case, a list like above of the git commits
that are missing.

thanks,

greg k-h


Re: [PATCH 1/2] x86/mm: Give each mm a unique ID

2018-03-09 Thread Greg Kroah-Hartman
On Fri, Mar 09, 2018 at 05:04:39PM -0800, Tim Chen wrote:
> On 03/08/2018 10:23 AM, Tim Chen wrote:
> > On 03/07/2018 09:30 AM, Greg Kroah-Hartman wrote:
> >> On Fri, Mar 02, 2018 at 01:32:09PM -0800, Tim Chen wrote:
> >>> From: Andy Lutomirski 
> >>> commit: f39681ed0f48498b80455095376f11535feea332
> >>>
> >>> This adds a new variable to mmu_context_t: ctx_id.
> >>> ctx_id uniquely identifies the mm_struct and will never be reused.
> >>>
> >>> Signed-off-by: Andy Lutomirski 
> >>> Reviewed-by: Nadav Amit 
> >>> Reviewed-by: Thomas Gleixner 
> >>> Cc: Andrew Morton 
> >>> Cc: Arjan van de Ven 
> >>> Cc: Borislav Petkov 
> >>> Cc: Dave Hansen 
> >>> Cc: Linus Torvalds 
> >>> Cc: Mel Gorman 
> >>> Cc: Peter Zijlstra 
> >>> Cc: Rik van Riel 
> >>> Cc: linux...@kvack.org
> >>> Link: 
> >>> http://lkml.kernel.org/r/413a91c24dab3ed0caa5f4e4d017d87b0857f920.1498751203.git.l...@kernel.org
> >>> Signed-off-by: Ingo Molnar 
> >>> Signed-off-by: Tim Chen 
> >>> ---
> >>>  arch/x86/include/asm/mmu.h | 15 +--
> >>>  arch/x86/include/asm/mmu_context.h |  5 +
> >>>  arch/x86/mm/tlb.c  |  2 ++
> >>>  3 files changed, 20 insertions(+), 2 deletions(-)
> >>>
> >>
> >> Does not apply to 4.4.y :(
> >>
> >> Can you provide a working backport for that tree?
> >>
> > 
> > Okay. Will do.  Thanks.
> > 
> 
> 
> Greg,
> 
> I actually found that there are a number of dependent IBPB related patches 
> that haven't been
> backported yet to 4.4:
> 
> x86/cpufeatures: Add AMD feature bits for Speculation Control
> (cherry picked from commit 5d10cbc91d9eb5537998b65608441b592eec65e7)
> 
> x86/msr: Add definitions for new speculation control MSRs
> (cherry picked from commit 1e340c60d0dd3ae07b5bedc16a0469c14b9f3410)
> 
> x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) 
> support
> (cherry picked from commit 20ffa1caecca4db8f79fe665acdeaa5af815a24d)
> 
> x86/cpufeatures: Clean up Spectre v2 related CPUID flags
> (cherry picked from commit 2961298efe1ea1b6fc0d7ee8b76018fa6c0bcef2)
> 
> And probably and a few more.
> You have plans to backport these patches?

I don't, but I think someone from Amazon was looking into it, but I
haven't heard from them in a few weeks.  I'll gladly take patches if you
have them, or at the worse case, a list like above of the git commits
that are missing.

thanks,

greg k-h


Re: [PATCH 4.4 00/36] 4.4.121-stable review

2018-03-09 Thread Nathan Chancellor
On Fri, Mar 09, 2018 at 05:03:12PM -0800, Greg Kroah-Hartman wrote:
> On Fri, Mar 09, 2018 at 05:50:35PM -0700, Nathan Chancellor wrote:
> > On Fri, Mar 09, 2018 at 04:18:16PM -0800, Greg Kroah-Hartman wrote:
> > > This is the start of the stable review cycle for the 4.4.121 release.
> > > There are 36 patches in this series, all will be posted as a response
> > > to this one.  If anyone has any issues with these being applied, please
> > > let me know.
> > > 
> > > Responses should be made by Mon Mar 12 00:17:54 UTC 2018.
> > > Anything received after that time might be too late.
> > > 
> > > The whole patch series can be found in one patch at:
> > >   
> > > https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.121-rc1.gz
> > > or in the git tree and branch at:
> > >   
> > > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > > linux-4.4.y
> > > and the diffstat can be found below.
> > > 
> > > thanks,
> > > 
> > > greg k-h
> > >
> > 
> > Merged, compiled, and flashed onto my Pixel 2 XL and OnePlus 5.
> > 
> > No merge conflicts and no visible issues in dmesg or general usage.
> 
> That was fast, thanks!
> 
> greg k-h

I happened to run the stable queue since there was no RC when I decided
to build so the timing worked out!

Nathan


Re: [PATCH 4.4 00/36] 4.4.121-stable review

2018-03-09 Thread Nathan Chancellor
On Fri, Mar 09, 2018 at 05:03:12PM -0800, Greg Kroah-Hartman wrote:
> On Fri, Mar 09, 2018 at 05:50:35PM -0700, Nathan Chancellor wrote:
> > On Fri, Mar 09, 2018 at 04:18:16PM -0800, Greg Kroah-Hartman wrote:
> > > This is the start of the stable review cycle for the 4.4.121 release.
> > > There are 36 patches in this series, all will be posted as a response
> > > to this one.  If anyone has any issues with these being applied, please
> > > let me know.
> > > 
> > > Responses should be made by Mon Mar 12 00:17:54 UTC 2018.
> > > Anything received after that time might be too late.
> > > 
> > > The whole patch series can be found in one patch at:
> > >   
> > > https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.121-rc1.gz
> > > or in the git tree and branch at:
> > >   
> > > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > > linux-4.4.y
> > > and the diffstat can be found below.
> > > 
> > > thanks,
> > > 
> > > greg k-h
> > >
> > 
> > Merged, compiled, and flashed onto my Pixel 2 XL and OnePlus 5.
> > 
> > No merge conflicts and no visible issues in dmesg or general usage.
> 
> That was fast, thanks!
> 
> greg k-h

I happened to run the stable queue since there was no RC when I decided
to build so the timing worked out!

Nathan


Re: [PATCH 1/2] x86/mm: Give each mm a unique ID

2018-03-09 Thread Tim Chen
On 03/08/2018 10:23 AM, Tim Chen wrote:
> On 03/07/2018 09:30 AM, Greg Kroah-Hartman wrote:
>> On Fri, Mar 02, 2018 at 01:32:09PM -0800, Tim Chen wrote:
>>> From: Andy Lutomirski 
>>> commit: f39681ed0f48498b80455095376f11535feea332
>>>
>>> This adds a new variable to mmu_context_t: ctx_id.
>>> ctx_id uniquely identifies the mm_struct and will never be reused.
>>>
>>> Signed-off-by: Andy Lutomirski 
>>> Reviewed-by: Nadav Amit 
>>> Reviewed-by: Thomas Gleixner 
>>> Cc: Andrew Morton 
>>> Cc: Arjan van de Ven 
>>> Cc: Borislav Petkov 
>>> Cc: Dave Hansen 
>>> Cc: Linus Torvalds 
>>> Cc: Mel Gorman 
>>> Cc: Peter Zijlstra 
>>> Cc: Rik van Riel 
>>> Cc: linux...@kvack.org
>>> Link: 
>>> http://lkml.kernel.org/r/413a91c24dab3ed0caa5f4e4d017d87b0857f920.1498751203.git.l...@kernel.org
>>> Signed-off-by: Ingo Molnar 
>>> Signed-off-by: Tim Chen 
>>> ---
>>>  arch/x86/include/asm/mmu.h | 15 +--
>>>  arch/x86/include/asm/mmu_context.h |  5 +
>>>  arch/x86/mm/tlb.c  |  2 ++
>>>  3 files changed, 20 insertions(+), 2 deletions(-)
>>>
>>
>> Does not apply to 4.4.y :(
>>
>> Can you provide a working backport for that tree?
>>
> 
> Okay. Will do.  Thanks.
> 


Greg,

I actually found that there are a number of dependent IBPB related patches that 
haven't been
backported yet to 4.4:

x86/cpufeatures: Add AMD feature bits for Speculation Control
(cherry picked from commit 5d10cbc91d9eb5537998b65608441b592eec65e7)

x86/msr: Add definitions for new speculation control MSRs
(cherry picked from commit 1e340c60d0dd3ae07b5bedc16a0469c14b9f3410)

x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support
(cherry picked from commit 20ffa1caecca4db8f79fe665acdeaa5af815a24d)

x86/cpufeatures: Clean up Spectre v2 related CPUID flags
(cherry picked from commit 2961298efe1ea1b6fc0d7ee8b76018fa6c0bcef2)

And probably and a few more.
You have plans to backport these patches?

Tim



Re: [PATCH 1/2] x86/mm: Give each mm a unique ID

2018-03-09 Thread Tim Chen
On 03/08/2018 10:23 AM, Tim Chen wrote:
> On 03/07/2018 09:30 AM, Greg Kroah-Hartman wrote:
>> On Fri, Mar 02, 2018 at 01:32:09PM -0800, Tim Chen wrote:
>>> From: Andy Lutomirski 
>>> commit: f39681ed0f48498b80455095376f11535feea332
>>>
>>> This adds a new variable to mmu_context_t: ctx_id.
>>> ctx_id uniquely identifies the mm_struct and will never be reused.
>>>
>>> Signed-off-by: Andy Lutomirski 
>>> Reviewed-by: Nadav Amit 
>>> Reviewed-by: Thomas Gleixner 
>>> Cc: Andrew Morton 
>>> Cc: Arjan van de Ven 
>>> Cc: Borislav Petkov 
>>> Cc: Dave Hansen 
>>> Cc: Linus Torvalds 
>>> Cc: Mel Gorman 
>>> Cc: Peter Zijlstra 
>>> Cc: Rik van Riel 
>>> Cc: linux...@kvack.org
>>> Link: 
>>> http://lkml.kernel.org/r/413a91c24dab3ed0caa5f4e4d017d87b0857f920.1498751203.git.l...@kernel.org
>>> Signed-off-by: Ingo Molnar 
>>> Signed-off-by: Tim Chen 
>>> ---
>>>  arch/x86/include/asm/mmu.h | 15 +--
>>>  arch/x86/include/asm/mmu_context.h |  5 +
>>>  arch/x86/mm/tlb.c  |  2 ++
>>>  3 files changed, 20 insertions(+), 2 deletions(-)
>>>
>>
>> Does not apply to 4.4.y :(
>>
>> Can you provide a working backport for that tree?
>>
> 
> Okay. Will do.  Thanks.
> 


Greg,

I actually found that there are a number of dependent IBPB related patches that 
haven't been
backported yet to 4.4:

x86/cpufeatures: Add AMD feature bits for Speculation Control
(cherry picked from commit 5d10cbc91d9eb5537998b65608441b592eec65e7)

x86/msr: Add definitions for new speculation control MSRs
(cherry picked from commit 1e340c60d0dd3ae07b5bedc16a0469c14b9f3410)

x86/speculation: Add basic IBPB (Indirect Branch Prediction Barrier) support
(cherry picked from commit 20ffa1caecca4db8f79fe665acdeaa5af815a24d)

x86/cpufeatures: Clean up Spectre v2 related CPUID flags
(cherry picked from commit 2961298efe1ea1b6fc0d7ee8b76018fa6c0bcef2)

And probably and a few more.
You have plans to backport these patches?

Tim



Re: [PATCH 4.4 00/36] 4.4.121-stable review

2018-03-09 Thread Greg Kroah-Hartman
On Fri, Mar 09, 2018 at 05:50:35PM -0700, Nathan Chancellor wrote:
> On Fri, Mar 09, 2018 at 04:18:16PM -0800, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.4.121 release.
> > There are 36 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> > 
> > Responses should be made by Mon Mar 12 00:17:54 UTC 2018.
> > Anything received after that time might be too late.
> > 
> > The whole patch series can be found in one patch at:
> > 
> > https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.121-rc1.gz
> > or in the git tree and branch at:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > linux-4.4.y
> > and the diffstat can be found below.
> > 
> > thanks,
> > 
> > greg k-h
> >
> 
> Merged, compiled, and flashed onto my Pixel 2 XL and OnePlus 5.
> 
> No merge conflicts and no visible issues in dmesg or general usage.

That was fast, thanks!

greg k-h


Re: [PATCH 4.4 00/36] 4.4.121-stable review

2018-03-09 Thread Greg Kroah-Hartman
On Fri, Mar 09, 2018 at 05:50:35PM -0700, Nathan Chancellor wrote:
> On Fri, Mar 09, 2018 at 04:18:16PM -0800, Greg Kroah-Hartman wrote:
> > This is the start of the stable review cycle for the 4.4.121 release.
> > There are 36 patches in this series, all will be posted as a response
> > to this one.  If anyone has any issues with these being applied, please
> > let me know.
> > 
> > Responses should be made by Mon Mar 12 00:17:54 UTC 2018.
> > Anything received after that time might be too late.
> > 
> > The whole patch series can be found in one patch at:
> > 
> > https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.121-rc1.gz
> > or in the git tree and branch at:
> > 
> > git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> > linux-4.4.y
> > and the diffstat can be found below.
> > 
> > thanks,
> > 
> > greg k-h
> >
> 
> Merged, compiled, and flashed onto my Pixel 2 XL and OnePlus 5.
> 
> No merge conflicts and no visible issues in dmesg or general usage.

That was fast, thanks!

greg k-h


VLA removal, device_handler and COMMAND_SIZE

2018-03-09 Thread Stephen Kitt
Hi,

I’ve been looking into removing some VLAs from device_handler drivers,
prompted by https://lkml.org/lkml/2018/3/7/621

The uses in question here are quite straightforward, e.g. in
drivers/scsi/device_handler/scsi_dh_alua.c:

u8 cdb[COMMAND_SIZE(MAINTENANCE_IN)];

There’s no trivial way of keeping the compiler happy with -Wvla though here,
at least not while keeping the behaviour strictly identical. I’ve come up
with two approaches, and I’m curious whether they’re appropriate or if
there’s a better way...

The first approach is to use MAX_COMMAND_SIZE instead; this wastes a few
bytes on the stack here and there, and stays reasonably maintainable.

The second approach might be symptomatic of a twisted mind, and involves
replacing COMMAND_SIZE so that it can be calculated at compile time when the
opcode is known:

/*
 * SCSI command sizes are as follows, in bytes, for fixed size commands, per
 * group: 6, 10, 10, 12, 16, 12, 10, 10. The top three bits of an opcode
 * determine its group.
 * The size table is encoded into a 32-bit value by subtracting each value
 * from 16, resulting in a value of 1715488362
 * (6 << 28 + 6 << 24 + 4 << 20 + 0 << 16 + 4 << 12 + 6 << 8 + 6 << 4 + 10).
 * Command group 3 is reserved and should never be used.
 */
#define COMMAND_SIZE(opcode) \
   (16 - (15 & (1715488362 >> (4 * (((opcode) >> 5) & 7)


This has the side-effect of making some of the call sites more complex, and
the macro itself isn’t the most maintainer-friendly. It does mean we can drop
BLK_SCSI_REQUEST from drivers/target/Kconfig so it’s not all bad...

Both patches will follow in reply to this email, I’ll let more familiar
developers judge which is appropriate (if any).

Regards,

Stephen


pgpYjyFbY64Zj.pgp
Description: OpenPGP digital signature


VLA removal, device_handler and COMMAND_SIZE

2018-03-09 Thread Stephen Kitt
Hi,

I’ve been looking into removing some VLAs from device_handler drivers,
prompted by https://lkml.org/lkml/2018/3/7/621

The uses in question here are quite straightforward, e.g. in
drivers/scsi/device_handler/scsi_dh_alua.c:

u8 cdb[COMMAND_SIZE(MAINTENANCE_IN)];

There’s no trivial way of keeping the compiler happy with -Wvla though here,
at least not while keeping the behaviour strictly identical. I’ve come up
with two approaches, and I’m curious whether they’re appropriate or if
there’s a better way...

The first approach is to use MAX_COMMAND_SIZE instead; this wastes a few
bytes on the stack here and there, and stays reasonably maintainable.

The second approach might be symptomatic of a twisted mind, and involves
replacing COMMAND_SIZE so that it can be calculated at compile time when the
opcode is known:

/*
 * SCSI command sizes are as follows, in bytes, for fixed size commands, per
 * group: 6, 10, 10, 12, 16, 12, 10, 10. The top three bits of an opcode
 * determine its group.
 * The size table is encoded into a 32-bit value by subtracting each value
 * from 16, resulting in a value of 1715488362
 * (6 << 28 + 6 << 24 + 4 << 20 + 0 << 16 + 4 << 12 + 6 << 8 + 6 << 4 + 10).
 * Command group 3 is reserved and should never be used.
 */
#define COMMAND_SIZE(opcode) \
   (16 - (15 & (1715488362 >> (4 * (((opcode) >> 5) & 7)


This has the side-effect of making some of the call sites more complex, and
the macro itself isn’t the most maintainer-friendly. It does mean we can drop
BLK_SCSI_REQUEST from drivers/target/Kconfig so it’s not all bad...

Both patches will follow in reply to this email, I’ll let more familiar
developers judge which is appropriate (if any).

Regards,

Stephen


pgpYjyFbY64Zj.pgp
Description: OpenPGP digital signature


[PATCH 3.18 01/21] tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on the bus

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Jeremy Boone 

commit 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed upstream.

Discrete TPMs are often connected over slow serial buses which, on
some platforms, can have glitches causing bit flips.  In all the
driver _recv() functions, we need to use a u32 to unmarshal the
response size, otherwise a bit flip of the 31st bit would cause the
expected variable to go negative, which would then try to read a huge
amount of data.  Also sanity check that the expected amount of data is
large enough for the TPM header.

Signed-off-by: Jeremy Boone 
Cc: sta...@vger.kernel.org
Signed-off-by: James Bottomley 
Reviewed-by: Jarkko Sakkinen 
Signed-off-by: Jarkko Sakkinen 
Signed-off-by: James Morris 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/char/tpm/tpm_i2c_infineon.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -436,7 +436,8 @@ static int recv_data(struct tpm_chip *ch
 static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
int size = 0;
-   int expected, status;
+   int status;
+   u32 expected;
 
if (count < TPM_HEADER_SIZE) {
size = -EIO;
@@ -451,7 +452,7 @@ static int tpm_tis_i2c_recv(struct tpm_c
}
 
expected = be32_to_cpu(*(__be32 *)(buf + 2));
-   if ((size_t) expected > count) {
+   if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) {
size = -EIO;
goto out;
}




[PATCH 3.18 10/21] ipv6 sit: work around bogus gcc-8 -Wrestrict warning

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Arnd Bergmann 


[ Upstream commit ca79bec237f5809a7c3c59bd41cd0880aa889966 ]

gcc-8 has a new warning that detects overlapping input and output arguments
in memcpy(). It triggers for sit_init_net() calling ipip6_tunnel_clone_6rd(),
which is actually correct:

net/ipv6/sit.c: In function 'sit_init_net':
net/ipv6/sit.c:192:3: error: 'memcpy' source argument is the same as 
destination [-Werror=restrict]

The problem here is that the logic detecting the memcpy() arguments finds them
to be the same, but the conditional that tests for the input and output of
ipip6_tunnel_clone_6rd() to be identical is not a compile-time constant.

We know that netdev_priv(t->dev) is the same as t for a tunnel device,
and comparing "dev" directly here lets the compiler figure out as well
that 'dev == sitn->fb_tunnel_dev' when called from sit_init_net(), so
it no longer warns.

This code is old, so Cc stable to make sure that we don't get the warning
for older kernels built with new gcc.

Cc: Martin Sebor 
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83456
Signed-off-by: Arnd Bergmann 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/ipv6/sit.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -176,7 +176,7 @@ static void ipip6_tunnel_clone_6rd(struc
 #ifdef CONFIG_IPV6_SIT_6RD
struct ip_tunnel *t = netdev_priv(dev);
 
-   if (t->dev == sitn->fb_tunnel_dev) {
+   if (dev == sitn->fb_tunnel_dev) {
ipv6_addr_set(>ip6rd.prefix, htonl(0x2002), 0, 0, 0);
t->ip6rd.relay_prefix = 0;
t->ip6rd.prefixlen = 16;




[PATCH 3.18 11/21] net: fix race on decreasing number of TX queues

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Jakub Kicinski 


[ Upstream commit ac5b70198adc25c73fba28de4f78adcee8f6be0b ]

netif_set_real_num_tx_queues() can be called when netdev is up.
That usually happens when user requests change of number of
channels/rings with ethtool -L.  The procedure for changing
the number of queues involves resetting the qdiscs and setting
dev->num_tx_queues to the new value.  When the new value is
lower than the old one, extra care has to be taken to ensure
ordering of accesses to the number of queues vs qdisc reset.

Currently the queues are reset before new dev->num_tx_queues
is assigned, leaving a window of time where packets can be
enqueued onto the queues going down, leading to a likely
crash in the drivers, since most drivers don't check if TX
skbs are assigned to an active queue.

Fixes: e6484930d7c7 ("net: allocate tx queues in register_netdevice")
Signed-off-by: Jakub Kicinski 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/core/dev.c |   11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2070,8 +2070,11 @@ EXPORT_SYMBOL(netif_set_xps_queue);
  */
 int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
 {
+   bool disabling;
int rc;
 
+   disabling = txq < dev->real_num_tx_queues;
+
if (txq < 1 || txq > dev->num_tx_queues)
return -EINVAL;
 
@@ -2087,15 +2090,19 @@ int netif_set_real_num_tx_queues(struct
if (dev->num_tc)
netif_setup_tc(dev, txq);
 
-   if (txq < dev->real_num_tx_queues) {
+   dev->real_num_tx_queues = txq;
+
+   if (disabling) {
+   synchronize_net();
qdisc_reset_all_tx_gt(dev, txq);
 #ifdef CONFIG_XPS
netif_reset_xps_queues_gt(dev, txq);
 #endif
}
+   } else {
+   dev->real_num_tx_queues = txq;
}
 
-   dev->real_num_tx_queues = txq;
return 0;
 }
 EXPORT_SYMBOL(netif_set_real_num_tx_queues);




[PATCH 3.18 01/21] tpm_i2c_infineon: fix potential buffer overruns caused by bit glitches on the bus

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Jeremy Boone 

commit 9b8cb28d7c62568a5916bdd7ea1c9176d7f8f2ed upstream.

Discrete TPMs are often connected over slow serial buses which, on
some platforms, can have glitches causing bit flips.  In all the
driver _recv() functions, we need to use a u32 to unmarshal the
response size, otherwise a bit flip of the 31st bit would cause the
expected variable to go negative, which would then try to read a huge
amount of data.  Also sanity check that the expected amount of data is
large enough for the TPM header.

Signed-off-by: Jeremy Boone 
Cc: sta...@vger.kernel.org
Signed-off-by: James Bottomley 
Reviewed-by: Jarkko Sakkinen 
Signed-off-by: Jarkko Sakkinen 
Signed-off-by: James Morris 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/char/tpm/tpm_i2c_infineon.c |5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- a/drivers/char/tpm/tpm_i2c_infineon.c
+++ b/drivers/char/tpm/tpm_i2c_infineon.c
@@ -436,7 +436,8 @@ static int recv_data(struct tpm_chip *ch
 static int tpm_tis_i2c_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 {
int size = 0;
-   int expected, status;
+   int status;
+   u32 expected;
 
if (count < TPM_HEADER_SIZE) {
size = -EIO;
@@ -451,7 +452,7 @@ static int tpm_tis_i2c_recv(struct tpm_c
}
 
expected = be32_to_cpu(*(__be32 *)(buf + 2));
-   if ((size_t) expected > count) {
+   if (((size_t) expected > count) || (expected < TPM_HEADER_SIZE)) {
size = -EIO;
goto out;
}




[PATCH 3.18 10/21] ipv6 sit: work around bogus gcc-8 -Wrestrict warning

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Arnd Bergmann 


[ Upstream commit ca79bec237f5809a7c3c59bd41cd0880aa889966 ]

gcc-8 has a new warning that detects overlapping input and output arguments
in memcpy(). It triggers for sit_init_net() calling ipip6_tunnel_clone_6rd(),
which is actually correct:

net/ipv6/sit.c: In function 'sit_init_net':
net/ipv6/sit.c:192:3: error: 'memcpy' source argument is the same as 
destination [-Werror=restrict]

The problem here is that the logic detecting the memcpy() arguments finds them
to be the same, but the conditional that tests for the input and output of
ipip6_tunnel_clone_6rd() to be identical is not a compile-time constant.

We know that netdev_priv(t->dev) is the same as t for a tunnel device,
and comparing "dev" directly here lets the compiler figure out as well
that 'dev == sitn->fb_tunnel_dev' when called from sit_init_net(), so
it no longer warns.

This code is old, so Cc stable to make sure that we don't get the warning
for older kernels built with new gcc.

Cc: Martin Sebor 
Link: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83456
Signed-off-by: Arnd Bergmann 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/ipv6/sit.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -176,7 +176,7 @@ static void ipip6_tunnel_clone_6rd(struc
 #ifdef CONFIG_IPV6_SIT_6RD
struct ip_tunnel *t = netdev_priv(dev);
 
-   if (t->dev == sitn->fb_tunnel_dev) {
+   if (dev == sitn->fb_tunnel_dev) {
ipv6_addr_set(>ip6rd.prefix, htonl(0x2002), 0, 0, 0);
t->ip6rd.relay_prefix = 0;
t->ip6rd.prefixlen = 16;




[PATCH 3.18 11/21] net: fix race on decreasing number of TX queues

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Jakub Kicinski 


[ Upstream commit ac5b70198adc25c73fba28de4f78adcee8f6be0b ]

netif_set_real_num_tx_queues() can be called when netdev is up.
That usually happens when user requests change of number of
channels/rings with ethtool -L.  The procedure for changing
the number of queues involves resetting the qdiscs and setting
dev->num_tx_queues to the new value.  When the new value is
lower than the old one, extra care has to be taken to ensure
ordering of accesses to the number of queues vs qdisc reset.

Currently the queues are reset before new dev->num_tx_queues
is assigned, leaving a window of time where packets can be
enqueued onto the queues going down, leading to a likely
crash in the drivers, since most drivers don't check if TX
skbs are assigned to an active queue.

Fixes: e6484930d7c7 ("net: allocate tx queues in register_netdevice")
Signed-off-by: Jakub Kicinski 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/core/dev.c |   11 +--
 1 file changed, 9 insertions(+), 2 deletions(-)

--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2070,8 +2070,11 @@ EXPORT_SYMBOL(netif_set_xps_queue);
  */
 int netif_set_real_num_tx_queues(struct net_device *dev, unsigned int txq)
 {
+   bool disabling;
int rc;
 
+   disabling = txq < dev->real_num_tx_queues;
+
if (txq < 1 || txq > dev->num_tx_queues)
return -EINVAL;
 
@@ -2087,15 +2090,19 @@ int netif_set_real_num_tx_queues(struct
if (dev->num_tc)
netif_setup_tc(dev, txq);
 
-   if (txq < dev->real_num_tx_queues) {
+   dev->real_num_tx_queues = txq;
+
+   if (disabling) {
+   synchronize_net();
qdisc_reset_all_tx_gt(dev, txq);
 #ifdef CONFIG_XPS
netif_reset_xps_queues_gt(dev, txq);
 #endif
}
+   } else {
+   dev->real_num_tx_queues = txq;
}
 
-   dev->real_num_tx_queues = txq;
return 0;
 }
 EXPORT_SYMBOL(netif_set_real_num_tx_queues);




[PATCH 3.18 02/21] tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the bus

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Jeremy Boone 

commit f9d4d9b5a5ef2f017bc344fb65a58a902517173b upstream.

Discrete TPMs are often connected over slow serial buses which, on
some platforms, can have glitches causing bit flips.  In all the
driver _recv() functions, we need to use a u32 to unmarshal the
response size, otherwise a bit flip of the 31st bit would cause the
expected variable to go negative, which would then try to read a huge
amount of data.  Also sanity check that the expected amount of data is
large enough for the TPM header.

Signed-off-by: Jeremy Boone 
Cc: sta...@vger.kernel.org
Signed-off-by: James Bottomley 
Reviewed-by: Jarkko Sakkinen 
Signed-off-by: Jarkko Sakkinen 
Signed-off-by: James Morris 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/char/tpm/tpm_i2c_nuvoton.c |8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
@@ -267,7 +267,11 @@ static int i2c_nuvoton_recv(struct tpm_c
struct device *dev = chip->dev;
struct i2c_client *client = to_i2c_client(dev);
s32 rc;
-   int expected, status, burst_count, retries, size = 0;
+   int status;
+   int burst_count;
+   int retries;
+   int size = 0;
+   u32 expected;
 
if (count < TPM_HEADER_SIZE) {
i2c_nuvoton_ready(chip);/* return to idle */
@@ -309,7 +313,7 @@ static int i2c_nuvoton_recv(struct tpm_c
 * to machine native
 */
expected = be32_to_cpu(*(__be32 *) (buf + 2));
-   if (expected > count) {
+   if (expected > count || expected < size) {
dev_err(dev, "%s() expected > count\n", __func__);
size = -EIO;
continue;




[PATCH 3.18 02/21] tpm_i2c_nuvoton: fix potential buffer overruns caused by bit glitches on the bus

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Jeremy Boone 

commit f9d4d9b5a5ef2f017bc344fb65a58a902517173b upstream.

Discrete TPMs are often connected over slow serial buses which, on
some platforms, can have glitches causing bit flips.  In all the
driver _recv() functions, we need to use a u32 to unmarshal the
response size, otherwise a bit flip of the 31st bit would cause the
expected variable to go negative, which would then try to read a huge
amount of data.  Also sanity check that the expected amount of data is
large enough for the TPM header.

Signed-off-by: Jeremy Boone 
Cc: sta...@vger.kernel.org
Signed-off-by: James Bottomley 
Reviewed-by: Jarkko Sakkinen 
Signed-off-by: Jarkko Sakkinen 
Signed-off-by: James Morris 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/char/tpm/tpm_i2c_nuvoton.c |8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/drivers/char/tpm/tpm_i2c_nuvoton.c
+++ b/drivers/char/tpm/tpm_i2c_nuvoton.c
@@ -267,7 +267,11 @@ static int i2c_nuvoton_recv(struct tpm_c
struct device *dev = chip->dev;
struct i2c_client *client = to_i2c_client(dev);
s32 rc;
-   int expected, status, burst_count, retries, size = 0;
+   int status;
+   int burst_count;
+   int retries;
+   int size = 0;
+   u32 expected;
 
if (count < TPM_HEADER_SIZE) {
i2c_nuvoton_ready(chip);/* return to idle */
@@ -309,7 +313,7 @@ static int i2c_nuvoton_recv(struct tpm_c
 * to machine native
 */
expected = be32_to_cpu(*(__be32 *) (buf + 2));
-   if (expected > count) {
+   if (expected > count || expected < size) {
dev_err(dev, "%s() expected > count\n", __func__);
size = -EIO;
continue;




[PATCH 3.18 05/21] ARM: mvebu: Fix broken PL310_ERRATA_753970 selects

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Ulf Magnusson 

commit 8aa36a8dcde3183d84db7b0d622ffddcebb61077 upstream.

The MACH_ARMADA_375 and MACH_ARMADA_38X boards select ARM_ERRATA_753970,
but it was renamed to PL310_ERRATA_753970 by commit fa0ce4035d48 ("ARM:
7162/1: errata: tidy up Kconfig options for PL310 errata workarounds").

Fix the selects to use the new name.

Discovered with the
https://github.com/ulfalizer/Kconfiglib/blob/master/examples/list_undefined.py
script.
Fixes: fa0ce4035d48 ("ARM: 7162/1: errata: tidy up Kconfig options for
PL310 errata workarounds"
cc: sta...@vger.kernel.org
Signed-off-by: Ulf Magnusson 
Signed-off-by: Gregory CLEMENT 
Signed-off-by: Greg Kroah-Hartman 

---
 arch/arm/mach-mvebu/Kconfig |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -37,7 +37,7 @@ config MACH_ARMADA_370
 config MACH_ARMADA_375
bool "Marvell Armada 375 boards" if ARCH_MULTI_V7
select ARM_ERRATA_720789
-   select ARM_ERRATA_753970
+   select PL310_ERRATA_753970
select ARM_GIC
select ARMADA_375_CLK
select HAVE_ARM_SCU
@@ -52,7 +52,7 @@ config MACH_ARMADA_375
 config MACH_ARMADA_38X
bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
select ARM_ERRATA_720789
-   select ARM_ERRATA_753970
+   select PL310_ERRATA_753970
select ARM_GIC
select ARMADA_38X_CLK
select HAVE_ARM_SCU




[PATCH 3.18 05/21] ARM: mvebu: Fix broken PL310_ERRATA_753970 selects

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Ulf Magnusson 

commit 8aa36a8dcde3183d84db7b0d622ffddcebb61077 upstream.

The MACH_ARMADA_375 and MACH_ARMADA_38X boards select ARM_ERRATA_753970,
but it was renamed to PL310_ERRATA_753970 by commit fa0ce4035d48 ("ARM:
7162/1: errata: tidy up Kconfig options for PL310 errata workarounds").

Fix the selects to use the new name.

Discovered with the
https://github.com/ulfalizer/Kconfiglib/blob/master/examples/list_undefined.py
script.
Fixes: fa0ce4035d48 ("ARM: 7162/1: errata: tidy up Kconfig options for
PL310 errata workarounds"
cc: sta...@vger.kernel.org
Signed-off-by: Ulf Magnusson 
Signed-off-by: Gregory CLEMENT 
Signed-off-by: Greg Kroah-Hartman 

---
 arch/arm/mach-mvebu/Kconfig |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/arch/arm/mach-mvebu/Kconfig
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -37,7 +37,7 @@ config MACH_ARMADA_370
 config MACH_ARMADA_375
bool "Marvell Armada 375 boards" if ARCH_MULTI_V7
select ARM_ERRATA_720789
-   select ARM_ERRATA_753970
+   select PL310_ERRATA_753970
select ARM_GIC
select ARMADA_375_CLK
select HAVE_ARM_SCU
@@ -52,7 +52,7 @@ config MACH_ARMADA_375
 config MACH_ARMADA_38X
bool "Marvell Armada 380/385 boards" if ARCH_MULTI_V7
select ARM_ERRATA_720789
-   select ARM_ERRATA_753970
+   select PL310_ERRATA_753970
select ARM_GIC
select ARMADA_38X_CLK
select HAVE_ARM_SCU




[PATCH 3.18 08/21] bridge: check brport attr show in brport_show

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Xin Long 


[ Upstream commit 1b12580af1d0677c3c3a19e35bfe5d59b03f737f ]

Now br_sysfs_if file flush doesn't have attr show. To read it will
cause kernel panic after users chmod u+r this file.

Xiong found this issue when running the commands:

  ip link add br0 type bridge
  ip link add type veth
  ip link set veth0 master br0
  chmod u+r /sys/devices/virtual/net/veth0/brport/flush
  timeout 3 cat /sys/devices/virtual/net/veth0/brport/flush

kernel crashed with NULL a pointer dereference call trace.

This patch is to fix it by return -EINVAL when brport_attr->show
is null, just the same as the check for brport_attr->store in
brport_store().

Fixes: 9cf637473c85 ("bridge: add sysfs hook to flush forwarding table")
Reported-by: Xiong Zhou 
Signed-off-by: Xin Long 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/bridge/br_sysfs_if.c |3 +++
 1 file changed, 3 insertions(+)

--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -225,6 +225,9 @@ static ssize_t brport_show(struct kobjec
struct brport_attribute *brport_attr = to_brport_attr(attr);
struct net_bridge_port *p = to_brport(kobj);
 
+   if (!brport_attr->show)
+   return -EINVAL;
+
return brport_attr->show(p, buf);
 }
 




[PATCH 3.18 08/21] bridge: check brport attr show in brport_show

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Xin Long 


[ Upstream commit 1b12580af1d0677c3c3a19e35bfe5d59b03f737f ]

Now br_sysfs_if file flush doesn't have attr show. To read it will
cause kernel panic after users chmod u+r this file.

Xiong found this issue when running the commands:

  ip link add br0 type bridge
  ip link add type veth
  ip link set veth0 master br0
  chmod u+r /sys/devices/virtual/net/veth0/brport/flush
  timeout 3 cat /sys/devices/virtual/net/veth0/brport/flush

kernel crashed with NULL a pointer dereference call trace.

This patch is to fix it by return -EINVAL when brport_attr->show
is null, just the same as the check for brport_attr->store in
brport_store().

Fixes: 9cf637473c85 ("bridge: add sysfs hook to flush forwarding table")
Reported-by: Xiong Zhou 
Signed-off-by: Xin Long 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/bridge/br_sysfs_if.c |3 +++
 1 file changed, 3 insertions(+)

--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -225,6 +225,9 @@ static ssize_t brport_show(struct kobjec
struct brport_attribute *brport_attr = to_brport_attr(attr);
struct net_bridge_port *p = to_brport(kobj);
 
+   if (!brport_attr->show)
+   return -EINVAL;
+
return brport_attr->show(p, buf);
 }
 




[PATCH 3.18 07/21] leds: do not overflow sysfs buffer in led_trigger_show

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Nathan Sullivan 

commit 3b9b95363c45365d606ad4bbba16acca75fdf6d3 upstream.

Per the documentation, use scnprintf instead of sprintf to ensure there
is never more than PAGE_SIZE bytes of trigger names put into the
buffer.

Signed-off-by: Nathan Sullivan 
Signed-off-by: Zach Brown 
Signed-off-by: Jacek Anaszewski 
Cc: Willy Tarreau 
Cc: Vlastimil Babka 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/leds/led-triggers.c |   12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -78,21 +78,23 @@ ssize_t led_trigger_show(struct device *
down_read(_cdev->trigger_lock);
 
if (!led_cdev->trigger)
-   len += sprintf(buf+len, "[none] ");
+   len += scnprintf(buf+len, PAGE_SIZE - len, "[none] ");
else
-   len += sprintf(buf+len, "none ");
+   len += scnprintf(buf+len, PAGE_SIZE - len, "none ");
 
list_for_each_entry(trig, _list, next_trig) {
if (led_cdev->trigger && !strcmp(led_cdev->trigger->name,
trig->name))
-   len += sprintf(buf+len, "[%s] ", trig->name);
+   len += scnprintf(buf+len, PAGE_SIZE - len, "[%s] ",
+trig->name);
else
-   len += sprintf(buf+len, "%s ", trig->name);
+   len += scnprintf(buf+len, PAGE_SIZE - len, "%s ",
+trig->name);
}
up_read(_cdev->trigger_lock);
up_read(_list_lock);
 
-   len += sprintf(len+buf, "\n");
+   len += scnprintf(len+buf, PAGE_SIZE - len, "\n");
return len;
 }
 EXPORT_SYMBOL_GPL(led_trigger_show);




[PATCH 3.18 04/21] cpufreq: s3c24xx: Fix broken s3c_cpufreq_init()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Viresh Kumar 

commit 0373ca74831b0f93cd4cdbf7ad3aec3c33a479a5 upstream.

commit a307a1e6bc0d "cpufreq: s3c: use cpufreq_generic_init()"
accidentally broke cpufreq on s3c2410 and s3c2412.

These two platforms don't have a CPU frequency table and used to skip
calling cpufreq_table_validate_and_show() for them.  But with the
above commit, we started calling it unconditionally and that will
eventually fail as the frequency table pointer is NULL.

Fix this by calling cpufreq_table_validate_and_show() conditionally
again.

Fixes: a307a1e6bc0d "cpufreq: s3c: use cpufreq_generic_init()"
Cc: 3.13+  # v3.13+
Signed-off-by: Viresh Kumar 
Signed-off-by: Rafael J. Wysocki 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/cpufreq/s3c24xx-cpufreq.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -364,7 +364,13 @@ struct clk *s3c_cpufreq_clk_get(struct d
 static int s3c_cpufreq_init(struct cpufreq_policy *policy)
 {
policy->clk = clk_arm;
-   return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency);
+
+   policy->cpuinfo.transition_latency = cpu_cur.info->latency;
+
+   if (ftab)
+   return cpufreq_table_validate_and_show(policy, ftab);
+
+   return 0;
 }
 
 static int __init s3c_cpufreq_initclks(void)




[PATCH 3.18 04/21] cpufreq: s3c24xx: Fix broken s3c_cpufreq_init()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Viresh Kumar 

commit 0373ca74831b0f93cd4cdbf7ad3aec3c33a479a5 upstream.

commit a307a1e6bc0d "cpufreq: s3c: use cpufreq_generic_init()"
accidentally broke cpufreq on s3c2410 and s3c2412.

These two platforms don't have a CPU frequency table and used to skip
calling cpufreq_table_validate_and_show() for them.  But with the
above commit, we started calling it unconditionally and that will
eventually fail as the frequency table pointer is NULL.

Fix this by calling cpufreq_table_validate_and_show() conditionally
again.

Fixes: a307a1e6bc0d "cpufreq: s3c: use cpufreq_generic_init()"
Cc: 3.13+  # v3.13+
Signed-off-by: Viresh Kumar 
Signed-off-by: Rafael J. Wysocki 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/cpufreq/s3c24xx-cpufreq.c |8 +++-
 1 file changed, 7 insertions(+), 1 deletion(-)

--- a/drivers/cpufreq/s3c24xx-cpufreq.c
+++ b/drivers/cpufreq/s3c24xx-cpufreq.c
@@ -364,7 +364,13 @@ struct clk *s3c_cpufreq_clk_get(struct d
 static int s3c_cpufreq_init(struct cpufreq_policy *policy)
 {
policy->clk = clk_arm;
-   return cpufreq_generic_init(policy, ftab, cpu_cur.info->latency);
+
+   policy->cpuinfo.transition_latency = cpu_cur.info->latency;
+
+   if (ftab)
+   return cpufreq_table_validate_and_show(policy, ftab);
+
+   return 0;
 }
 
 static int __init s3c_cpufreq_initclks(void)




[PATCH 3.18 07/21] leds: do not overflow sysfs buffer in led_trigger_show

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Nathan Sullivan 

commit 3b9b95363c45365d606ad4bbba16acca75fdf6d3 upstream.

Per the documentation, use scnprintf instead of sprintf to ensure there
is never more than PAGE_SIZE bytes of trigger names put into the
buffer.

Signed-off-by: Nathan Sullivan 
Signed-off-by: Zach Brown 
Signed-off-by: Jacek Anaszewski 
Cc: Willy Tarreau 
Cc: Vlastimil Babka 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/leds/led-triggers.c |   12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

--- a/drivers/leds/led-triggers.c
+++ b/drivers/leds/led-triggers.c
@@ -78,21 +78,23 @@ ssize_t led_trigger_show(struct device *
down_read(_cdev->trigger_lock);
 
if (!led_cdev->trigger)
-   len += sprintf(buf+len, "[none] ");
+   len += scnprintf(buf+len, PAGE_SIZE - len, "[none] ");
else
-   len += sprintf(buf+len, "none ");
+   len += scnprintf(buf+len, PAGE_SIZE - len, "none ");
 
list_for_each_entry(trig, _list, next_trig) {
if (led_cdev->trigger && !strcmp(led_cdev->trigger->name,
trig->name))
-   len += sprintf(buf+len, "[%s] ", trig->name);
+   len += scnprintf(buf+len, PAGE_SIZE - len, "[%s] ",
+trig->name);
else
-   len += sprintf(buf+len, "%s ", trig->name);
+   len += scnprintf(buf+len, PAGE_SIZE - len, "%s ",
+trig->name);
}
up_read(_cdev->trigger_lock);
up_read(_list_lock);
 
-   len += sprintf(len+buf, "\n");
+   len += scnprintf(len+buf, PAGE_SIZE - len, "\n");
return len;
 }
 EXPORT_SYMBOL_GPL(led_trigger_show);




[PATCH 3.18 14/21] udplite: fix partial checksum initialization

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Alexey Kodanev 


[ Upstream commit 15f35d49c93f4fa9875235e7bf3e3783d2dd7a1b ]

Since UDP-Lite is always using checksum, the following path is
triggered when calculating pseudo header for it:

  udp4_csum_init() or udp6_csum_init()
skb_checksum_init_zero_check()
  __skb_checksum_validate_complete()

The problem can appear if skb->len is less than CHECKSUM_BREAK. In
this particular case __skb_checksum_validate_complete() also invokes
__skb_checksum_complete(skb). If UDP-Lite is using partial checksum
that covers only part of a packet, the function will return bad
checksum and the packet will be dropped.

It can be fixed if we skip skb_checksum_init_zero_check() and only
set the required pseudo header checksum for UDP-Lite with partial
checksum before udp4_csum_init()/udp6_csum_init() functions return.

Fixes: ed70fcfcee95 ("net: Call skb_checksum_init in IPv4")
Fixes: e4f45b7f40bd ("net: Call skb_checksum_init in IPv6")
Signed-off-by: Alexey Kodanev 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 include/net/udplite.h   |1 +
 net/ipv4/udp.c  |5 +
 net/ipv6/ip6_checksum.c |5 +
 3 files changed, 11 insertions(+)

--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -61,6 +61,7 @@ static inline int udplite_checksum_init(
UDP_SKB_CB(skb)->cscov = cscov;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->ip_summed = CHECKSUM_NONE;
+   skb->csum_valid = 0;
 }
 
return 0;
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1718,6 +1718,11 @@ static inline int udp4_csum_init(struct
err = udplite_checksum_init(skb, uh);
if (err)
return err;
+
+   if (UDP_SKB_CB(skb)->partial_cov) {
+   skb->csum = inet_compute_pseudo(skb, proto);
+   return 0;
+   }
}
 
return skb_checksum_init_zero_check(skb, proto, uh->check,
--- a/net/ipv6/ip6_checksum.c
+++ b/net/ipv6/ip6_checksum.c
@@ -73,6 +73,11 @@ int udp6_csum_init(struct sk_buff *skb,
err = udplite_checksum_init(skb, uh);
if (err)
return err;
+
+   if (UDP_SKB_CB(skb)->partial_cov) {
+   skb->csum = ip6_compute_pseudo(skb, proto);
+   return 0;
+   }
}
 
/* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)




[PATCH 3.18 14/21] udplite: fix partial checksum initialization

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Alexey Kodanev 


[ Upstream commit 15f35d49c93f4fa9875235e7bf3e3783d2dd7a1b ]

Since UDP-Lite is always using checksum, the following path is
triggered when calculating pseudo header for it:

  udp4_csum_init() or udp6_csum_init()
skb_checksum_init_zero_check()
  __skb_checksum_validate_complete()

The problem can appear if skb->len is less than CHECKSUM_BREAK. In
this particular case __skb_checksum_validate_complete() also invokes
__skb_checksum_complete(skb). If UDP-Lite is using partial checksum
that covers only part of a packet, the function will return bad
checksum and the packet will be dropped.

It can be fixed if we skip skb_checksum_init_zero_check() and only
set the required pseudo header checksum for UDP-Lite with partial
checksum before udp4_csum_init()/udp6_csum_init() functions return.

Fixes: ed70fcfcee95 ("net: Call skb_checksum_init in IPv4")
Fixes: e4f45b7f40bd ("net: Call skb_checksum_init in IPv6")
Signed-off-by: Alexey Kodanev 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 include/net/udplite.h   |1 +
 net/ipv4/udp.c  |5 +
 net/ipv6/ip6_checksum.c |5 +
 3 files changed, 11 insertions(+)

--- a/include/net/udplite.h
+++ b/include/net/udplite.h
@@ -61,6 +61,7 @@ static inline int udplite_checksum_init(
UDP_SKB_CB(skb)->cscov = cscov;
if (skb->ip_summed == CHECKSUM_COMPLETE)
skb->ip_summed = CHECKSUM_NONE;
+   skb->csum_valid = 0;
 }
 
return 0;
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1718,6 +1718,11 @@ static inline int udp4_csum_init(struct
err = udplite_checksum_init(skb, uh);
if (err)
return err;
+
+   if (UDP_SKB_CB(skb)->partial_cov) {
+   skb->csum = inet_compute_pseudo(skb, proto);
+   return 0;
+   }
}
 
return skb_checksum_init_zero_check(skb, proto, uh->check,
--- a/net/ipv6/ip6_checksum.c
+++ b/net/ipv6/ip6_checksum.c
@@ -73,6 +73,11 @@ int udp6_csum_init(struct sk_buff *skb,
err = udplite_checksum_init(skb, uh);
if (err)
return err;
+
+   if (UDP_SKB_CB(skb)->partial_cov) {
+   skb->csum = ip6_compute_pseudo(skb, proto);
+   return 0;
+   }
}
 
/* To support RFC 6936 (allow zero checksum in UDP/IPV6 for tunnels)




[PATCH 3.18 16/21] s390/qeth: fix SETIP command handling

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Julian Wiedmann 


[ Upstream commit 1c5b2216fbb973a9410e0b06389740b5c1289171 ]

send_control_data() applies some special handling to SETIP v4 IPA
commands. But current code parses *all* command types for the SETIP
command code. Limit the command code check to IPA commands.

Fixes: 5b54e16f1a54 ("qeth: do not spin for SETIP ip assist command")
Signed-off-by: Julian Wiedmann 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/s390/net/qeth_core.h  |5 +
 drivers/s390/net/qeth_core_main.c |   14 --
 2 files changed, 13 insertions(+), 6 deletions(-)

--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -593,6 +593,11 @@ struct qeth_cmd_buffer {
void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *);
 };
 
+static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
+{
+   return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
+}
+
 /**
  * definition of a qeth channel, used for read and write
  */
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2023,7 +2023,7 @@ int qeth_send_control_data(struct qeth_c
unsigned long flags;
struct qeth_reply *reply = NULL;
unsigned long timeout, event_timeout;
-   struct qeth_ipa_cmd *cmd;
+   struct qeth_ipa_cmd *cmd = NULL;
 
QETH_CARD_TEXT(card, 2, "sendctl");
 
@@ -2050,10 +2050,13 @@ int qeth_send_control_data(struct qeth_c
while (atomic_cmpxchg(>write.irq_pending, 0, 1)) ;
qeth_prepare_control_data(card, len, iob);
 
-   if (IS_IPA(iob->data))
+   if (IS_IPA(iob->data)) {
+   cmd = __ipa_cmd(iob);
event_timeout = QETH_IPA_TIMEOUT;
-   else
+   } else {
event_timeout = QETH_TIMEOUT;
+   }
+
timeout = jiffies + event_timeout;
 
QETH_CARD_TEXT(card, 6, "noirqpnd");
@@ -2078,9 +2081,8 @@ int qeth_send_control_data(struct qeth_c
 
/* we have only one long running ipassist, since we can ensure
   process context of this command we can sleep */
-   cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
-   if ((cmd->hdr.command == IPA_CMD_SETIP) &&
-   (cmd->hdr.prot_version == QETH_PROT_IPV4)) {
+   if (cmd && cmd->hdr.command == IPA_CMD_SETIP &&
+   cmd->hdr.prot_version == QETH_PROT_IPV4) {
if (!wait_event_timeout(reply->wait_q,
atomic_read(>received), event_timeout))
goto time_err;




[PATCH 3.18 09/21] hdlc_ppp: carrier detect ok, dont turn off negotiation

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Denis Du 


[ Upstream commit b6c3bad1ba83af1062a7ff6986d9edc4f3d7fc8e ]

Sometimes when physical lines have a just good noise to make the protocol
handshaking fail, but the carrier detect still good. Then after remove of
the noise, nobody will trigger this protocol to be start again to cause
the link to never come back. The fix is when the carrier is still on, not
terminate the protocol handshaking.

Signed-off-by: Denis Du 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/net/wan/hdlc_ppp.c |5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -574,7 +574,10 @@ static void ppp_timer(unsigned long arg)
ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
 0, NULL);
proto->restart_counter--;
-   } else
+   } else if (netif_carrier_ok(proto->dev))
+   ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
+0, NULL);
+   else
ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0,
 0, NULL);
break;




[PATCH 3.18 16/21] s390/qeth: fix SETIP command handling

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Julian Wiedmann 


[ Upstream commit 1c5b2216fbb973a9410e0b06389740b5c1289171 ]

send_control_data() applies some special handling to SETIP v4 IPA
commands. But current code parses *all* command types for the SETIP
command code. Limit the command code check to IPA commands.

Fixes: 5b54e16f1a54 ("qeth: do not spin for SETIP ip assist command")
Signed-off-by: Julian Wiedmann 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/s390/net/qeth_core.h  |5 +
 drivers/s390/net/qeth_core_main.c |   14 --
 2 files changed, 13 insertions(+), 6 deletions(-)

--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -593,6 +593,11 @@ struct qeth_cmd_buffer {
void (*callback) (struct qeth_channel *, struct qeth_cmd_buffer *);
 };
 
+static inline struct qeth_ipa_cmd *__ipa_cmd(struct qeth_cmd_buffer *iob)
+{
+   return (struct qeth_ipa_cmd *)(iob->data + IPA_PDU_HEADER_SIZE);
+}
+
 /**
  * definition of a qeth channel, used for read and write
  */
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2023,7 +2023,7 @@ int qeth_send_control_data(struct qeth_c
unsigned long flags;
struct qeth_reply *reply = NULL;
unsigned long timeout, event_timeout;
-   struct qeth_ipa_cmd *cmd;
+   struct qeth_ipa_cmd *cmd = NULL;
 
QETH_CARD_TEXT(card, 2, "sendctl");
 
@@ -2050,10 +2050,13 @@ int qeth_send_control_data(struct qeth_c
while (atomic_cmpxchg(>write.irq_pending, 0, 1)) ;
qeth_prepare_control_data(card, len, iob);
 
-   if (IS_IPA(iob->data))
+   if (IS_IPA(iob->data)) {
+   cmd = __ipa_cmd(iob);
event_timeout = QETH_IPA_TIMEOUT;
-   else
+   } else {
event_timeout = QETH_TIMEOUT;
+   }
+
timeout = jiffies + event_timeout;
 
QETH_CARD_TEXT(card, 6, "noirqpnd");
@@ -2078,9 +2081,8 @@ int qeth_send_control_data(struct qeth_c
 
/* we have only one long running ipassist, since we can ensure
   process context of this command we can sleep */
-   cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
-   if ((cmd->hdr.command == IPA_CMD_SETIP) &&
-   (cmd->hdr.prot_version == QETH_PROT_IPV4)) {
+   if (cmd && cmd->hdr.command == IPA_CMD_SETIP &&
+   cmd->hdr.prot_version == QETH_PROT_IPV4) {
if (!wait_event_timeout(reply->wait_q,
atomic_read(>received), event_timeout))
goto time_err;




[PATCH 3.18 09/21] hdlc_ppp: carrier detect ok, dont turn off negotiation

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Denis Du 


[ Upstream commit b6c3bad1ba83af1062a7ff6986d9edc4f3d7fc8e ]

Sometimes when physical lines have a just good noise to make the protocol
handshaking fail, but the carrier detect still good. Then after remove of
the noise, nobody will trigger this protocol to be start again to cause
the link to never come back. The fix is when the carrier is still on, not
terminate the protocol handshaking.

Signed-off-by: Denis Du 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/net/wan/hdlc_ppp.c |5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -574,7 +574,10 @@ static void ppp_timer(unsigned long arg)
ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
 0, NULL);
proto->restart_counter--;
-   } else
+   } else if (netif_carrier_ok(proto->dev))
+   ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
+0, NULL);
+   else
ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0,
 0, NULL);
break;




[PATCH 3.18 13/21] ppp: prevent unregistered channels from connecting to PPP units

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Guillaume Nault 


[ Upstream commit 77f840e3e5f09c6d7d727e85e6e08276dd813d11 ]

PPP units don't hold any reference on the channels connected to it.
It is the channel's responsibility to ensure that it disconnects from
its unit before being destroyed.
In practice, this is ensured by ppp_unregister_channel() disconnecting
the channel from the unit before dropping a reference on the channel.

However, it is possible for an unregistered channel to connect to a PPP
unit: register a channel with ppp_register_net_channel(), attach a
/dev/ppp file to it with ioctl(PPPIOCATTCHAN), unregister the channel
with ppp_unregister_channel() and finally connect the /dev/ppp file to
a PPP unit with ioctl(PPPIOCCONNECT).

Once in this situation, the channel is only held by the /dev/ppp file,
which can be released at anytime and free the channel without letting
the parent PPP unit know. Then the ppp structure ends up with dangling
pointers in its ->channels list.

Prevent this scenario by forbidding unregistered channels from
connecting to PPP units. This maintains the code logic by keeping
ppp_unregister_channel() responsible from disconnecting the channel if
necessary and avoids modification on the reference counting mechanism.

This issue seems to predate git history (successfully reproduced on
Linux 2.6.26 and earlier PPP commits are unrelated).

Signed-off-by: Guillaume Nault 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/net/ppp/ppp_generic.c |9 +
 1 file changed, 9 insertions(+)

--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2908,6 +2908,15 @@ ppp_connect_channel(struct channel *pch,
goto outl;
 
ppp_lock(ppp);
+   spin_lock_bh(>downl);
+   if (!pch->chan) {
+   /* Don't connect unregistered channels */
+   spin_unlock_bh(>downl);
+   ppp_unlock(ppp);
+   ret = -ENOTCONN;
+   goto outl;
+   }
+   spin_unlock_bh(>downl);
if (pch->file.hdrlen > ppp->file.hdrlen)
ppp->file.hdrlen = pch->file.hdrlen;
hdrlen = pch->file.hdrlen + 2;  /* for protocol bytes */




[PATCH 3.18 13/21] ppp: prevent unregistered channels from connecting to PPP units

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Guillaume Nault 


[ Upstream commit 77f840e3e5f09c6d7d727e85e6e08276dd813d11 ]

PPP units don't hold any reference on the channels connected to it.
It is the channel's responsibility to ensure that it disconnects from
its unit before being destroyed.
In practice, this is ensured by ppp_unregister_channel() disconnecting
the channel from the unit before dropping a reference on the channel.

However, it is possible for an unregistered channel to connect to a PPP
unit: register a channel with ppp_register_net_channel(), attach a
/dev/ppp file to it with ioctl(PPPIOCATTCHAN), unregister the channel
with ppp_unregister_channel() and finally connect the /dev/ppp file to
a PPP unit with ioctl(PPPIOCCONNECT).

Once in this situation, the channel is only held by the /dev/ppp file,
which can be released at anytime and free the channel without letting
the parent PPP unit know. Then the ppp structure ends up with dangling
pointers in its ->channels list.

Prevent this scenario by forbidding unregistered channels from
connecting to PPP units. This maintains the code logic by keeping
ppp_unregister_channel() responsible from disconnecting the channel if
necessary and avoids modification on the reference counting mechanism.

This issue seems to predate git history (successfully reproduced on
Linux 2.6.26 and earlier PPP commits are unrelated).

Signed-off-by: Guillaume Nault 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/net/ppp/ppp_generic.c |9 +
 1 file changed, 9 insertions(+)

--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2908,6 +2908,15 @@ ppp_connect_channel(struct channel *pch,
goto outl;
 
ppp_lock(ppp);
+   spin_lock_bh(>downl);
+   if (!pch->chan) {
+   /* Don't connect unregistered channels */
+   spin_unlock_bh(>downl);
+   ppp_unlock(ppp);
+   ret = -ENOTCONN;
+   goto outl;
+   }
+   spin_unlock_bh(>downl);
if (pch->file.hdrlen > ppp->file.hdrlen)
ppp->file.hdrlen = pch->file.hdrlen;
hdrlen = pch->file.hdrlen + 2;  /* for protocol bytes */




Re: [PATCH] proc: reject "." and ".." as filenames

2018-03-09 Thread Florian Westphal
Alexey Dobriyan  wrote:
> Various subsystems can create files and directories in /proc
> with names directly controlled by userspace.
> 
> Which means "/", "." and ".." are no-no.
> 
> "/" split is already taken care of, do the other 2 prohibited names.

Acked-by: Florian Westphal 

I'll send a patch for xtables too to reject bogus names
coming from userspace (syzbot reports WARN() ).


Re: [PATCH] proc: reject "." and ".." as filenames

2018-03-09 Thread Florian Westphal
Alexey Dobriyan  wrote:
> Various subsystems can create files and directories in /proc
> with names directly controlled by userspace.
> 
> Which means "/", "." and ".." are no-no.
> 
> "/" split is already taken care of, do the other 2 prohibited names.

Acked-by: Florian Westphal 

I'll send a patch for xtables too to reject bogus names
coming from userspace (syzbot reports WARN() ).


[PATCH 3.18 17/21] s390/qeth: fix IPA command submission race

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Julian Wiedmann 


[ Upstream commit d22ffb5a712f9211ffd104c38fc17cbfb1b5e2b0 ]

If multiple IPA commands are build & sent out concurrently,
fill_ipacmd_header() may assign a seqno value to a command that's
different from what send_control_data() later assigns to this command's
reply.
This is due to other commands passing through send_control_data(),
and incrementing card->seqno.ipa along the way.

So one IPA command has no reply that's waiting for its seqno, while some
other IPA command has multiple reply objects waiting for it.
Only one of those waiting replies wins, and the other(s) times out and
triggers a recovery via send_ipa_cmd().

Fix this by making sure that the same seqno value is assigned to
a command and its reply object.
Do so immediately before submitting the command & while holding the
irq_pending "lock", to produce nicely ascending seqnos.

As a side effect, *all* IPA commands now use a reply object that's
waiting for its actual seqno. Previously, early IPA commands that were
submitted while the card was still DOWN used the "catch-all" IDX seqno.

Signed-off-by: Julian Wiedmann 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/s390/net/qeth_core_main.c |   19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2037,25 +2037,26 @@ int qeth_send_control_data(struct qeth_c
}
reply->callback = reply_cb;
reply->param = reply_param;
-   if (card->state == CARD_STATE_DOWN)
-   reply->seqno = QETH_IDX_COMMAND_SEQNO;
-   else
-   reply->seqno = card->seqno.ipa++;
+
init_waitqueue_head(>wait_q);
-   spin_lock_irqsave(>lock, flags);
-   list_add_tail(>list, >cmd_waiter_list);
-   spin_unlock_irqrestore(>lock, flags);
QETH_DBF_HEX(CTRL, 2, iob->data, QETH_DBF_CTRL_LEN);
 
while (atomic_cmpxchg(>write.irq_pending, 0, 1)) ;
-   qeth_prepare_control_data(card, len, iob);
 
if (IS_IPA(iob->data)) {
cmd = __ipa_cmd(iob);
+   cmd->hdr.seqno = card->seqno.ipa++;
+   reply->seqno = cmd->hdr.seqno;
event_timeout = QETH_IPA_TIMEOUT;
} else {
+   reply->seqno = QETH_IDX_COMMAND_SEQNO;
event_timeout = QETH_TIMEOUT;
}
+   qeth_prepare_control_data(card, len, iob);
+
+   spin_lock_irqsave(>lock, flags);
+   list_add_tail(>list, >cmd_waiter_list);
+   spin_unlock_irqrestore(>lock, flags);
 
timeout = jiffies + event_timeout;
 
@@ -2889,7 +2890,7 @@ static void qeth_fill_ipacmd_header(stru
memset(cmd, 0, sizeof(struct qeth_ipa_cmd));
cmd->hdr.command = command;
cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST;
-   cmd->hdr.seqno = card->seqno.ipa;
+   /* cmd->hdr.seqno is set by qeth_send_control_data() */
cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type);
cmd->hdr.rel_adapter_no = (__u8) card->info.portno;
if (card->options.layer2)




Re: [PATCH 4.4 00/36] 4.4.121-stable review

2018-03-09 Thread Nathan Chancellor
On Fri, Mar 09, 2018 at 04:18:16PM -0800, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.4.121 release.
> There are 36 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Mon Mar 12 00:17:54 UTC 2018.
> Anything received after that time might be too late.
> 
> The whole patch series can be found in one patch at:
>   
> https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.121-rc1.gz
> or in the git tree and branch at:
>   
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> linux-4.4.y
> and the diffstat can be found below.
> 
> thanks,
> 
> greg k-h
>

Merged, compiled, and flashed onto my Pixel 2 XL and OnePlus 5.

No merge conflicts and no visible issues in dmesg or general usage.

Thanks!
Nathan


[PATCH 3.18 17/21] s390/qeth: fix IPA command submission race

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Julian Wiedmann 


[ Upstream commit d22ffb5a712f9211ffd104c38fc17cbfb1b5e2b0 ]

If multiple IPA commands are build & sent out concurrently,
fill_ipacmd_header() may assign a seqno value to a command that's
different from what send_control_data() later assigns to this command's
reply.
This is due to other commands passing through send_control_data(),
and incrementing card->seqno.ipa along the way.

So one IPA command has no reply that's waiting for its seqno, while some
other IPA command has multiple reply objects waiting for it.
Only one of those waiting replies wins, and the other(s) times out and
triggers a recovery via send_ipa_cmd().

Fix this by making sure that the same seqno value is assigned to
a command and its reply object.
Do so immediately before submitting the command & while holding the
irq_pending "lock", to produce nicely ascending seqnos.

As a side effect, *all* IPA commands now use a reply object that's
waiting for its actual seqno. Previously, early IPA commands that were
submitted while the card was still DOWN used the "catch-all" IDX seqno.

Signed-off-by: Julian Wiedmann 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/s390/net/qeth_core_main.c |   19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -2037,25 +2037,26 @@ int qeth_send_control_data(struct qeth_c
}
reply->callback = reply_cb;
reply->param = reply_param;
-   if (card->state == CARD_STATE_DOWN)
-   reply->seqno = QETH_IDX_COMMAND_SEQNO;
-   else
-   reply->seqno = card->seqno.ipa++;
+
init_waitqueue_head(>wait_q);
-   spin_lock_irqsave(>lock, flags);
-   list_add_tail(>list, >cmd_waiter_list);
-   spin_unlock_irqrestore(>lock, flags);
QETH_DBF_HEX(CTRL, 2, iob->data, QETH_DBF_CTRL_LEN);
 
while (atomic_cmpxchg(>write.irq_pending, 0, 1)) ;
-   qeth_prepare_control_data(card, len, iob);
 
if (IS_IPA(iob->data)) {
cmd = __ipa_cmd(iob);
+   cmd->hdr.seqno = card->seqno.ipa++;
+   reply->seqno = cmd->hdr.seqno;
event_timeout = QETH_IPA_TIMEOUT;
} else {
+   reply->seqno = QETH_IDX_COMMAND_SEQNO;
event_timeout = QETH_TIMEOUT;
}
+   qeth_prepare_control_data(card, len, iob);
+
+   spin_lock_irqsave(>lock, flags);
+   list_add_tail(>list, >cmd_waiter_list);
+   spin_unlock_irqrestore(>lock, flags);
 
timeout = jiffies + event_timeout;
 
@@ -2889,7 +2890,7 @@ static void qeth_fill_ipacmd_header(stru
memset(cmd, 0, sizeof(struct qeth_ipa_cmd));
cmd->hdr.command = command;
cmd->hdr.initiator = IPA_CMD_INITIATOR_HOST;
-   cmd->hdr.seqno = card->seqno.ipa;
+   /* cmd->hdr.seqno is set by qeth_send_control_data() */
cmd->hdr.adapter_type = qeth_get_ipa_adp_type(card->info.link_type);
cmd->hdr.rel_adapter_no = (__u8) card->info.portno;
if (card->options.layer2)




Re: [PATCH 4.4 00/36] 4.4.121-stable review

2018-03-09 Thread Nathan Chancellor
On Fri, Mar 09, 2018 at 04:18:16PM -0800, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 4.4.121 release.
> There are 36 patches in this series, all will be posted as a response
> to this one.  If anyone has any issues with these being applied, please
> let me know.
> 
> Responses should be made by Mon Mar 12 00:17:54 UTC 2018.
> Anything received after that time might be too late.
> 
> The whole patch series can be found in one patch at:
>   
> https://www.kernel.org/pub/linux/kernel/v4.x/stable-review/patch-4.4.121-rc1.gz
> or in the git tree and branch at:
>   
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git 
> linux-4.4.y
> and the diffstat can be found below.
> 
> thanks,
> 
> greg k-h
>

Merged, compiled, and flashed onto my Pixel 2 XL and OnePlus 5.

No merge conflicts and no visible issues in dmesg or general usage.

Thanks!
Nathan


[PATCH 3.18 15/21] sctp: fix dst refcnt leak in sctp_v6_get_dst()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Alexey Kodanev 


[ Upstream commit 957d761cf91cdbb175ad7d8f5472336a4d54dbf2 ]

When going through the bind address list in sctp_v6_get_dst() and
the previously found address is better ('matchlen > bmatchlen'),
the code continues to the next iteration without releasing currently
held destination.

Fix it by releasing 'bdst' before continue to the next iteration, and
instead of introducing one more '!IS_ERR(bdst)' check for dst_release(),
move the already existed one right after ip6_dst_lookup_flow(), i.e. we
shouldn't proceed further if we get an error for the route lookup.

Fixes: dbc2b5e9a09e ("sctp: fix src address selection if using secondary 
addresses for ipv6")
Signed-off-by: Alexey Kodanev 
Acked-by: Neil Horman 
Acked-by: Marcelo Ricardo Leitner 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/sctp/ipv6.c |   10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -323,8 +323,10 @@ static void sctp_v6_get_dst(struct sctp_
final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), );
bdst = ip6_dst_lookup_flow(sk, fl6, final_p);
 
-   if (!IS_ERR(bdst) &&
-   ipv6_chk_addr(dev_net(bdst->dev),
+   if (IS_ERR(bdst))
+   continue;
+
+   if (ipv6_chk_addr(dev_net(bdst->dev),
  >a.v6.sin6_addr, bdst->dev, 1)) {
if (!IS_ERR_OR_NULL(dst))
dst_release(dst);
@@ -333,8 +335,10 @@ static void sctp_v6_get_dst(struct sctp_
}
 
bmatchlen = sctp_v6_addr_match_len(daddr, >a);
-   if (matchlen > bmatchlen)
+   if (matchlen > bmatchlen) {
+   dst_release(bdst);
continue;
+   }
 
if (!IS_ERR_OR_NULL(dst))
dst_release(dst);




[PATCH 3.18 15/21] sctp: fix dst refcnt leak in sctp_v6_get_dst()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Alexey Kodanev 


[ Upstream commit 957d761cf91cdbb175ad7d8f5472336a4d54dbf2 ]

When going through the bind address list in sctp_v6_get_dst() and
the previously found address is better ('matchlen > bmatchlen'),
the code continues to the next iteration without releasing currently
held destination.

Fix it by releasing 'bdst' before continue to the next iteration, and
instead of introducing one more '!IS_ERR(bdst)' check for dst_release(),
move the already existed one right after ip6_dst_lookup_flow(), i.e. we
shouldn't proceed further if we get an error for the route lookup.

Fixes: dbc2b5e9a09e ("sctp: fix src address selection if using secondary 
addresses for ipv6")
Signed-off-by: Alexey Kodanev 
Acked-by: Neil Horman 
Acked-by: Marcelo Ricardo Leitner 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/sctp/ipv6.c |   10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

--- a/net/sctp/ipv6.c
+++ b/net/sctp/ipv6.c
@@ -323,8 +323,10 @@ static void sctp_v6_get_dst(struct sctp_
final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), );
bdst = ip6_dst_lookup_flow(sk, fl6, final_p);
 
-   if (!IS_ERR(bdst) &&
-   ipv6_chk_addr(dev_net(bdst->dev),
+   if (IS_ERR(bdst))
+   continue;
+
+   if (ipv6_chk_addr(dev_net(bdst->dev),
  >a.v6.sin6_addr, bdst->dev, 1)) {
if (!IS_ERR_OR_NULL(dst))
dst_release(dst);
@@ -333,8 +335,10 @@ static void sctp_v6_get_dst(struct sctp_
}
 
bmatchlen = sctp_v6_addr_match_len(daddr, >a);
-   if (matchlen > bmatchlen)
+   if (matchlen > bmatchlen) {
+   dst_release(bdst);
continue;
+   }
 
if (!IS_ERR_OR_NULL(dst))
dst_release(dst);




[PATCH 3.18 19/21] net: ipv4: dont allow setting net.ipv4.route.min_pmtu below 68

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Sabrina Dubroca 


[ Upstream commit c7272c2f1229125f74f22dcdd59de9bbd804f1c8 ]

According to RFC 1191 sections 3 and 4, ICMP frag-needed messages
indicating an MTU below 68 should be rejected:

A host MUST never reduce its estimate of the Path MTU below 68
octets.

and (talking about ICMP frag-needed's Next-Hop MTU field):

This field will never contain a value less than 68, since every
router "must be able to forward a datagram of 68 octets without
fragmentation".

Furthermore, by letting net.ipv4.route.min_pmtu be set to negative
values, we can end up with a very large PMTU when (-1) is cast into u32.

Let's also make ip_rt_min_pmtu a u32, since it's only ever compared to
unsigned ints.

Reported-by: Jianlin Shi 
Signed-off-by: Sabrina Dubroca 
Reviewed-by: Stefano Brivio 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/ipv4/route.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -122,9 +122,11 @@ static int ip_rt_redirect_silence __read
 static int ip_rt_error_cost __read_mostly  = HZ;
 static int ip_rt_error_burst __read_mostly = 5 * HZ;
 static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ;
-static int ip_rt_min_pmtu __read_mostly= 512 + 20 + 20;
+static u32 ip_rt_min_pmtu __read_mostly= 512 + 20 + 20;
 static int ip_rt_min_advmss __read_mostly  = 256;
 
+static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU;
+
 /*
  * Interface to generic destination cache.
  */
@@ -2629,7 +2631,8 @@ static struct ctl_table ipv4_route_table
.data   = _rt_min_pmtu,
.maxlen = sizeof(int),
.mode   = 0644,
-   .proc_handler   = proc_dointvec,
+   .proc_handler   = proc_dointvec_minmax,
+   .extra1 = _min_valid_pmtu,
},
{
.procname   = "min_adv_mss",




[PATCH 3.18 20/21] fib_semantics: Dont match route with mismatching tclassid

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Stefano Brivio 


[ Upstream commit a8c6db1dfd1b1d18359241372bb204054f2c3174 ]

In fib_nh_match(), if output interface or gateway are passed in
the FIB configuration, we don't have to check next hops of
multipath routes to conclude whether we have a match or not.

However, we might still have routes with different realms
matching the same output interface and gateway configuration,
and this needs to cause the match to fail. Otherwise the first
route inserted in the FIB will match, regardless of the realms:

 # ip route add 1.1.1.1 dev eth0 table 1234 realms 1/2
 # ip route append 1.1.1.1 dev eth0 table 1234 realms 3/4
 # ip route list table 1234
 1.1.1.1 dev eth0 scope link realms 1/2
 1.1.1.1 dev eth0 scope link realms 3/4
 # ip route del 1.1.1.1 dev ens3 table 1234 realms 3/4
 # ip route list table 1234
 1.1.1.1 dev ens3 scope link realms 3/4

whereas route with realms 3/4 should have been deleted instead.

Explicitly check for fc_flow passed in the FIB configuration
(this comes from RTA_FLOW extracted by rtm_to_fib_config()) and
fail matching if it differs from nh_tclassid.

The handling of RTA_FLOW for multipath routes later in
fib_nh_match() is still needed, as we can have multiple RTA_FLOW
attributes that need to be matched against the tclassid of each
next hop.

v2: Check that fc_flow is set before discarding the match, so
that the user can still select the first matching rule by
not specifying any realm, as suggested by David Ahern.

Reported-by: Jianlin Shi 
Signed-off-by: Stefano Brivio 
Acked-by: David Ahern 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/ipv4/fib_semantics.c |5 +
 1 file changed, 5 insertions(+)

--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -514,6 +514,11 @@ int fib_nh_match(struct fib_config *cfg,
return 1;
 
if (cfg->fc_oif || cfg->fc_gw) {
+#ifdef CONFIG_IP_ROUTE_CLASSID
+   if (cfg->fc_flow &&
+   cfg->fc_flow != fi->fib_nh->nh_tclassid)
+   return 1;
+#endif
if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) &&
(!cfg->fc_gw  || cfg->fc_gw == fi->fib_nh->nh_gw))
return 0;




[PATCH 3.18 19/21] net: ipv4: dont allow setting net.ipv4.route.min_pmtu below 68

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Sabrina Dubroca 


[ Upstream commit c7272c2f1229125f74f22dcdd59de9bbd804f1c8 ]

According to RFC 1191 sections 3 and 4, ICMP frag-needed messages
indicating an MTU below 68 should be rejected:

A host MUST never reduce its estimate of the Path MTU below 68
octets.

and (talking about ICMP frag-needed's Next-Hop MTU field):

This field will never contain a value less than 68, since every
router "must be able to forward a datagram of 68 octets without
fragmentation".

Furthermore, by letting net.ipv4.route.min_pmtu be set to negative
values, we can end up with a very large PMTU when (-1) is cast into u32.

Let's also make ip_rt_min_pmtu a u32, since it's only ever compared to
unsigned ints.

Reported-by: Jianlin Shi 
Signed-off-by: Sabrina Dubroca 
Reviewed-by: Stefano Brivio 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/ipv4/route.c |7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -122,9 +122,11 @@ static int ip_rt_redirect_silence __read
 static int ip_rt_error_cost __read_mostly  = HZ;
 static int ip_rt_error_burst __read_mostly = 5 * HZ;
 static int ip_rt_mtu_expires __read_mostly = 10 * 60 * HZ;
-static int ip_rt_min_pmtu __read_mostly= 512 + 20 + 20;
+static u32 ip_rt_min_pmtu __read_mostly= 512 + 20 + 20;
 static int ip_rt_min_advmss __read_mostly  = 256;
 
+static int ip_min_valid_pmtu __read_mostly = IPV4_MIN_MTU;
+
 /*
  * Interface to generic destination cache.
  */
@@ -2629,7 +2631,8 @@ static struct ctl_table ipv4_route_table
.data   = _rt_min_pmtu,
.maxlen = sizeof(int),
.mode   = 0644,
-   .proc_handler   = proc_dointvec,
+   .proc_handler   = proc_dointvec_minmax,
+   .extra1 = _min_valid_pmtu,
},
{
.procname   = "min_adv_mss",




[PATCH 3.18 20/21] fib_semantics: Dont match route with mismatching tclassid

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Stefano Brivio 


[ Upstream commit a8c6db1dfd1b1d18359241372bb204054f2c3174 ]

In fib_nh_match(), if output interface or gateway are passed in
the FIB configuration, we don't have to check next hops of
multipath routes to conclude whether we have a match or not.

However, we might still have routes with different realms
matching the same output interface and gateway configuration,
and this needs to cause the match to fail. Otherwise the first
route inserted in the FIB will match, regardless of the realms:

 # ip route add 1.1.1.1 dev eth0 table 1234 realms 1/2
 # ip route append 1.1.1.1 dev eth0 table 1234 realms 3/4
 # ip route list table 1234
 1.1.1.1 dev eth0 scope link realms 1/2
 1.1.1.1 dev eth0 scope link realms 3/4
 # ip route del 1.1.1.1 dev ens3 table 1234 realms 3/4
 # ip route list table 1234
 1.1.1.1 dev ens3 scope link realms 3/4

whereas route with realms 3/4 should have been deleted instead.

Explicitly check for fc_flow passed in the FIB configuration
(this comes from RTA_FLOW extracted by rtm_to_fib_config()) and
fail matching if it differs from nh_tclassid.

The handling of RTA_FLOW for multipath routes later in
fib_nh_match() is still needed, as we can have multiple RTA_FLOW
attributes that need to be matched against the tclassid of each
next hop.

v2: Check that fc_flow is set before discarding the match, so
that the user can still select the first matching rule by
not specifying any realm, as suggested by David Ahern.

Reported-by: Jianlin Shi 
Signed-off-by: Stefano Brivio 
Acked-by: David Ahern 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/ipv4/fib_semantics.c |5 +
 1 file changed, 5 insertions(+)

--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -514,6 +514,11 @@ int fib_nh_match(struct fib_config *cfg,
return 1;
 
if (cfg->fc_oif || cfg->fc_gw) {
+#ifdef CONFIG_IP_ROUTE_CLASSID
+   if (cfg->fc_flow &&
+   cfg->fc_flow != fi->fib_nh->nh_tclassid)
+   return 1;
+#endif
if ((!cfg->fc_oif || cfg->fc_oif == fi->fib_nh->nh_oif) &&
(!cfg->fc_gw  || cfg->fc_gw == fi->fib_nh->nh_gw))
return 0;




[PATCH 4.4 01/36] tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the bus

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Jeremy Boone 

commit 6d24cd186d9fead3722108dec1b1c993354645ff upstream.

Discrete TPMs are often connected over slow serial buses which, on
some platforms, can have glitches causing bit flips.  In all the
driver _recv() functions, we need to use a u32 to unmarshal the
response size, otherwise a bit flip of the 31st bit would cause the
expected variable to go negative, which would then try to read a huge
amount of data.  Also sanity check that the expected amount of data is
large enough for the TPM header.

Signed-off-by: Jeremy Boone 
Cc: sta...@vger.kernel.org
Signed-off-by: James Bottomley 
Reviewed-by: Jarkko Sakkinen 
Signed-off-by: Jarkko Sakkinen 
Signed-off-by: James Morris 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/char/tpm/st33zp24/st33zp24.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -485,7 +485,7 @@ static int st33zp24_recv(struct tpm_chip
size_t count)
 {
int size = 0;
-   int expected;
+   u32 expected;
 
if (!chip)
return -EBUSY;
@@ -502,7 +502,7 @@ static int st33zp24_recv(struct tpm_chip
}
 
expected = be32_to_cpu(*(__be32 *)(buf + 2));
-   if (expected > count) {
+   if (expected > count || expected < TPM_HEADER_SIZE) {
size = -EIO;
goto out;
}




[PATCH 3.18 21/21] dm io: fix duplicate bio completion due to missing ref count

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Mike Snitzer 

commit feb7695fe9fb83084aa29de0094774f4c9d4c9fc upstream.

If only a subset of the devices associated with multiple regions support
a given special operation (eg. DISCARD) then the dec_count() that is
used to set error for the region must increment the io->count.

Otherwise, when the dec_count() is called it can cause the dm-io
caller's bio to be completed multiple times.  As was reported against
the dm-mirror target that had mirror legs with a mix of discard
capabilities.

Bug: https://bugzilla.kernel.org/show_bug.cgi?id=196077
Reported-by: Zhang Yi 
Signed-off-by: Mike Snitzer 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/md/dm-io.c |1 +
 1 file changed, 1 insertion(+)

--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -299,6 +299,7 @@ static void do_region(int rw, unsigned r
else if (rw & REQ_WRITE_SAME)
special_cmd_max_sectors = q->limits.max_write_same_sectors;
if ((rw & (REQ_DISCARD | REQ_WRITE_SAME)) && special_cmd_max_sectors == 
0) {
+   atomic_inc(>count);
dec_count(io, region, -EOPNOTSUPP);
return;
}




[PATCH 3.18 18/21] sctp: verify size of a new chunk in _sctp_make_chunk()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Alexey Kodanev 


[ Upstream commit 07f2c7ab6f8d0a7e7c5764c4e6cc9c52951b9d9c ]

When SCTP makes INIT or INIT_ACK packet the total chunk length
can exceed SCTP_MAX_CHUNK_LEN which leads to kernel panic when
transmitting these packets, e.g. the crash on sending INIT_ACK:

[  597.804948] skbuff: skb_over_panic: text:ffae06e4 len:120168
   put:120156 head:7aa47635 data:d991c2de
   tail:0x1d640 end:0xfec0 dev:
...
[  597.976970] [ cut here ]
[  598.033408] kernel BUG at net/core/skbuff.c:104!
[  600.314841] Call Trace:
[  600.345829]  
[  600.371639]  ? sctp_packet_transmit+0x2095/0x26d0 [sctp]
[  600.436934]  skb_put+0x16c/0x200
[  600.477295]  sctp_packet_transmit+0x2095/0x26d0 [sctp]
[  600.540630]  ? sctp_packet_config+0x890/0x890 [sctp]
[  600.601781]  ? __sctp_packet_append_chunk+0x3b4/0xd00 [sctp]
[  600.671356]  ? sctp_cmp_addr_exact+0x3f/0x90 [sctp]
[  600.731482]  sctp_outq_flush+0x663/0x30d0 [sctp]
[  600.788565]  ? sctp_make_init+0xbf0/0xbf0 [sctp]
[  600.84]  ? sctp_check_transmitted+0x18f0/0x18f0 [sctp]
[  600.912945]  ? sctp_outq_tail+0x631/0x9d0 [sctp]
[  600.969936]  sctp_cmd_interpreter.isra.22+0x3be1/0x5cb0 [sctp]
[  601.041593]  ? sctp_sf_do_5_1B_init+0x85f/0xc30 [sctp]
[  601.104837]  ? sctp_generate_t1_cookie_event+0x20/0x20 [sctp]
[  601.175436]  ? sctp_eat_data+0x1710/0x1710 [sctp]
[  601.233575]  sctp_do_sm+0x182/0x560 [sctp]
[  601.284328]  ? sctp_has_association+0x70/0x70 [sctp]
[  601.345586]  ? sctp_rcv+0xef4/0x32f0 [sctp]
[  601.397478]  ? sctp6_rcv+0xa/0x20 [sctp]
...

Here the chunk size for INIT_ACK packet becomes too big, mostly
because of the state cookie (INIT packet has large size with
many address parameters), plus additional server parameters.

Later this chunk causes the panic in skb_put_data():

  skb_packet_transmit()
  sctp_packet_pack()
  skb_put_data(nskb, chunk->skb->data, chunk->skb->len);

'nskb' (head skb) was previously allocated with packet->size
from u16 'chunk->chunk_hdr->length'.

As suggested by Marcelo we should check the chunk's length in
_sctp_make_chunk() before trying to allocate skb for it and
discard a chunk if its size bigger than SCTP_MAX_CHUNK_LEN.

Signed-off-by: Alexey Kodanev 
Acked-by: Marcelo Ricardo Leitner 
Acked-by: Neil Horman 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/sctp/sm_make_chunk.c |8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1367,10 +1367,14 @@ static struct sctp_chunk *_sctp_make_chu
sctp_chunkhdr_t *chunk_hdr;
struct sk_buff *skb;
struct sock *sk;
+   int chunklen;
+
+   chunklen = sizeof(*chunk_hdr) + paylen;
+   if (chunklen > SCTP_MAX_CHUNK_LEN)
+   goto nodata;
 
/* No need to allocate LL here, as this is only a chunk. */
-   skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen),
-   GFP_ATOMIC);
+   skb = alloc_skb(chunklen, GFP_ATOMIC);
if (!skb)
goto nodata;
 




[PATCH 4.4 01/36] tpm: st33zp24: fix potential buffer overruns caused by bit glitches on the bus

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Jeremy Boone 

commit 6d24cd186d9fead3722108dec1b1c993354645ff upstream.

Discrete TPMs are often connected over slow serial buses which, on
some platforms, can have glitches causing bit flips.  In all the
driver _recv() functions, we need to use a u32 to unmarshal the
response size, otherwise a bit flip of the 31st bit would cause the
expected variable to go negative, which would then try to read a huge
amount of data.  Also sanity check that the expected amount of data is
large enough for the TPM header.

Signed-off-by: Jeremy Boone 
Cc: sta...@vger.kernel.org
Signed-off-by: James Bottomley 
Reviewed-by: Jarkko Sakkinen 
Signed-off-by: Jarkko Sakkinen 
Signed-off-by: James Morris 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/char/tpm/st33zp24/st33zp24.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/drivers/char/tpm/st33zp24/st33zp24.c
+++ b/drivers/char/tpm/st33zp24/st33zp24.c
@@ -485,7 +485,7 @@ static int st33zp24_recv(struct tpm_chip
size_t count)
 {
int size = 0;
-   int expected;
+   u32 expected;
 
if (!chip)
return -EBUSY;
@@ -502,7 +502,7 @@ static int st33zp24_recv(struct tpm_chip
}
 
expected = be32_to_cpu(*(__be32 *)(buf + 2));
-   if (expected > count) {
+   if (expected > count || expected < TPM_HEADER_SIZE) {
size = -EIO;
goto out;
}




[PATCH 3.18 21/21] dm io: fix duplicate bio completion due to missing ref count

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Mike Snitzer 

commit feb7695fe9fb83084aa29de0094774f4c9d4c9fc upstream.

If only a subset of the devices associated with multiple regions support
a given special operation (eg. DISCARD) then the dec_count() that is
used to set error for the region must increment the io->count.

Otherwise, when the dec_count() is called it can cause the dm-io
caller's bio to be completed multiple times.  As was reported against
the dm-mirror target that had mirror legs with a mix of discard
capabilities.

Bug: https://bugzilla.kernel.org/show_bug.cgi?id=196077
Reported-by: Zhang Yi 
Signed-off-by: Mike Snitzer 
Signed-off-by: Greg Kroah-Hartman 

---
 drivers/md/dm-io.c |1 +
 1 file changed, 1 insertion(+)

--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -299,6 +299,7 @@ static void do_region(int rw, unsigned r
else if (rw & REQ_WRITE_SAME)
special_cmd_max_sectors = q->limits.max_write_same_sectors;
if ((rw & (REQ_DISCARD | REQ_WRITE_SAME)) && special_cmd_max_sectors == 
0) {
+   atomic_inc(>count);
dec_count(io, region, -EOPNOTSUPP);
return;
}




[PATCH 3.18 18/21] sctp: verify size of a new chunk in _sctp_make_chunk()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Alexey Kodanev 


[ Upstream commit 07f2c7ab6f8d0a7e7c5764c4e6cc9c52951b9d9c ]

When SCTP makes INIT or INIT_ACK packet the total chunk length
can exceed SCTP_MAX_CHUNK_LEN which leads to kernel panic when
transmitting these packets, e.g. the crash on sending INIT_ACK:

[  597.804948] skbuff: skb_over_panic: text:ffae06e4 len:120168
   put:120156 head:7aa47635 data:d991c2de
   tail:0x1d640 end:0xfec0 dev:
...
[  597.976970] [ cut here ]
[  598.033408] kernel BUG at net/core/skbuff.c:104!
[  600.314841] Call Trace:
[  600.345829]  
[  600.371639]  ? sctp_packet_transmit+0x2095/0x26d0 [sctp]
[  600.436934]  skb_put+0x16c/0x200
[  600.477295]  sctp_packet_transmit+0x2095/0x26d0 [sctp]
[  600.540630]  ? sctp_packet_config+0x890/0x890 [sctp]
[  600.601781]  ? __sctp_packet_append_chunk+0x3b4/0xd00 [sctp]
[  600.671356]  ? sctp_cmp_addr_exact+0x3f/0x90 [sctp]
[  600.731482]  sctp_outq_flush+0x663/0x30d0 [sctp]
[  600.788565]  ? sctp_make_init+0xbf0/0xbf0 [sctp]
[  600.84]  ? sctp_check_transmitted+0x18f0/0x18f0 [sctp]
[  600.912945]  ? sctp_outq_tail+0x631/0x9d0 [sctp]
[  600.969936]  sctp_cmd_interpreter.isra.22+0x3be1/0x5cb0 [sctp]
[  601.041593]  ? sctp_sf_do_5_1B_init+0x85f/0xc30 [sctp]
[  601.104837]  ? sctp_generate_t1_cookie_event+0x20/0x20 [sctp]
[  601.175436]  ? sctp_eat_data+0x1710/0x1710 [sctp]
[  601.233575]  sctp_do_sm+0x182/0x560 [sctp]
[  601.284328]  ? sctp_has_association+0x70/0x70 [sctp]
[  601.345586]  ? sctp_rcv+0xef4/0x32f0 [sctp]
[  601.397478]  ? sctp6_rcv+0xa/0x20 [sctp]
...

Here the chunk size for INIT_ACK packet becomes too big, mostly
because of the state cookie (INIT packet has large size with
many address parameters), plus additional server parameters.

Later this chunk causes the panic in skb_put_data():

  skb_packet_transmit()
  sctp_packet_pack()
  skb_put_data(nskb, chunk->skb->data, chunk->skb->len);

'nskb' (head skb) was previously allocated with packet->size
from u16 'chunk->chunk_hdr->length'.

As suggested by Marcelo we should check the chunk's length in
_sctp_make_chunk() before trying to allocate skb for it and
discard a chunk if its size bigger than SCTP_MAX_CHUNK_LEN.

Signed-off-by: Alexey Kodanev 
Acked-by: Marcelo Ricardo Leitner 
Acked-by: Neil Horman 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/sctp/sm_make_chunk.c |8 ++--
 1 file changed, 6 insertions(+), 2 deletions(-)

--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1367,10 +1367,14 @@ static struct sctp_chunk *_sctp_make_chu
sctp_chunkhdr_t *chunk_hdr;
struct sk_buff *skb;
struct sock *sk;
+   int chunklen;
+
+   chunklen = sizeof(*chunk_hdr) + paylen;
+   if (chunklen > SCTP_MAX_CHUNK_LEN)
+   goto nodata;
 
/* No need to allocate LL here, as this is only a chunk. */
-   skb = alloc_skb(WORD_ROUND(sizeof(sctp_chunkhdr_t) + paylen),
-   GFP_ATOMIC);
+   skb = alloc_skb(chunklen, GFP_ATOMIC);
if (!skb)
goto nodata;
 




[PATCH 3.18 12/21] netlink: ensure to loop over all netns in genlmsg_multicast_allns()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Nicolas Dichtel 


[ Upstream commit cb9f7a9a5c96a773bbc9c70660dc600cfff82f82 ]

Nowadays, nlmsg_multicast() returns only 0 or -ESRCH but this was not the
case when commit 134e63756d5f was pushed.
However, there was no reason to stop the loop if a netns does not have
listeners.
Returns -ESRCH only if there was no listeners in all netns.

To avoid having the same problem in the future, I didn't take the
assumption that nlmsg_multicast() returns only 0 or -ESRCH.

Fixes: 134e63756d5f ("genetlink: make netns aware")
CC: Johannes Berg 
Signed-off-by: Nicolas Dichtel 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/netlink/genetlink.c |   12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1058,6 +1058,7 @@ static int genlmsg_mcast(struct sk_buff
 {
struct sk_buff *tmp;
struct net *net, *prev = NULL;
+   bool delivered = false;
int err;
 
for_each_net_rcu(net) {
@@ -1069,14 +1070,21 @@ static int genlmsg_mcast(struct sk_buff
}
err = nlmsg_multicast(prev->genl_sock, tmp,
  portid, group, flags);
-   if (err)
+   if (!err)
+   delivered = true;
+   else if (err != -ESRCH)
goto error;
}
 
prev = net;
}
 
-   return nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
+   err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
+   if (!err)
+   delivered = true;
+   else if (err != -ESRCH)
+   goto error;
+   return delivered ? 0 : -ESRCH;
  error:
kfree_skb(skb);
return err;




[PATCH 3.18 12/21] netlink: ensure to loop over all netns in genlmsg_multicast_allns()

2018-03-09 Thread Greg Kroah-Hartman
3.18-stable review patch.  If anyone has any objections, please let me know.

--

From: Nicolas Dichtel 


[ Upstream commit cb9f7a9a5c96a773bbc9c70660dc600cfff82f82 ]

Nowadays, nlmsg_multicast() returns only 0 or -ESRCH but this was not the
case when commit 134e63756d5f was pushed.
However, there was no reason to stop the loop if a netns does not have
listeners.
Returns -ESRCH only if there was no listeners in all netns.

To avoid having the same problem in the future, I didn't take the
assumption that nlmsg_multicast() returns only 0 or -ESRCH.

Fixes: 134e63756d5f ("genetlink: make netns aware")
CC: Johannes Berg 
Signed-off-by: Nicolas Dichtel 
Signed-off-by: David S. Miller 
Signed-off-by: Greg Kroah-Hartman 
---
 net/netlink/genetlink.c |   12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1058,6 +1058,7 @@ static int genlmsg_mcast(struct sk_buff
 {
struct sk_buff *tmp;
struct net *net, *prev = NULL;
+   bool delivered = false;
int err;
 
for_each_net_rcu(net) {
@@ -1069,14 +1070,21 @@ static int genlmsg_mcast(struct sk_buff
}
err = nlmsg_multicast(prev->genl_sock, tmp,
  portid, group, flags);
-   if (err)
+   if (!err)
+   delivered = true;
+   else if (err != -ESRCH)
goto error;
}
 
prev = net;
}
 
-   return nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
+   err = nlmsg_multicast(prev->genl_sock, skb, portid, group, flags);
+   if (!err)
+   delivered = true;
+   else if (err != -ESRCH)
+   goto error;
+   return delivered ? 0 : -ESRCH;
  error:
kfree_skb(skb);
return err;




[PATCH 4.4 12/36] btrfs: Dont clear SGID when inheriting ACLs

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Jan Kara 

commit b7f8a09f8097db776b8d160862540e4fc1f51296 upstream.

When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
set, DIR1 is expected to have SGID bit set (and owning group equal to
the owning group of 'DIR0'). However when 'DIR0' also has some default
ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
'DIR1' to get cleared if user is not member of the owning group.

Fix the problem by moving posix_acl_update_mode() out of
__btrfs_set_acl() into btrfs_set_acl(). That way the function will not be
called when inheriting ACLs which is what we want as it prevents SGID
bit clearing and the mode has been properly set by posix_acl_create()
anyway.

Fixes: 073931017b49d9458aa351605b43a7e34598caef
CC: sta...@vger.kernel.org
CC: linux-bt...@vger.kernel.org
CC: David Sterba 
Signed-off-by: Jan Kara 
Signed-off-by: David Sterba 
Signed-off-by: Nikolay Borisov 
Signed-off-by: Greg Kroah-Hartman 
---
 fs/btrfs/acl.c |   13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -82,12 +82,6 @@ static int __btrfs_set_acl(struct btrfs_
switch (type) {
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
-   if (acl) {
-   ret = posix_acl_update_mode(inode, >i_mode, 
);
-   if (ret)
-   return ret;
-   }
-   ret = 0;
break;
case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode))
@@ -123,6 +117,13 @@ out:
 
 int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
+   int ret;
+
+   if (type == ACL_TYPE_ACCESS && acl) {
+   ret = posix_acl_update_mode(inode, >i_mode, );
+   if (ret)
+   return ret;
+   }
return __btrfs_set_acl(NULL, inode, acl, type);
 }
 




[PATCH 4.4 12/36] btrfs: Dont clear SGID when inheriting ACLs

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Jan Kara 

commit b7f8a09f8097db776b8d160862540e4fc1f51296 upstream.

When new directory 'DIR1' is created in a directory 'DIR0' with SGID bit
set, DIR1 is expected to have SGID bit set (and owning group equal to
the owning group of 'DIR0'). However when 'DIR0' also has some default
ACLs that 'DIR1' inherits, setting these ACLs will result in SGID bit on
'DIR1' to get cleared if user is not member of the owning group.

Fix the problem by moving posix_acl_update_mode() out of
__btrfs_set_acl() into btrfs_set_acl(). That way the function will not be
called when inheriting ACLs which is what we want as it prevents SGID
bit clearing and the mode has been properly set by posix_acl_create()
anyway.

Fixes: 073931017b49d9458aa351605b43a7e34598caef
CC: sta...@vger.kernel.org
CC: linux-bt...@vger.kernel.org
CC: David Sterba 
Signed-off-by: Jan Kara 
Signed-off-by: David Sterba 
Signed-off-by: Nikolay Borisov 
Signed-off-by: Greg Kroah-Hartman 
---
 fs/btrfs/acl.c |   13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -82,12 +82,6 @@ static int __btrfs_set_acl(struct btrfs_
switch (type) {
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
-   if (acl) {
-   ret = posix_acl_update_mode(inode, >i_mode, 
);
-   if (ret)
-   return ret;
-   }
-   ret = 0;
break;
case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode))
@@ -123,6 +117,13 @@ out:
 
 int btrfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
+   int ret;
+
+   if (type == ACL_TYPE_ACCESS && acl) {
+   ret = posix_acl_update_mode(inode, >i_mode, );
+   if (ret)
+   return ret;
+   }
return __btrfs_set_acl(NULL, inode, acl, type);
 }
 




[PATCH 4.4 14/36] x86/apic/vector: Handle legacy irq data correctly

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--


From: Thomas Gleixner 

The backport of upstream commit 45d55e7bac40 ("x86/apic/vector: Fix off by
one in error path") missed to fixup the legacy interrupt data which is not
longer available upstream.

Handle legacy irq data correctly by clearing the legacy storage to prevent
use after free.

Fixes: 7fd133539289 ("x86/apic/vector: Fix off by one in error path") - 4.4.y
Fixes: c557481a9491 ("x86/apic/vector: Fix off by one in error path") - 4.9.y
Reported-by: Ben Hutchings 
Signed-off-by: Thomas Gleixner 
Signed-off-by: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 
---
 arch/x86/kernel/apic/vector.c |   14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -91,8 +91,12 @@ out_data:
return NULL;
 }
 
-static void free_apic_chip_data(struct apic_chip_data *data)
+static void free_apic_chip_data(unsigned int virq, struct apic_chip_data *data)
 {
+#ifdef CONFIG_X86_IO_APIC
+   if (virq  < nr_legacy_irqs())
+   legacy_irq_data[virq] = NULL;
+#endif
if (data) {
free_cpumask_var(data->domain);
free_cpumask_var(data->old_domain);
@@ -316,11 +320,7 @@ static void x86_vector_free_irqs(struct
apic_data = irq_data->chip_data;
irq_domain_reset_irq_data(irq_data);
raw_spin_unlock_irqrestore(_lock, flags);
-   free_apic_chip_data(apic_data);
-#ifdef CONFIG_X86_IO_APIC
-   if (virq + i < nr_legacy_irqs())
-   legacy_irq_data[virq + i] = NULL;
-#endif
+   free_apic_chip_data(virq + i, apic_data);
}
}
 }
@@ -361,7 +361,7 @@ static int x86_vector_alloc_irqs(struct
err = assign_irq_vector_policy(virq + i, node, data, info);
if (err) {
irq_data->chip_data = NULL;
-   free_apic_chip_data(data);
+   free_apic_chip_data(virq + i, data);
goto error;
}
}




[PATCH 4.4 11/36] x86/syscall: Sanitize syscall table de-references under speculation fix

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Jiri Slaby 

In 4.4.118, we have commit c8961332d6da (x86/syscall: Sanitize syscall
table de-references under speculation), which is a backport of upstream
commit 2fbd7af5af86. But it fixed only the C part of the upstream patch
-- the IA32 sysentry. So it ommitted completely the assembly part -- the
64bit sysentry.

Fix that in this patch by explicit array_index_mask_nospec written in
assembly. The same was used in lib/getuser.S.

However, to have "sbb" working properly, we have to switch from "cmp"
against (NR_syscalls-1) to (NR_syscalls), otherwise the last syscall
number would be "and"ed by 0. It is because the original "ja" relies on
"CF" or "ZF", but we rely only on "CF" in "sbb". That means: switch to
"jae" conditional jump too.

Final note: use rcx for mask as this is exactly what is overwritten by
the 4th syscall argument (r10) right after.

Reported-by: Jan Beulich 
Cc: Linus Torvalds 
Cc: Dan Williams 
Cc: Thomas Gleixner 
Cc: linux-a...@vger.kernel.org
Cc: kernel-harden...@lists.openwall.com
Cc: gre...@linuxfoundation.org
Cc: Andy Lutomirski 
Cc: a...@linux.intel.com
Cc: Jinpu Wang 
Signed-off-by: Jiri Slaby 
Signed-off-by: Greg Kroah-Hartman 
---
 arch/x86/entry/entry_64.S |   16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -178,12 +178,14 @@ GLOBAL(entry_SYSCALL_64_after_swapgs)
jnz tracesys
 entry_SYSCALL_64_fastpath:
 #if __SYSCALL_MASK == ~0
-   cmpq$__NR_syscall_max, %rax
+   cmpq$NR_syscalls, %rax
 #else
andl$__SYSCALL_MASK, %eax
-   cmpl$__NR_syscall_max, %eax
+   cmpl$NR_syscalls, %eax
 #endif
-   ja  1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   jae 1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   sbb %rcx, %rcx  /* array_index_mask_nospec() */
+   and %rcx, %rax
movq%r10, %rcx
 #ifdef CONFIG_RETPOLINE
movqsys_call_table(, %rax, 8), %rax
@@ -276,12 +278,14 @@ tracesys_phase2:
RESTORE_C_REGS_EXCEPT_RAX
RESTORE_EXTRA_REGS
 #if __SYSCALL_MASK == ~0
-   cmpq$__NR_syscall_max, %rax
+   cmpq$NR_syscalls, %rax
 #else
andl$__SYSCALL_MASK, %eax
-   cmpl$__NR_syscall_max, %eax
+   cmpl$NR_syscalls, %eax
 #endif
-   ja  1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   jae 1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   sbb %rcx, %rcx  /* array_index_mask_nospec() */
+   and %rcx, %rax
movq%r10, %rcx  /* fixup for C */
 #ifdef CONFIG_RETPOLINE
movqsys_call_table(, %rax, 8), %rax




[PATCH 4.4 14/36] x86/apic/vector: Handle legacy irq data correctly

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--


From: Thomas Gleixner 

The backport of upstream commit 45d55e7bac40 ("x86/apic/vector: Fix off by
one in error path") missed to fixup the legacy interrupt data which is not
longer available upstream.

Handle legacy irq data correctly by clearing the legacy storage to prevent
use after free.

Fixes: 7fd133539289 ("x86/apic/vector: Fix off by one in error path") - 4.4.y
Fixes: c557481a9491 ("x86/apic/vector: Fix off by one in error path") - 4.9.y
Reported-by: Ben Hutchings 
Signed-off-by: Thomas Gleixner 
Signed-off-by: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 
---
 arch/x86/kernel/apic/vector.c |   14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -91,8 +91,12 @@ out_data:
return NULL;
 }
 
-static void free_apic_chip_data(struct apic_chip_data *data)
+static void free_apic_chip_data(unsigned int virq, struct apic_chip_data *data)
 {
+#ifdef CONFIG_X86_IO_APIC
+   if (virq  < nr_legacy_irqs())
+   legacy_irq_data[virq] = NULL;
+#endif
if (data) {
free_cpumask_var(data->domain);
free_cpumask_var(data->old_domain);
@@ -316,11 +320,7 @@ static void x86_vector_free_irqs(struct
apic_data = irq_data->chip_data;
irq_domain_reset_irq_data(irq_data);
raw_spin_unlock_irqrestore(_lock, flags);
-   free_apic_chip_data(apic_data);
-#ifdef CONFIG_X86_IO_APIC
-   if (virq + i < nr_legacy_irqs())
-   legacy_irq_data[virq + i] = NULL;
-#endif
+   free_apic_chip_data(virq + i, apic_data);
}
}
 }
@@ -361,7 +361,7 @@ static int x86_vector_alloc_irqs(struct
err = assign_irq_vector_policy(virq + i, node, data, info);
if (err) {
irq_data->chip_data = NULL;
-   free_apic_chip_data(data);
+   free_apic_chip_data(virq + i, data);
goto error;
}
}




[PATCH 4.4 11/36] x86/syscall: Sanitize syscall table de-references under speculation fix

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Jiri Slaby 

In 4.4.118, we have commit c8961332d6da (x86/syscall: Sanitize syscall
table de-references under speculation), which is a backport of upstream
commit 2fbd7af5af86. But it fixed only the C part of the upstream patch
-- the IA32 sysentry. So it ommitted completely the assembly part -- the
64bit sysentry.

Fix that in this patch by explicit array_index_mask_nospec written in
assembly. The same was used in lib/getuser.S.

However, to have "sbb" working properly, we have to switch from "cmp"
against (NR_syscalls-1) to (NR_syscalls), otherwise the last syscall
number would be "and"ed by 0. It is because the original "ja" relies on
"CF" or "ZF", but we rely only on "CF" in "sbb". That means: switch to
"jae" conditional jump too.

Final note: use rcx for mask as this is exactly what is overwritten by
the 4th syscall argument (r10) right after.

Reported-by: Jan Beulich 
Cc: Linus Torvalds 
Cc: Dan Williams 
Cc: Thomas Gleixner 
Cc: linux-a...@vger.kernel.org
Cc: kernel-harden...@lists.openwall.com
Cc: gre...@linuxfoundation.org
Cc: Andy Lutomirski 
Cc: a...@linux.intel.com
Cc: Jinpu Wang 
Signed-off-by: Jiri Slaby 
Signed-off-by: Greg Kroah-Hartman 
---
 arch/x86/entry/entry_64.S |   16 ++--
 1 file changed, 10 insertions(+), 6 deletions(-)

--- a/arch/x86/entry/entry_64.S
+++ b/arch/x86/entry/entry_64.S
@@ -178,12 +178,14 @@ GLOBAL(entry_SYSCALL_64_after_swapgs)
jnz tracesys
 entry_SYSCALL_64_fastpath:
 #if __SYSCALL_MASK == ~0
-   cmpq$__NR_syscall_max, %rax
+   cmpq$NR_syscalls, %rax
 #else
andl$__SYSCALL_MASK, %eax
-   cmpl$__NR_syscall_max, %eax
+   cmpl$NR_syscalls, %eax
 #endif
-   ja  1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   jae 1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   sbb %rcx, %rcx  /* array_index_mask_nospec() */
+   and %rcx, %rax
movq%r10, %rcx
 #ifdef CONFIG_RETPOLINE
movqsys_call_table(, %rax, 8), %rax
@@ -276,12 +278,14 @@ tracesys_phase2:
RESTORE_C_REGS_EXCEPT_RAX
RESTORE_EXTRA_REGS
 #if __SYSCALL_MASK == ~0
-   cmpq$__NR_syscall_max, %rax
+   cmpq$NR_syscalls, %rax
 #else
andl$__SYSCALL_MASK, %eax
-   cmpl$__NR_syscall_max, %eax
+   cmpl$NR_syscalls, %eax
 #endif
-   ja  1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   jae 1f  /* return -ENOSYS (already in 
pt_regs->ax) */
+   sbb %rcx, %rcx  /* array_index_mask_nospec() */
+   and %rcx, %rax
movq%r10, %rcx  /* fixup for C */
 #ifdef CONFIG_RETPOLINE
movqsys_call_table(, %rax, 8), %rax




[PATCH 4.4 16/36] x86/spectre: Fix an error message

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Dan Carpenter 

commit 9de29eac8d2189424d81c0d840cd0469aa3d41c8 upstream.

If i == ARRAY_SIZE(mitigation_options) then we accidentally print
garbage from one space beyond the end of the mitigation_options[] array.

Signed-off-by: Dan Carpenter 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: David Woodhouse 
Cc: Greg Kroah-Hartman 
Cc: KarimAllah Ahmed 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: kernel-janit...@vger.kernel.org
Fixes: 9005c6834c0f ("x86/spectre: Simplify spectre_v2 command line parsing")
Link: http://lkml.kernel.org/r/20180214071416.GA26677@mwanda
Signed-off-by: Ingo Molnar 
Cc: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 

---
 arch/x86/kernel/cpu/bugs.c |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -175,8 +175,7 @@ static enum spectre_v2_mitigation_cmd __
}
 
if (i >= ARRAY_SIZE(mitigation_options)) {
-   pr_err("unknown option (%s). Switching to AUTO 
select\n",
-  mitigation_options[i].option);
+   pr_err("unknown option (%s). Switching to AUTO 
select\n", arg);
return SPECTRE_V2_CMD_AUTO;
}
}




[PATCH 4.4 16/36] x86/spectre: Fix an error message

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Dan Carpenter 

commit 9de29eac8d2189424d81c0d840cd0469aa3d41c8 upstream.

If i == ARRAY_SIZE(mitigation_options) then we accidentally print
garbage from one space beyond the end of the mitigation_options[] array.

Signed-off-by: Dan Carpenter 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: David Woodhouse 
Cc: Greg Kroah-Hartman 
Cc: KarimAllah Ahmed 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Thomas Gleixner 
Cc: kernel-janit...@vger.kernel.org
Fixes: 9005c6834c0f ("x86/spectre: Simplify spectre_v2 command line parsing")
Link: http://lkml.kernel.org/r/20180214071416.GA26677@mwanda
Signed-off-by: Ingo Molnar 
Cc: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 

---
 arch/x86/kernel/cpu/bugs.c |3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

--- a/arch/x86/kernel/cpu/bugs.c
+++ b/arch/x86/kernel/cpu/bugs.c
@@ -175,8 +175,7 @@ static enum spectre_v2_mitigation_cmd __
}
 
if (i >= ARRAY_SIZE(mitigation_options)) {
-   pr_err("unknown option (%s). Switching to AUTO 
select\n",
-  mitigation_options[i].option);
+   pr_err("unknown option (%s). Switching to AUTO 
select\n", arg);
return SPECTRE_V2_CMD_AUTO;
}
}




[PATCH 4.4 17/36] Revert "led: core: Fix brightness setting when setting delay_off=0"

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Ben Hutchings 

This reverts commit 20ac8f72514b3af8b62c520d55656ded865eff00, which
was commit 2b83ff96f51d0b039c4561b9f95c824d7bddb85c upstream.
The bug that it should fix was only introduced in Linux 4.7, and
in 4.4 it causes a regression.

Reported-by: Jacek Anaszewski 
Cc: Matthieu CASTET 
Signed-off-by: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/leds/led-core.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -149,7 +149,7 @@ void led_blink_set(struct led_classdev *
   unsigned long *delay_on,
   unsigned long *delay_off)
 {
-   led_stop_software_blink(led_cdev);
+   del_timer_sync(_cdev->blink_timer);
 
led_cdev->flags &= ~LED_BLINK_ONESHOT;
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;




[PATCH 4.4 17/36] Revert "led: core: Fix brightness setting when setting delay_off=0"

2018-03-09 Thread Greg Kroah-Hartman
4.4-stable review patch.  If anyone has any objections, please let me know.

--

From: Ben Hutchings 

This reverts commit 20ac8f72514b3af8b62c520d55656ded865eff00, which
was commit 2b83ff96f51d0b039c4561b9f95c824d7bddb85c upstream.
The bug that it should fix was only introduced in Linux 4.7, and
in 4.4 it causes a regression.

Reported-by: Jacek Anaszewski 
Cc: Matthieu CASTET 
Signed-off-by: Ben Hutchings 
Signed-off-by: Greg Kroah-Hartman 
---
 drivers/leds/led-core.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/leds/led-core.c
+++ b/drivers/leds/led-core.c
@@ -149,7 +149,7 @@ void led_blink_set(struct led_classdev *
   unsigned long *delay_on,
   unsigned long *delay_off)
 {
-   led_stop_software_blink(led_cdev);
+   del_timer_sync(_cdev->blink_timer);
 
led_cdev->flags &= ~LED_BLINK_ONESHOT;
led_cdev->flags &= ~LED_BLINK_ONESHOT_STOP;




<    1   2   3   4   5   6   7   8   9   10   >