Merge remote-tracking branch 'caf/LA.BF64.1.2.3_rb1.9' into HEAD

Change-Id: I2391988ac82581b76333efe2f33c3ea722390cc2
This commit is contained in:
Olivier Karasangabo 2017-03-25 19:26:33 +01:00
commit 835d61c69a
No known key found for this signature in database
GPG Key ID: C5C93AF8ED1CCEB5
36 changed files with 943 additions and 614 deletions

View File

@ -610,6 +610,9 @@ unsigned long dma_alloc_from_contiguous(struct device *dev, size_t count,
if (!count)
return 0;
if (count > cma->count)
return 0;
mask = (1 << align) - 1;

View File

@ -835,9 +835,9 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
void *args;
remote_arg_t *pra = ctx->pra;
remote_arg_t *rpra = ctx->rpra;
ssize_t rlen, used, size;
ssize_t rlen, used, size, copylen = 0;
uint32_t sc = ctx->sc, start;
int i, inh, bufs = 0, err = 0, oix, copylen = 0;
int i, inh, bufs = 0, err = 0, oix;
int inbufs = REMOTE_SCALARS_INBUFS(sc);
int outbufs = REMOTE_SCALARS_OUTBUFS(sc);
int cid = ctx->fdata->cid;
@ -886,13 +886,23 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
/* calculate len requreed for copying */
for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix;
uintptr_t mstart, mend;
if (!pra[i].buf.len)
continue;
if (list[i].num)
continue;
if (ctx->overps[oix]->offset == 0)
copylen = ALIGN(copylen, BALIGN);
copylen += ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
mstart = ctx->overps[oix]->mstart;
mend = ctx->overps[oix]->mend;
VERIFY(err, (mend - mstart) <= LONG_MAX);
if (err)
goto bail;
copylen += mend - mstart;
VERIFY(err, copylen >= 0);
if (err)
goto bail;
}
/* alocate new buffer */
@ -918,7 +928,7 @@ static int get_args(uint32_t kernel, struct smq_invoke_ctx *ctx,
/* copy non ion buffers */
for (oix = 0; oix < inbufs + outbufs; ++oix) {
int i = ctx->overps[oix]->raix;
int mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
ssize_t mlen = ctx->overps[oix]->mend - ctx->overps[oix]->mstart;
if (!pra[i].buf.len)
continue;
if (list[i].num)

View File

@ -1456,6 +1456,15 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
pr_err("%s: Invalid byte offset\n", __func__);
goto error;
}
total = req->byteoffset;
for (i = 0; i < req->entries; i++) {
if (total > U32_MAX - req->vbuf.src[i].len) {
pr_err("%s:Integer overflow on total src len\n",
__func__);
goto error;
}
total += req->vbuf.src[i].len;
}
}
if (req->data_len < req->byteoffset) {
@ -1491,7 +1500,7 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
}
}
/* Check for sum of all dst length is equal to data_len */
for (i = 0; i < req->entries; i++) {
for (i = 0, total = 0; i < req->entries; i++) {
if (req->vbuf.dst[i].len >= U32_MAX - total) {
pr_err("%s: Integer overflow on total req dst vbuf length\n",
__func__);

View File

@ -258,6 +258,7 @@ struct synaptics_rmi4_fwu_handle {
bool interrupt_flag;
bool polling_mode;
char product_id[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
unsigned int full_update_size;
unsigned int image_size;
unsigned int data_pos;
unsigned char intr_mask;
@ -297,6 +298,22 @@ static struct synaptics_rmi4_fwu_handle *fwu;
DECLARE_COMPLETION(fwu_remove_complete);
DEFINE_MUTEX(fwu_sysfs_mutex);
/* Check offset + size <= bound. 1 if in bounds, 0 otherwise. */
static bool in_bounds(unsigned long offset,
unsigned long size,
unsigned long bound)
{
if (offset > bound || size > bound) {
pr_err("%s: %lu or %lu > %lu\n", __func__, offset, size, bound);
return 0;
}
if (offset > (bound - size)) {
pr_err("%s: %lu > %lu - %lu\n", __func__, offset, size, bound);
return 0;
}
return 1;
}
static unsigned int extract_uint(const unsigned char *ptr)
{
return (unsigned int)ptr[0] +
@ -333,11 +350,17 @@ static void synaptics_rmi4_update_debug_info(void)
pkg_id[3] << 8 | pkg_id[2], build_id);
}
static void parse_header(void)
static int parse_header(void)
{
struct image_content *img = &fwu->image_content;
struct image_header_data *data =
(struct image_header_data *)fwu->data_buffer;
if (fwu->full_update_size < sizeof(*data)) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
"Provided update too small");
return -EINVAL;
}
img->checksum = extract_uint(data->file_checksum);
img->bootloader_version = data->bootloader_version;
img->image_size = extract_uint(data->firmware_size);
@ -374,12 +397,29 @@ static void parse_header(void)
img->config_size);
/* get UI firmware offset */
if (img->image_size)
if (img->image_size) {
if (!in_bounds(FW_IMAGE_OFFSET, img->image_size,
fwu->full_update_size)) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
"%s: image size out of bounds\n",
__func__);
return -EINVAL;
}
img->firmware_data = fwu->data_buffer + FW_IMAGE_OFFSET;
}
/* get config offset*/
if (img->config_size)
if (img->config_size) {
// FW_IMAGE_OFFSET + image_size was ok as above
if (!in_bounds(FW_IMAGE_OFFSET + img->image_size,
img->config_size, fwu->full_update_size)) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
"%s: config size out of bounds\n",
__func__);
return -EINVAL;
}
img->config_data = fwu->data_buffer + FW_IMAGE_OFFSET +
img->image_size;
}
/* get lockdown offset*/
switch (img->bootloader_version) {
case 3:
@ -398,6 +438,14 @@ static void parse_header(void)
img->lockdown_data = NULL;
}
if (img->lockdown_block_count * fwu->block_size > FW_IMAGE_OFFSET) {
dev_err(&fwu->rmi4_data->i2c_client->dev,
"%s: lockdown size too big\n",
__func__);
return -EINVAL;
}
if (fwu->full_update_size < FW_IMAGE_OFFSET)
return -EINVAL;
img->lockdown_data = fwu->data_buffer +
FW_IMAGE_OFFSET -
img->lockdown_block_count * fwu->block_size;
@ -406,7 +454,7 @@ static void parse_header(void)
fwu->lockdown_data = img->lockdown_data;
fwu->config_data = img->config_data;
fwu->firmware_data = img->firmware_data;
return;
return 0;
}
static int fwu_read_f01_device_status(struct f01_device_status *status)
@ -1290,8 +1338,8 @@ static int fwu_start_write_config(void)
"%s: write config from config file\n",
__func__);
fwu->config_data = fwu->data_buffer;
} else {
parse_header();
} else if (parse_header()) {
return -EINVAL;
}
pr_notice("%s: Start of write config process\n", __func__);
@ -1358,7 +1406,8 @@ exit:
static int fwu_start_write_lockdown(void)
{
parse_header();
if (parse_header())
return -EINVAL;
return fwu_do_write_lockdown(true);
}
@ -1580,9 +1629,13 @@ static int fwu_start_reflash(void)
__func__, fw_entry->size);
fwu->data_buffer = fw_entry->data;
fwu->full_update_size = fw_entry->size;
}
parse_header();
if (parse_header()) {
retval = -EINVAL;
goto exit;
}
flash_area = fwu_go_nogo();
if (fwu->rmi4_data->sensor_sleep) {
@ -2021,6 +2074,7 @@ static ssize_t fwu_sysfs_image_size_store(struct device *dev,
if (!mutex_trylock(&fwu_sysfs_mutex))
return -EBUSY;
fwu->full_update_size = size;
fwu->image_size = size;
fwu->data_pos = 0;

View File

@ -1424,7 +1424,8 @@ static void cleanup_instance(struct msm_vidc_inst *inst)
debugfs_remove_recursive(inst->debugfs_root);
mutex_lock(&inst->pending_getpropq.lock);
WARN_ON(!list_empty(&inst->pending_getpropq.list));
WARN_ON(!list_empty(&inst->pending_getpropq.list)
&& (msm_vidc_debug & VIDC_INFO));
mutex_unlock(&inst->pending_getpropq.lock);
}
}

View File

@ -267,7 +267,7 @@ static int venus_hfi_acquire_regulator(struct regulator_info *rinfo)
rinfo->name);
}
}
WARN_ON(!regulator_is_enabled(rinfo->regulator));
WARN_ON(!regulator_is_enabled(rinfo->regulator) && (msm_vidc_debug & VIDC_INFO));
return rc;
}
@ -3975,7 +3975,7 @@ static int venus_hfi_disable_regulator(struct regulator_info *rinfo)
disable_regulator_failed:
/* Bring attention to this issue */
WARN_ON(1);
WARN_ON(msm_vidc_debug & VIDC_INFO);
return rc;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -87,6 +87,10 @@ int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la,
goto err;
}
if (!rx_num || rx_num > wcd9xxx->num_rx_port) {
pr_err("%s: invalid rx num %d\n", __func__, rx_num);
return -EINVAL;
}
if (wcd9xxx->rx_chs) {
wcd9xxx->num_rx_port = rx_num;
for (i = 0; i < rx_num; i++) {
@ -109,6 +113,10 @@ int wcd9xxx_init_slimslave(struct wcd9xxx *wcd9xxx, u8 wcd9xxx_pgd_la,
wcd9xxx->num_rx_port);
}
if (!tx_num || tx_num > wcd9xxx->num_tx_port) {
pr_err("%s: invalid tx num %d\n", __func__, tx_num);
return -EINVAL;
}
if (wcd9xxx->tx_chs) {
wcd9xxx->num_tx_port = tx_num;
for (i = 0; i < tx_num; i++) {

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -9,7 +9,6 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/debugfs.h>
#include <linux/errno.h>
#include <linux/etherdevice.h>
@ -106,10 +105,6 @@ enum ecm_ipa_operation {
* struct ecm_ipa_dev - main driver context parameters
* @net: network interface struct implemented by this driver
* @directory: debugfs directory for various debuging switches
* @tx_enable: flag that enable/disable Tx path to continue to IPA
* @rx_enable: flag that enable/disable Rx path to continue to IPA
* @rm_enable: flag that enable/disable Resource manager request prior to Tx
* @dma_enable: flag that allow on-the-fly DMA mode for IPA
* @eth_ipv4_hdr_hdl: saved handle for ipv4 header-insertion table
* @eth_ipv6_hdr_hdl: saved handle for ipv6 header-insertion table
* @usb_to_ipa_hdl: save handle for IPA pipe operations
@ -129,10 +124,6 @@ enum ecm_ipa_operation {
*/
struct ecm_ipa_dev {
struct net_device *net;
u32 tx_enable;
u32 rx_enable;
u32 rm_enable;
bool dma_enable;
struct dentry *directory;
uint32_t eth_ipv4_hdr_hdl;
uint32_t eth_ipv6_hdr_hdl;
@ -167,32 +158,16 @@ static void ecm_ipa_rm_notify(void *user_data, enum ipa_rm_event event,
static struct net_device_stats *ecm_ipa_get_stats(struct net_device *net);
static int ecm_ipa_create_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx);
static void ecm_ipa_destory_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx);
static bool rx_filter(struct sk_buff *skb);
static bool tx_filter(struct sk_buff *skb);
static bool rm_enabled(struct ecm_ipa_dev *ecm_ipa_ctx);
static int resource_request(struct ecm_ipa_dev *ecm_ipa_ctx);
static void resource_release(struct ecm_ipa_dev *ecm_ipa_ctx);
static netdev_tx_t ecm_ipa_start_xmit(struct sk_buff *skb,
struct net_device *net);
static int ecm_ipa_debugfs_stall_open(struct inode *inode,
struct file *file);
static ssize_t ecm_ipa_debugfs_stall_write(struct file *file,
const char __user *buf, size_t count, loff_t *ppos);
static int ecm_ipa_debugfs_atomic_open(struct inode *inode, struct file *file);
static ssize_t ecm_ipa_debugfs_enable_write_dma(struct file *file,
const char __user *buf, size_t count, loff_t *ppos);
static int ecm_ipa_debugfs_dma_open(struct inode *inode, struct file *file);
static ssize_t ecm_ipa_debugfs_enable_write(struct file *file,
const char __user *buf, size_t count, loff_t *ppos);
static ssize_t ecm_ipa_debugfs_enable_read(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos);
static ssize_t ecm_ipa_debugfs_atomic_read(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos);
static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx);
static void ecm_ipa_debugfs_destroy(struct ecm_ipa_dev *ecm_ipa_ctx);
static int ecm_ipa_ep_registers_cfg(u32 usb_to_ipa_hdl, u32 ipa_to_usb_hdl);
static int ecm_ipa_ep_registers_dma_cfg(u32 usb_to_ipa_hdl,
enum ipa_client_type prod_client);
static int ecm_ipa_set_device_ethernet_addr(u8 *dev_ethaddr,
u8 device_ethaddr[]);
static enum ecm_ipa_state ecm_ipa_next_state(enum ecm_ipa_state current_state,
@ -210,22 +185,11 @@ static const struct net_device_ops ecm_ipa_netdev_ops = {
.ndo_get_stats = ecm_ipa_get_stats,
};
const struct file_operations ecm_ipa_debugfs_dma_ops = {
.open = ecm_ipa_debugfs_dma_open,
.read = ecm_ipa_debugfs_enable_read,
.write = ecm_ipa_debugfs_enable_write_dma,
};
const struct file_operations ecm_ipa_debugfs_atomic_ops = {
.open = ecm_ipa_debugfs_atomic_open,
.read = ecm_ipa_debugfs_atomic_read,
};
const struct file_operations ecm_ipa_debugfs_stall_ops = {
.open = ecm_ipa_debugfs_stall_open,
.write = ecm_ipa_debugfs_stall_write,
};
static void ecm_ipa_msg_free_cb(void *buff, u32 len, u32 type)
{
kfree(buff);
@ -286,9 +250,6 @@ int ecm_ipa_init(struct ecm_ipa_params *params)
ECM_IPA_DEBUG("ecm_ipa_ctx (private) = %p\n", ecm_ipa_ctx);
ecm_ipa_ctx->net = net;
ecm_ipa_ctx->tx_enable = true;
ecm_ipa_ctx->rx_enable = true;
ecm_ipa_ctx->rm_enable = true;
ecm_ipa_ctx->outstanding_high = DEFAULT_OUTSTANDING_HIGH;
ecm_ipa_ctx->outstanding_low = DEFAULT_OUTSTANDING_LOW;
atomic_set(&ecm_ipa_ctx->outstanding_pkts, 0);
@ -604,12 +565,6 @@ static netdev_tx_t ecm_ipa_start_xmit(struct sk_buff *skb,
return NETDEV_TX_BUSY;
}
if (unlikely(tx_filter(skb))) {
dev_kfree_skb_any(skb);
ECM_IPA_DEBUG("packet got filtered out on Tx path\n");
status = NETDEV_TX_OK;
goto out;
}
ret = resource_request(ecm_ipa_ctx);
if (ret) {
ECM_IPA_DEBUG("Waiting to resource\n");
@ -681,11 +636,6 @@ static void ecm_ipa_packet_receive_notify(void *priv,
skb->dev = ecm_ipa_ctx->net;
skb->protocol = eth_type_trans(skb, ecm_ipa_ctx->net);
if (rx_filter(skb)) {
ECM_IPA_DEBUG("packet got filtered out on Rx path\n");
dev_kfree_skb_any(skb);
return;
}
result = netif_rx(skb);
if (result)
@ -1148,42 +1098,15 @@ static void ecm_ipa_destory_rm_resource(struct ecm_ipa_dev *ecm_ipa_ctx)
ECM_IPA_LOG_EXIT();
}
static bool rx_filter(struct sk_buff *skb)
{
struct ecm_ipa_dev *ecm_ipa_ctx = netdev_priv(skb->dev);
return !ecm_ipa_ctx->rx_enable;
}
static bool tx_filter(struct sk_buff *skb)
{
struct ecm_ipa_dev *ecm_ipa_ctx = netdev_priv(skb->dev);
return !ecm_ipa_ctx->tx_enable;
}
static bool rm_enabled(struct ecm_ipa_dev *ecm_ipa_ctx)
{
return ecm_ipa_ctx->rm_enable;
}
static int resource_request(struct ecm_ipa_dev *ecm_ipa_ctx)
{
int result = 0;
if (!rm_enabled(ecm_ipa_ctx))
goto out;
result = ipa_rm_inactivity_timer_request_resource(
IPA_RM_RESOURCE_STD_ECM_PROD);
out:
return result;
return ipa_rm_inactivity_timer_request_resource(
IPA_RM_RESOURCE_STD_ECM_PROD);
}
static void resource_release(struct ecm_ipa_dev *ecm_ipa_ctx)
{
if (!rm_enabled(ecm_ipa_ctx))
goto out;
ipa_rm_inactivity_timer_release_resource(IPA_RM_RESOURCE_STD_ECM_PROD);
out:
return;
}
/**
@ -1255,45 +1178,6 @@ static void ecm_ipa_tx_timeout(struct net_device *net)
net->stats.tx_errors++;
}
static int ecm_ipa_debugfs_stall_open(struct inode *inode,
struct file *file)
{
ECM_IPA_LOG_ENTRY();
ECM_IPA_LOG_EXIT();
return 0;
}
static ssize_t ecm_ipa_debugfs_stall_write(struct file *file,
const char __user *buf, size_t count, loff_t *ppos)
{
u32 cmdq_cfg_mmio_phy = 0xFD4E3038;
void *cmdq_cfg_mmio_virt;
int result;
bool val = 0;
ECM_IPA_LOG_ENTRY();
file->private_data = &val;
result = ecm_ipa_debugfs_enable_write(file, buf, count, ppos);
cmdq_cfg_mmio_virt = ioremap(cmdq_cfg_mmio_phy, sizeof(u32));
if (!cmdq_cfg_mmio_virt) {
ECM_IPA_ERROR("fail on mmio for cmdq_cfg_mmio_phy=0x%x",
cmdq_cfg_mmio_phy);
return result;
}
iowrite32(val, cmdq_cfg_mmio_virt);
ECM_IPA_DEBUG("Value %d was written to cfgq", val);
ECM_IPA_LOG_EXIT();
return result;
}
static int ecm_ipa_debugfs_atomic_open(struct inode *inode, struct file *file)
{
struct ecm_ipa_dev *ecm_ipa_ctx = inode->i_private;
@ -1303,78 +1187,6 @@ static int ecm_ipa_debugfs_atomic_open(struct inode *inode, struct file *file)
return 0;
}
static ssize_t ecm_ipa_debugfs_enable_write_dma(struct file *file,
const char __user *buf, size_t count, loff_t *ppos)
{
struct ecm_ipa_dev *ecm_ipa_ctx = file->private_data;
int result;
ECM_IPA_LOG_ENTRY();
file->private_data = &ecm_ipa_ctx->dma_enable;
result = ecm_ipa_debugfs_enable_write(file, buf, count, ppos);
if (ecm_ipa_ctx->dma_enable)
ecm_ipa_ep_registers_dma_cfg(ecm_ipa_ctx->usb_to_ipa_hdl,
ecm_ipa_ctx->ipa_to_usb_client);
else
ecm_ipa_ep_registers_cfg(ecm_ipa_ctx->usb_to_ipa_hdl,
ecm_ipa_ctx->usb_to_ipa_hdl);
ECM_IPA_LOG_EXIT();
return result;
}
static int ecm_ipa_debugfs_dma_open(struct inode *inode, struct file *file)
{
struct ecm_ipa_dev *ecm_ipa_ctx = inode->i_private;
ECM_IPA_LOG_ENTRY();
file->private_data = ecm_ipa_ctx;
ECM_IPA_LOG_EXIT();
return 0;
}
static ssize_t ecm_ipa_debugfs_enable_write(struct file *file,
const char __user *buf, size_t count, loff_t *ppos)
{
unsigned long missing;
char input;
bool *enable = file->private_data;
if (count != sizeof(input) + 1) {
ECM_IPA_ERROR("wrong input length(%zd)\n", count);
return -EINVAL;
}
if (!buf) {
ECM_IPA_ERROR("Bad argument\n");
return -EINVAL;
}
missing = copy_from_user(&input, buf, 1);
if (missing)
return -EFAULT;
ECM_IPA_DEBUG("input received %c\n", input);
*enable = input - '0';
ECM_IPA_DEBUG("value was set to %d\n", *enable);
return count;
}
static ssize_t ecm_ipa_debugfs_enable_read(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos)
{
int nbytes;
int size = 0;
int ret;
loff_t pos;
u8 enable_str[sizeof(char)*3] = {0};
bool *enable = file->private_data;
pos = *ppos;
nbytes = scnprintf(enable_str, sizeof(enable_str), "%d\n", *enable);
ret = simple_read_from_buffer(ubuf, count, ppos, enable_str, nbytes);
if (ret < 0) {
ECM_IPA_ERROR("simple_read_from_buffer problem\n");
return ret;
}
size += ret;
count -= nbytes;
*ppos = pos + size;
return size;
}
static ssize_t ecm_ipa_debugfs_atomic_read(struct file *file,
char __user *ubuf, size_t count, loff_t *ppos)
{
@ -1391,7 +1203,6 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
{
const mode_t flags_read_write = S_IRUGO | S_IWUGO;
const mode_t flags_read_only = S_IRUGO;
const mode_t flags_write_only = S_IWUGO;
struct dentry *file;
ECM_IPA_LOG_ENTRY();
@ -1404,24 +1215,6 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
ECM_IPA_ERROR("could not create debugfs directory entry\n");
goto fail_directory;
}
file = debugfs_create_bool("tx_enable", flags_read_write,
ecm_ipa_ctx->directory, &ecm_ipa_ctx->tx_enable);
if (!file) {
ECM_IPA_ERROR("could not create debugfs tx file\n");
goto fail_file;
}
file = debugfs_create_bool("rx_enable", flags_read_write,
ecm_ipa_ctx->directory, &ecm_ipa_ctx->rx_enable);
if (!file) {
ECM_IPA_ERROR("could not create debugfs rx file\n");
goto fail_file;
}
file = debugfs_create_bool("rm_enable", flags_read_write,
ecm_ipa_ctx->directory, &ecm_ipa_ctx->rm_enable);
if (!file) {
ECM_IPA_ERROR("could not create debugfs rm file\n");
goto fail_file;
}
file = debugfs_create_u8("outstanding_high", flags_read_write,
ecm_ipa_ctx->directory, &ecm_ipa_ctx->outstanding_high);
if (!file) {
@ -1434,13 +1227,6 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
ECM_IPA_ERROR("could not create outstanding_low file\n");
goto fail_file;
}
file = debugfs_create_file("dma_enable", flags_read_write,
ecm_ipa_ctx->directory,
ecm_ipa_ctx, &ecm_ipa_debugfs_dma_ops);
if (!file) {
ECM_IPA_ERROR("could not create debugfs dma file\n");
goto fail_file;
}
file = debugfs_create_file("outstanding", flags_read_only,
ecm_ipa_ctx->directory,
ecm_ipa_ctx, &ecm_ipa_debugfs_atomic_ops);
@ -1449,14 +1235,7 @@ static int ecm_ipa_debugfs_init(struct ecm_ipa_dev *ecm_ipa_ctx)
goto fail_file;
}
file = debugfs_create_file("stall_ipa_rx_proc", flags_write_only,
ecm_ipa_ctx->directory,
ecm_ipa_ctx, &ecm_ipa_debugfs_stall_ops);
if (!file) {
ECM_IPA_ERROR("could not create stall_ipa_rx_proc file\n");
goto fail_file;
}
ECM_IPA_DEBUG("debugfs entries were created\n");
ECM_IPA_LOG_EXIT();
return 0;
@ -1519,46 +1298,6 @@ out:
return result;
}
/**
* ecm_ipa_ep_registers_dma_cfg() - configure the USB endpoints for ECM
* DMA
* @usb_to_ipa_hdl: handle received from ipa_connect
*
* This function will override the previous configuration
* which is needed for cores that does not support blocks logic
* Note that client handles are the actual pipe index
*/
static int ecm_ipa_ep_registers_dma_cfg(u32 usb_to_ipa_hdl,
enum ipa_client_type prod_client)
{
int result = 0;
struct ipa_ep_cfg_mode cfg_mode;
u32 apps_to_ipa_hdl = 2;
ECM_IPA_LOG_ENTRY();
memset(&cfg_mode, 0 , sizeof(cfg_mode));
cfg_mode.mode = IPA_DMA;
cfg_mode.dst = prod_client;
result = ipa_cfg_ep_mode(apps_to_ipa_hdl, &cfg_mode);
if (result) {
ECM_IPA_ERROR("failed to configure Apps to IPA\n");
goto out;
}
memset(&cfg_mode, 0 , sizeof(cfg_mode));
cfg_mode.mode = IPA_DMA;
cfg_mode.dst = IPA_CLIENT_A5_LAN_WAN_CONS;
result = ipa_cfg_ep_mode(usb_to_ipa_hdl, &cfg_mode);
if (result) {
ECM_IPA_ERROR("failed to configure USB to IPA\n");
goto out;
}
ECM_IPA_DEBUG("end-point registers successfully configured\n");
out:
ECM_IPA_LOG_EXIT();
return result;
}
/**
* ecm_ipa_set_device_ethernet_addr() - set device etherenet address
* @dev_ethaddr: device etherenet address

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -436,7 +436,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
retval = -EFAULT;
break;
}
if (ipa_del_hdr((struct ipa_ioc_del_hdr *)param)) {
if (ipa_del_hdr_by_user((struct ipa_ioc_del_hdr *)param,
true)) {
retval = -EFAULT;
break;
}
@ -1117,8 +1118,8 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
retval = -EFAULT;
break;
}
if (ipa_del_hdr_proc_ctx(
(struct ipa_ioc_del_hdr_proc_ctx *)param)) {
if (ipa_del_hdr_proc_ctx_by_user(
(struct ipa_ioc_del_hdr_proc_ctx *)param, true)) {
retval = -EFAULT;
break;
}
@ -2271,7 +2272,7 @@ fail_schedule_delayed_work:
if (ipa_ctx->dflt_v4_rt_rule_hdl)
__ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl);
if (ipa_ctx->excp_hdr_hdl)
__ipa_del_hdr(ipa_ctx->excp_hdr_hdl);
__ipa_del_hdr(ipa_ctx->excp_hdr_hdl, false);
ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd);
fail_cmd:
return result;
@ -2283,7 +2284,7 @@ static void ipa_teardown_apps_pipes(void)
ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_data_in);
__ipa_del_rt_rule(ipa_ctx->dflt_v6_rt_rule_hdl);
__ipa_del_rt_rule(ipa_ctx->dflt_v4_rt_rule_hdl);
__ipa_del_hdr(ipa_ctx->excp_hdr_hdl);
__ipa_del_hdr(ipa_ctx->excp_hdr_hdl, false);
ipa_teardown_sys_pipe(ipa_ctx->clnt_hdl_cmd);
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -719,7 +719,8 @@ error:
return -EPERM;
}
static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr)
static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl,
bool release_hdr, bool by_user)
{
struct ipa_hdr_proc_ctx_entry *entry;
struct ipa_hdr_proc_ctx_tbl *htbl = &ipa_ctx->hdr_proc_ctx_tbl;
@ -733,6 +734,14 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr)
IPADBG("del ctx proc cnt=%d ofst=%d\n",
htbl->proc_ctx_cnt, entry->offset_entry->offset);
if (by_user && entry->user_deleted) {
IPAERR("proc_ctx already deleted by user\n");
return -EINVAL;
}
if (by_user)
entry->user_deleted = true;
if (--entry->ref_cnt) {
IPADBG("proc_ctx_hdl %x ref_cnt %d\n",
proc_ctx_hdl, entry->ref_cnt);
@ -740,7 +749,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr)
}
if (release_hdr)
__ipa_release_hdr(entry->hdr->id);
__ipa_del_hdr(entry->hdr->id, false);
/* move the offset entry to appropriate free list */
list_move(&entry->offset_entry->link,
@ -757,7 +766,7 @@ static int __ipa_del_hdr_proc_ctx(u32 proc_ctx_hdl, bool release_hdr)
}
int __ipa_del_hdr(u32 hdr_hdl)
int __ipa_del_hdr(u32 hdr_hdl, bool by_user)
{
struct ipa_hdr_entry *entry;
struct ipa_hdr_tbl *htbl = &ipa_ctx->hdr_tbl;
@ -776,6 +785,14 @@ int __ipa_del_hdr(u32 hdr_hdl)
IPADBG("del hdr of sz=%d hdr_cnt=%d ofst=%d\n", entry->hdr_len,
htbl->hdr_cnt, entry->offset_entry->offset);
if (by_user && entry->user_deleted) {
IPAERR("hdr already deleted by user\n");
return -EINVAL;
}
if (by_user)
entry->user_deleted = true;
if (--entry->ref_cnt) {
IPADBG("hdr_hdl %x ref_cnt %d\n", hdr_hdl, entry->ref_cnt);
return 0;
@ -786,7 +803,7 @@ int __ipa_del_hdr(u32 hdr_hdl)
entry->phys_base,
entry->hdr_len,
DMA_TO_DEVICE);
__ipa_del_hdr_proc_ctx(entry->proc_ctx->id, false);
__ipa_del_hdr_proc_ctx(entry->proc_ctx->id, false, false);
} else {
/* move the offset entry to appropriate free list */
list_move(&entry->offset_entry->link,
@ -849,15 +866,16 @@ bail:
EXPORT_SYMBOL(ipa_add_hdr);
/**
* ipa_del_hdr() - Remove the specified headers from SW and optionally commit them
* to IPA HW
* ipa_del_hdr_by_user() - Remove the specified headers
* from SW and optionally commit them to IPA HW
* @hdls: [inout] set of headers to delete
* @by_user: Operation requested by user?
*
* Returns: 0 on success, negative on failure
*
* Note: Should not be called from atomic context
*/
int ipa_del_hdr(struct ipa_ioc_del_hdr *hdls)
int ipa_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user)
{
int i;
int result = -EFAULT;
@ -869,7 +887,7 @@ int ipa_del_hdr(struct ipa_ioc_del_hdr *hdls)
mutex_lock(&ipa_ctx->lock);
for (i = 0; i < hdls->num_hdls; i++) {
if (__ipa_del_hdr(hdls->hdl[i].hdl)) {
if (__ipa_del_hdr(hdls->hdl[i].hdl, by_user)) {
IPAERR("failed to del hdr %i\n", i);
hdls->hdl[i].status = -1;
} else {
@ -888,6 +906,20 @@ bail:
mutex_unlock(&ipa_ctx->lock);
return result;
}
/**
* ipa_del_hdr() - Remove the specified headers from SW and optionally commit them
* to IPA HW
* @hdls: [inout] set of headers to delete
*
* Returns: 0 on success, negative on failure
*
* Note: Should not be called from atomic context
*/
int ipa_del_hdr(struct ipa_ioc_del_hdr *hdls)
{
return ipa_del_hdr_by_user(hdls, false);
}
EXPORT_SYMBOL(ipa_del_hdr);
/**
@ -936,16 +968,18 @@ bail:
EXPORT_SYMBOL(ipa_add_hdr_proc_ctx);
/**
* ipa_del_hdr_proc_ctx() -
* ipa_del_hdr_proc_ctx_by_user() -
* Remove the specified processing context headers from SW and
* optionally commit them to IPA HW.
* @hdls: [inout] set of processing context headers to delete
* @by_user: Operation requested by user?
*
* Returns: 0 on success, negative on failure
*
* Note: Should not be called from atomic context
*/
int ipa_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls)
int ipa_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls,
bool by_user)
{
int i;
int result;
@ -957,7 +991,7 @@ int ipa_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls)
mutex_lock(&ipa_ctx->lock);
for (i = 0; i < hdls->num_hdls; i++) {
if (__ipa_del_hdr_proc_ctx(hdls->hdl[i].hdl, true)) {
if (__ipa_del_hdr_proc_ctx(hdls->hdl[i].hdl, true, by_user)) {
IPAERR("failed to del hdr %i\n", i);
hdls->hdl[i].status = -1;
} else {
@ -976,6 +1010,21 @@ bail:
mutex_unlock(&ipa_ctx->lock);
return result;
}
/**
* ipa_del_hdr_proc_ctx() -
* Remove the specified processing context headers from SW and
* optionally commit them to IPA HW.
* @hdls: [inout] set of processing context headers to delete
*
* Returns: 0 on success, negative on failure
*
* Note: Should not be called from atomic context
*/
int ipa_del_hdr_proc_ctx(struct ipa_ioc_del_hdr_proc_ctx *hdls)
{
return ipa_del_hdr_proc_ctx_by_user(hdls, false);
}
EXPORT_SYMBOL(ipa_del_hdr_proc_ctx);
/**
@ -1197,7 +1246,7 @@ int __ipa_release_hdr(u32 hdr_hdl)
{
int result = 0;
if (__ipa_del_hdr(hdr_hdl)) {
if (__ipa_del_hdr(hdr_hdl, false)) {
IPADBG("fail to del hdr %x\n", hdr_hdl);
result = -EFAULT;
goto bail;
@ -1225,7 +1274,7 @@ int __ipa_release_hdr_proc_ctx(u32 proc_ctx_hdl)
{
int result = 0;
if (__ipa_del_hdr_proc_ctx(proc_ctx_hdl, true)) {
if (__ipa_del_hdr_proc_ctx(proc_ctx_hdl, true, false)) {
IPADBG("fail to del hdr %x\n", proc_ctx_hdl);
result = -EFAULT;
goto bail;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -226,6 +226,7 @@ struct ipa_rt_tbl {
* @id: header entry id
* @is_eth2_ofst_valid: is eth2_ofst field valid?
* @eth2_ofst: offset to start of Ethernet-II/802.3 header
* @user_deleted: is the header deleted by the user?
*/
struct ipa_hdr_entry {
struct list_head link;
@ -243,6 +244,7 @@ struct ipa_hdr_entry {
int id;
u8 is_eth2_ofst_valid;
u16 eth2_ofst;
bool user_deleted;
};
/**
@ -318,6 +320,7 @@ struct ipa_hdr_proc_ctx_add_hdr_cmd_seq {
* @cookie: cookie used for validity check
* @ref_cnt: reference counter of routing table
* @id: processing context header entry id
* @user_deleted: is the hdr processing context deleted by the user?
*/
struct ipa_hdr_proc_ctx_entry {
struct list_head link;
@ -327,6 +330,7 @@ struct ipa_hdr_proc_ctx_entry {
u32 cookie;
u32 ref_cnt;
int id;
bool user_deleted;
};
/**
@ -1410,8 +1414,11 @@ void ipa_inc_client_enable_clks(void);
int ipa_inc_client_enable_clks_no_block(void);
void ipa_dec_client_disable_clks(void);
int ipa_interrupts_init(u32 ipa_irq, u32 ee, struct device *ipa_dev);
int ipa_del_hdr_by_user(struct ipa_ioc_del_hdr *hdls, bool by_user);
int ipa_del_hdr_proc_ctx_by_user(struct ipa_ioc_del_hdr_proc_ctx *hdls,
bool by_user);
int __ipa_del_rt_rule(u32 rule_hdl);
int __ipa_del_hdr(u32 hdr_hdl);
int __ipa_del_hdr(u32 hdr_hdl, bool by_user);
int __ipa_release_hdr(u32 hdr_hdl);
int __ipa_release_hdr_proc_ctx(u32 proc_ctx_hdl);
int _ipa_read_gen_reg_v1_1(char *buff, int max_len);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -217,12 +217,14 @@ static int __init pft_lsm_init(struct pft_device *dev)
ret = register_security(&pft_security_ops);
if (ret) {
pr_err("pft lsm registeration failed, ret=%d.\n", ret);
return 0;
return ret;
}
dev->is_chosen_lsm = true;
pr_debug("pft is the chosen lsm, registered sucessfully !\n");
} else {
pr_debug("pft is not the chosen lsm.\n");
pr_err("pft is not the chosen lsm.\n");
return -ENODEV;
}
return 0;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -509,6 +509,7 @@ struct fg_trans {
struct fg_chip *chip;
struct fg_log_buffer *log; /* log buffer */
u8 *data; /* fg data that is read */
struct mutex memif_dfs_lock; /* Prevent thread concurrency */
};
struct fg_dbgfs {
@ -4924,6 +4925,7 @@ static int fg_memif_data_open(struct inode *inode, struct file *file)
trans->addr = dbgfs_data.addr;
trans->chip = dbgfs_data.chip;
trans->offset = trans->addr;
mutex_init(&trans->memif_dfs_lock);
file->private_data = trans;
return 0;
@ -4935,6 +4937,7 @@ static int fg_memif_dfs_close(struct inode *inode, struct file *file)
if (trans && trans->log && trans->data) {
file->private_data = NULL;
mutex_destroy(&trans->memif_dfs_lock);
kfree(trans->log);
kfree(trans->data);
kfree(trans);
@ -5092,10 +5095,13 @@ static ssize_t fg_memif_dfs_reg_read(struct file *file, char __user *buf,
size_t ret;
size_t len;
mutex_lock(&trans->memif_dfs_lock);
/* Is the the log buffer empty */
if (log->rpos >= log->wpos) {
if (get_log_data(trans) <= 0)
return 0;
if (get_log_data(trans) <= 0) {
len = 0;
goto unlock_mutex;
}
}
len = min(count, log->wpos - log->rpos);
@ -5103,7 +5109,8 @@ static ssize_t fg_memif_dfs_reg_read(struct file *file, char __user *buf,
ret = copy_to_user(buf, &log->data[log->rpos], len);
if (ret == len) {
pr_err("error copy sram register values to user\n");
return -EFAULT;
len = -EFAULT;
goto unlock_mutex;
}
/* 'ret' is the number of bytes not copied */
@ -5111,6 +5118,9 @@ static ssize_t fg_memif_dfs_reg_read(struct file *file, char __user *buf,
*ppos += len;
log->rpos += len;
unlock_mutex:
mutex_unlock(&trans->memif_dfs_lock);
return len;
}
@ -5131,14 +5141,20 @@ static ssize_t fg_memif_dfs_reg_write(struct file *file, const char __user *buf,
int cnt = 0;
u8 *values;
size_t ret = 0;
char *kbuf;
u32 offset;
struct fg_trans *trans = file->private_data;
u32 offset = trans->offset;
mutex_lock(&trans->memif_dfs_lock);
offset = trans->offset;
/* Make a copy of the user data */
char *kbuf = kmalloc(count + 1, GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
kbuf = kmalloc(count + 1, GFP_KERNEL);
if (!kbuf) {
ret = -ENOMEM;
goto unlock_mutex;
}
ret = copy_from_user(kbuf, buf, count);
if (ret == count) {
@ -5177,6 +5193,8 @@ static ssize_t fg_memif_dfs_reg_write(struct file *file, const char __user *buf,
free_buf:
kfree(kbuf);
unlock_mutex:
mutex_unlock(&trans->memif_dfs_lock);
return ret;
}

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -985,8 +985,9 @@ int subsystem_restart_dev(struct subsys_device *dev)
pr_info("Restart sequence requested for %s, restart_level = %s.\n",
name, restart_levels[dev->restart_level]);
if (WARN(disable_restart_work == DISABLE_SSR,
"subsys-restart: Ignoring restart request for %s.\n", name)) {
if (disable_restart_work == DISABLE_SSR) {
pr_warn("subsys-restart: Ignoring restart request for %s.\n",
name);
return 0;
}

View File

@ -27,4 +27,11 @@ config MSM_QPNP_INT
help
Say 'y' here to include support for the Qualcomm QPNP interrupt
support. QPNP is a SPMI based PMIC implementation.
config MSM_SPMI_DEBUGFS_RO
depends on DEBUG_FS
depends on SPMI
bool "Disable SPMI debugfs write"
help
Say 'y' here to disable the SPMI debugfs register write operation.
endif

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -46,6 +46,12 @@
static const char *DFS_ROOT_NAME = "spmi";
static const mode_t DFS_MODE = S_IRUSR | S_IWUSR;
#ifndef CONFIG_MSM_SPMI_DEBUGFS_RO
static const mode_t DFS_DATA_MODE = S_IRUSR | S_IWUSR;
#else
static const mode_t DFS_DATA_MODE = S_IRUSR;
#endif
/* Log buffer */
struct spmi_log_buffer {
size_t rpos; /* Current 'read' position in buffer */
@ -69,6 +75,7 @@ struct spmi_trans {
u32 addr; /* 20-bit address: SID + PID + Register offset */
u32 offset; /* Offset of last read data */
bool raw_data; /* Set to true for raw data dump */
struct mutex spmi_dfs_lock; /* Prevent thread concurrency */
struct spmi_controller *ctrl;
struct spmi_log_buffer *log; /* log buffer */
};
@ -168,6 +175,7 @@ static int spmi_dfs_open(struct spmi_ctrl_data *ctrl_data, struct file *file)
trans->addr = ctrl_data->addr;
trans->ctrl = ctrl_data->ctrl;
trans->offset = trans->addr;
mutex_init(&trans->spmi_dfs_lock);
file->private_data = trans;
return 0;
@ -197,6 +205,7 @@ static int spmi_dfs_close(struct inode *inode, struct file *file)
if (trans && trans->log) {
file->private_data = NULL;
mutex_destroy(&trans->spmi_dfs_lock);
kfree(trans->log);
kfree(trans);
}
@ -241,6 +250,7 @@ done:
return ret;
}
#ifndef CONFIG_MSM_SPMI_DEBUGFS_RO
/**
* spmi_write_data: writes data across the SPMI bus
* @ctrl: The SPMI controller
@ -277,6 +287,7 @@ spmi_write_data(struct spmi_controller *ctrl, uint8_t *buf, int offset, int cnt)
done:
return ret;
}
#endif
/**
* print_to_log: format a string and place into the log buffer
@ -456,6 +467,7 @@ static int get_log_data(struct spmi_trans *trans)
return total_items_read;
}
#ifndef CONFIG_MSM_SPMI_DEBUGFS_RO
/**
* spmi_dfs_reg_write: write user's byte array (coded as string) over SPMI.
* @file: file pointer
@ -473,14 +485,20 @@ static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
int cnt = 0;
u8 *values;
size_t ret = 0;
u32 offset;
char *kbuf;
struct spmi_trans *trans = file->private_data;
u32 offset = trans->offset;
mutex_lock(&trans->spmi_dfs_lock);
offset = trans->offset;
/* Make a copy of the user data */
char *kbuf = kmalloc(count + 1, GFP_KERNEL);
if (!kbuf)
return -ENOMEM;
kbuf = kmalloc(count + 1, GFP_KERNEL);
if (!kbuf) {
ret = -ENOMEM;
goto unlock_mutex;
}
ret = copy_from_user(kbuf, buf, count);
if (ret == count) {
@ -517,8 +535,13 @@ static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
free_buf:
kfree(kbuf);
unlock_mutex:
mutex_unlock(&trans->spmi_dfs_lock);
return ret;
}
#else
#define spmi_dfs_reg_write NULL
#endif
/**
* spmi_dfs_reg_read: reads value(s) over SPMI and fill user's buffer a
@ -537,10 +560,13 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
size_t ret;
size_t len;
mutex_lock(&trans->spmi_dfs_lock);
/* Is the the log buffer empty */
if (log->rpos >= log->wpos) {
if (get_log_data(trans) <= 0)
return 0;
if (get_log_data(trans) <= 0) {
len = 0;
goto unlock_mutex;
}
}
len = min(count, log->wpos - log->rpos);
@ -548,7 +574,8 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
ret = copy_to_user(buf, &log->data[log->rpos], len);
if (ret == len) {
pr_err("error copy SPMI register values to user\n");
return -EFAULT;
len = -EFAULT;
goto unlock_mutex;
}
/* 'ret' is the number of bytes not copied */
@ -556,6 +583,9 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
*ppos += len;
log->rpos += len;
unlock_mutex:
mutex_unlock(&trans->spmi_dfs_lock);
return len;
}
@ -671,14 +701,14 @@ int spmi_dfs_add_controller(struct spmi_controller *ctrl)
goto err_remove_fs;
}
file = debugfs_create_file("data", DFS_MODE, dir, ctrl_data,
file = debugfs_create_file("data", DFS_DATA_MODE, dir, ctrl_data,
&spmi_dfs_reg_fops);
if (!file) {
pr_err("error creating 'data' entry\n");
goto err_remove_fs;
}
file = debugfs_create_file("data_raw", DFS_MODE, dir, ctrl_data,
file = debugfs_create_file("data_raw", DFS_DATA_MODE, dir, ctrl_data,
&spmi_dfs_raw_data_fops);
if (!file) {
pr_err("error creating 'data' entry\n");

2
drivers/staging/android/ion/ion.c Normal file → Executable file
View File

@ -1468,7 +1468,7 @@ static long ion_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
handle = __ion_alloc(client, data.allocation.len,
data.allocation.align,
data.allocation.heap_id_mask,
data.allocation.flags,true);
data.allocation.flags, true);
if (IS_ERR(handle))
return PTR_ERR(handle);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -221,6 +221,7 @@ static int sharedmem_qmi_req_cb(struct qmi_handle *handle, void *conn_h,
#define DEBUG_BUF_SIZE (2048)
static char *debug_buffer;
static u32 debug_data_size;
static struct mutex dbg_buf_lock; /* mutex for debug_buffer */
static ssize_t debug_read(struct file *file, char __user *buf,
size_t count, loff_t *file_pos)
@ -276,21 +277,30 @@ static u32 fill_debug_info(char *buffer, u32 buffer_size)
static int debug_open(struct inode *inode, struct file *file)
{
u32 buffer_size;
if (debug_buffer != NULL)
mutex_lock(&dbg_buf_lock);
if (debug_buffer != NULL) {
mutex_unlock(&dbg_buf_lock);
return -EBUSY;
}
buffer_size = DEBUG_BUF_SIZE;
debug_buffer = kzalloc(buffer_size, GFP_KERNEL);
if (debug_buffer == NULL)
if (debug_buffer == NULL) {
mutex_unlock(&dbg_buf_lock);
return -ENOMEM;
}
debug_data_size = fill_debug_info(debug_buffer, buffer_size);
mutex_unlock(&dbg_buf_lock);
return 0;
}
static int debug_close(struct inode *inode, struct file *file)
{
mutex_lock(&dbg_buf_lock);
kfree(debug_buffer);
debug_buffer = NULL;
debug_data_size = 0;
mutex_unlock(&dbg_buf_lock);
return 0;
}
@ -321,6 +331,7 @@ static void debugfs_init(void)
{
struct dentry *f_ent;
mutex_init(&dbg_buf_lock);
dir_ent = debugfs_create_dir("rmt_storage", NULL);
if (IS_ERR(dir_ent)) {
pr_err("Failed to create debug_fs directory\n");
@ -349,6 +360,7 @@ static void debugfs_init(void)
static void debugfs_exit(void)
{
debugfs_remove_recursive(dir_ent);
mutex_destroy(&dbg_buf_lock);
}
static void sharedmem_qmi_svc_recv_msg(struct work_struct *work)

View File

@ -35,6 +35,7 @@
#include <linux/eventfd.h>
#include <linux/blkdev.h>
#include <linux/compat.h>
#include <linux/personality.h>
#include <asm/kmap_types.h>
#include <asm/uaccess.h>
@ -153,6 +154,9 @@ static int aio_setup_ring(struct kioctx *ctx)
unsigned long size, populate;
int nr_pages;
if (current->personality & READ_IMPLIES_EXEC)
return -EPERM;
/* Compensate for the ring buffer's head/tail overlap entry */
nr_events += 2; /* 1 is required, 2 for good luck */

View File

@ -168,16 +168,16 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
int g;
struct fdtable *fdt = NULL;
const struct cred *cred;
pid_t ppid, tpid;
pid_t ppid = 0, tpid = 0;
struct task_struct *leader = NULL;
rcu_read_lock();
ppid = pid_alive(p) ?
task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
tpid = 0;
if (pid_alive(p)) {
struct task_struct *tracer = ptrace_parent(p);
if (tracer)
tpid = task_pid_nr_ns(tracer, ns);
ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
leader = p->group_leader;
}
cred = get_task_cred(p);
seq_printf(m,
@ -189,7 +189,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
"Uid:\t%d\t%d\t%d\t%d\n"
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
task_tgid_nr_ns(p, ns),
leader ? task_pid_nr_ns(leader, ns) : 0,
pid_nr_ns(pid, ns),
ppid, tpid,
from_kuid_munged(user_ns, cred->uid),

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -18,6 +18,7 @@
#define QSEECOM_KEY_ID_SIZE 32
#define QSEOS_RESULT_FAIL_SEND_CMD_NO_THREAD -19 /*0xFFFFFFED*/
#define QSEOS_RESULT_FAIL_UNSUPPORTED_CE_PIPE -63
#define QSEOS_RESULT_FAIL_KS_OP -64
#define QSEOS_RESULT_FAIL_KEY_ID_EXISTS -65
@ -61,6 +62,10 @@ enum qseecom_qceos_cmd_id {
QSEOS_TEE_INVOKE_MODFD_COMMAND = QSEOS_TEE_INVOKE_COMMAND,
QSEOS_TEE_CLOSE_SESSION,
QSEOS_TEE_REQUEST_CANCELLATION,
QSEOS_CLIENT_SEND_DATA_COMMAND_WHITELIST = 0x1C,
QSEOS_TEE_OPEN_SESSION_WHITELIST = 0x1D,
QSEOS_TEE_INVOKE_COMMAND_WHITELIST = 0x1E,
QSEOS_LISTENER_DATA_RSP_COMMAND_WHITELIST = 0x1F,
QSEOS_FSM_LTE_INIT_DB = 0x100,
QSEOS_FSM_LTE_STORE_KENB = 0x101,
QSEOS_FSM_LTE_GEN_KEYS = 0x102,
@ -145,6 +150,8 @@ __packed struct qseecom_client_send_data_ireq {
uint32_t req_len;
uint32_t rsp_ptr;/* First 4 bytes should be the return status */
uint32_t rsp_len;
uint32_t sglistinfo_ptr;
uint32_t sglistinfo_len;
};
__packed struct qseecom_reg_log_buf_ireq {
@ -158,6 +165,8 @@ __packed struct qseecom_client_listener_data_irsp {
uint32_t qsee_cmd_id;
uint32_t listener_id;
uint32_t status;
uint32_t sglistinfo_ptr;
uint32_t sglistinfo_len;
};
/*
@ -233,6 +242,8 @@ __packed struct qseecom_qteec_ireq {
uint32_t req_len;
uint32_t resp_ptr;
uint32_t resp_len;
uint32_t sglistinfo_ptr;
uint32_t sglistinfo_len;
};
__packed struct qseecom_client_send_fsm_key_req {
@ -556,4 +567,45 @@ __packed struct qseecom_client_send_fsm_key_req {
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL)
#define TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID \
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
TZ_SVC_APP_ID_PLACEHOLDER, 0x06)
#define TZ_APP_QSAPP_SEND_DATA_WITH_WHITELIST_ID_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_7( \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL)
#define TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID \
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
TZ_SVC_APP_ID_PLACEHOLDER, 0x07)
#define TZ_APP_GPAPP_OPEN_SESSION_WITH_WHITELIST_ID_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_7( \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL)
#define TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID \
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_TZ_APPS, \
TZ_SVC_APP_ID_PLACEHOLDER, 0x09)
#define TZ_APP_GPAPP_INVOKE_COMMAND_WITH_WHITELIST_ID_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_7( \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_BUF_RW, \
TZ_SYSCALL_PARAM_TYPE_VAL)
#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_ID \
TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_QSEE_OS, TZ_SVC_LISTENER, 0x05)
#define TZ_OS_LISTENER_RESPONSE_HANDLER_WITH_WHITELIST_PARAM_ID \
TZ_SYSCALL_CREATE_PARAM_ID_4( \
TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL, \
TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
#endif /* __QSEECOMI_H_ */

View File

@ -3269,6 +3269,10 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
pte_unmap(page_table);
/* File mapping without ->vm_ops ? */
if (vma->vm_flags & VM_SHARED)
return VM_FAULT_SIGBUS;
/* Check if we need to add a guard page to the stack */
if (check_stack_guard_page(vma, address) < 0)
return VM_FAULT_SIGSEGV;
@ -3534,6 +3538,9 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
- vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
pte_unmap(page_table);
/* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */
if (!vma->vm_ops->fault)
return VM_FAULT_SIGBUS;
return __do_fault(mm, vma, address, pmd, pgoff, flags, orig_pte);
}
@ -3745,11 +3752,9 @@ int handle_pte_fault(struct mm_struct *mm,
entry = *pte;
if (!pte_present(entry)) {
if (pte_none(entry)) {
if (vma->vm_ops) {
if (likely(vma->vm_ops->fault))
return do_linear_fault(mm, vma, address,
if (vma->vm_ops)
return do_linear_fault(mm, vma, address,
pte, pmd, flags, entry);
}
return do_anonymous_page(mm, vma, address,
pte, pmd, flags);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -530,6 +530,11 @@ void rmnet_config_netlink_msg_handler(struct sk_buff *skb)
nlmsg_header = (struct nlmsghdr *) skb->data;
rmnet_header = (struct rmnet_nl_msg_s *) nlmsg_data(nlmsg_header);
if (!nlmsg_header->nlmsg_pid ||
(nlmsg_header->nlmsg_len < sizeof(struct nlmsghdr) +
sizeof(struct rmnet_nl_msg_s)))
return;
LOGL("Netlink message pid=%d, seq=%d, length=%d, rmnet_type=%d",
nlmsg_header->nlmsg_pid,
nlmsg_header->nlmsg_seq,

View File

@ -84,7 +84,6 @@
#include <linux/export.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/pft.h>
#include "avc.h"
@ -1677,14 +1676,8 @@ static int may_create(struct inode *dir,
return rc;
return avc_has_perm(newsid, sbsec->sid,
SECCLASS_FILESYSTEM,
FILESYSTEM__ASSOCIATE, &ad);
if (rc)
return rc;
rc = pft_inode_mknod(dir, dentry, 0, 0);
return rc;
SECCLASS_FILESYSTEM,
FILESYSTEM__ASSOCIATE, &ad);
}
/* Check whether a task can create a key. */
@ -1740,14 +1733,7 @@ static int may_link(struct inode *dir,
return 0;
}
rc = avc_has_perm(sid, isec->sid, isec->sclass, av, &ad);
if (rc)
return rc;
if (kind == MAY_UNLINK)
rc = pft_inode_unlink(dir, dentry);
return rc;
return avc_has_perm(sid, isec->sid, isec->sclass, av, &ad);
}
static inline int may_rename(struct inode *old_dir,
@ -2646,24 +2632,9 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir,
static int selinux_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
{
int ret;
ret = pft_inode_create(dir, dentry, mode);
if (ret < 0)
return ret;
return may_create(dir, dentry, SECCLASS_FILE);
}
static int selinux_inode_post_create(struct inode *dir, struct dentry *dentry,
umode_t mode)
{
int ret;
ret = pft_inode_post_create(dir, dentry, mode);
return ret;
}
static int selinux_inode_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
{
return may_link(dir, old_dentry, MAY_LINK);
@ -2697,12 +2668,6 @@ static int selinux_inode_mknod(struct inode *dir, struct dentry *dentry, umode_t
static int selinux_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
struct inode *new_inode, struct dentry *new_dentry)
{
int rc;
rc = pft_inode_rename(old_inode, old_dentry, new_inode, new_dentry);
if (rc)
return rc;
return may_rename(old_inode, old_dentry, new_inode, new_dentry);
}
@ -2821,9 +2786,6 @@ static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name)
{
const struct cred *cred = current_cred();
if (pft_inode_set_xattr(dentry, name, NULL, 0, 0) < 0)
return -EACCES;
if (!strncmp(name, XATTR_SECURITY_PREFIX,
sizeof XATTR_SECURITY_PREFIX - 1)) {
if (!strcmp(name, XATTR_NAME_CAPS)) {
@ -3067,16 +3029,11 @@ static int selinux_file_permission(struct file *file, int mask)
struct file_security_struct *fsec = file->f_security;
struct inode_security_struct *isec = inode->i_security;
u32 sid = current_sid();
int ret;
if (!mask)
/* No permission to check. Existence test. */
return 0;
ret = pft_file_permission(file, mask);
if (ret < 0)
return ret;
if (sid == fsec->sid && fsec->isid == isec->sid &&
fsec->pseqno == avc_policy_seqno())
/* No change since file_open check. */
@ -3370,11 +3327,6 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
{
struct file_security_struct *fsec;
struct inode_security_struct *isec;
int ret;
ret = pft_file_open(file, cred);
if (ret < 0)
return ret;
fsec = file->f_security;
isec = file_inode(file)->i_security;
@ -3398,17 +3350,6 @@ static int selinux_file_open(struct file *file, const struct cred *cred)
return path_has_perm(cred, &file->f_path, open_file_to_av(file));
}
static int selinux_file_close(struct file *file)
{
return pft_file_close(file);
}
static bool selinux_allow_merge_bio(struct bio *bio1, struct bio *bio2)
{
return pft_allow_merge_bio(bio1, bio2);
}
/* task security operations */
static int selinux_task_create(unsigned long clone_flags)
@ -5811,7 +5752,6 @@ static struct security_operations selinux_ops = {
.inode_free_security = selinux_inode_free_security,
.inode_init_security = selinux_inode_init_security,
.inode_create = selinux_inode_create,
.inode_post_create = selinux_inode_post_create,
.inode_link = selinux_inode_link,
.inode_unlink = selinux_inode_unlink,
.inode_symlink = selinux_inode_symlink,
@ -5848,8 +5788,6 @@ static struct security_operations selinux_ops = {
.file_receive = selinux_file_receive,
.file_open = selinux_file_open,
.file_close = selinux_file_close,
.allow_merge_bio = selinux_allow_merge_bio,
.task_create = selinux_task_create,
.cred_alloc_blank = selinux_cred_alloc_blank,

View File

@ -2215,15 +2215,19 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
micbias2 = (snd_soc_read(codec, MSM8X16_WCD_A_ANALOG_MICB_2_EN) & 0x80);
switch (event) {
case SND_SOC_DAPM_PRE_PMU:
if (strnstr(w->name, internal1_text, 30)) {
if (strnstr(w->name, internal1_text, strlen(w->name))) {
if (get_codec_version(msm8x16_wcd) == CAJON)
snd_soc_update_bits(codec,
MSM8X16_WCD_A_ANALOG_TX_1_2_ATEST_CTL_2,
0x02, 0x02);
snd_soc_update_bits(codec, micb_int_reg, 0x80, 0x80);
} else if (strnstr(w->name, internal2_text, 30)) {
} else if (strnstr(w->name, internal2_text, strlen(w->name))) {
snd_soc_update_bits(codec, micb_int_reg, 0x10, 0x10);
snd_soc_update_bits(codec, w->reg, 0x60, 0x00);
} else if (strnstr(w->name, internal3_text, 30)) {
} else if (strnstr(w->name, internal3_text, strlen(w->name))) {
snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x2);
}
if (!strnstr(w->name, external_text, 30))
if (!strnstr(w->name, external_text, strlen(w->name)))
snd_soc_update_bits(codec,
MSM8X16_WCD_A_ANALOG_MICB_1_EN, 0x05, 0x04);
if (w->reg == MSM8X16_WCD_A_ANALOG_MICB_1_EN)
@ -2232,28 +2236,28 @@ static int msm8x16_wcd_codec_enable_micbias(struct snd_soc_dapm_widget *w,
break;
case SND_SOC_DAPM_POST_PMU:
usleep_range(20000, 20100);
if (strnstr(w->name, internal1_text, 30)) {
if (strnstr(w->name, internal1_text, strlen(w->name))) {
snd_soc_update_bits(codec, micb_int_reg, 0x40, 0x40);
} else if (strnstr(w->name, internal2_text, 30)) {
} else if (strnstr(w->name, internal2_text, strlen(w->name))) {
snd_soc_update_bits(codec, micb_int_reg, 0x08, 0x08);
msm8x16_notifier_call(codec,
WCD_EVENT_PRE_MICBIAS_2_ON);
} else if (strnstr(w->name, internal3_text, 30)) {
} else if (strnstr(w->name, internal3_text, strlen(w->name))) {
snd_soc_update_bits(codec, micb_int_reg, 0x01, 0x01);
} else if (strnstr(w->name, external2_text, 30)) {
} else if (strnstr(w->name, external2_text, strlen(w->name))) {
msm8x16_notifier_call(codec,
WCD_EVENT_PRE_MICBIAS_2_ON);
}
break;
case SND_SOC_DAPM_POST_PMD:
if (strnstr(w->name, internal1_text, 30)) {
if (strnstr(w->name, internal1_text, strlen(w->name))) {
snd_soc_update_bits(codec, micb_int_reg, 0xC0, 0x40);
} else if (strnstr(w->name, internal2_text, 30)) {
} else if (strnstr(w->name, internal2_text, strlen(w->name))) {
msm8x16_notifier_call(codec,
WCD_EVENT_PRE_MICBIAS_2_OFF);
} else if (strnstr(w->name, internal3_text, 30)) {
} else if (strnstr(w->name, internal3_text, strlen(w->name))) {
snd_soc_update_bits(codec, micb_int_reg, 0x2, 0x0);
} else if (strnstr(w->name, external2_text, 30)) {
} else if (strnstr(w->name, external2_text, strlen(w->name))) {
/*
* send micbias turn off event to mbhc driver and then
* break, as no need to set MICB_1_EN register.

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014, Linux Foundation. All rights reserved.
* Copyright (c) 2013-2014, 2017 Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -793,13 +793,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
dev_dbg(rtd->dev,
"%s: %s\n",
__func__, "SNDRV_LSM_REG_SND_MODEL_V2");
if (!arg) {
dev_err(rtd->dev,
"%s: Invalid argument to ioctl %s\n",
__func__,
"SNDRV_LSM_REG_SND_MODEL_V2");
return -EINVAL;
}
memcpy(&snd_model, arg,
sizeof(struct snd_lsm_sound_model_v2));
@ -926,13 +919,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
dev_dbg(rtd->dev,
"%s: %s\n",
__func__, "SNDRV_LSM_EVENT_STATUS");
if (!arg) {
dev_err(rtd->dev,
"%s: Invalid argument to ioctl %s\n",
__func__,
"SNDRV_LSM_EVENT_STATUS");
return -EINVAL;
}
user = arg;
@ -1035,12 +1021,6 @@ static int msm_cpe_lsm_ioctl_shared(struct snd_pcm_substream *substream,
break;
case SNDRV_LSM_SET_PARAMS:
if (!arg) {
dev_err(rtd->dev,
"%s: %s Invalid argument\n",
__func__, "SNDRV_LSM_SET_PARAMS");
return -EINVAL;
}
memcpy(&det_params, arg,
sizeof(det_params));
if (det_params.num_confidence_levels <= 0) {
@ -1305,12 +1285,6 @@ done:
}
#ifdef CONFIG_COMPAT
struct snd_lsm_event_status32 {
u16 status;
u16 payload_size;
u8 payload[0];
};
struct snd_lsm_sound_model_v2_32 {
compat_uptr_t data;
compat_uptr_t confidence_level;
@ -1328,8 +1302,6 @@ struct snd_lsm_detection_params_32 {
};
enum {
SNDRV_LSM_EVENT_STATUS32 =
_IOW('U', 0x02, struct snd_lsm_event_status32),
SNDRV_LSM_REG_SND_MODEL_V2_32 =
_IOW('U', 0x07, struct snd_lsm_sound_model_v2_32),
SNDRV_LSM_SET_PARAMS32 =
@ -1416,7 +1388,7 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
err);
}
break;
case SNDRV_LSM_EVENT_STATUS32: {
case SNDRV_LSM_EVENT_STATUS: {
struct snd_lsm_event_status *event_status = NULL;
struct snd_lsm_event_status u_event_status32;
struct snd_lsm_event_status *udata_32 = NULL;
@ -1458,7 +1430,6 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
} else {
event_status->payload_size =
u_event_status32.payload_size;
cmd = SNDRV_LSM_EVENT_STATUS;
err = msm_cpe_lsm_ioctl_shared(substream,
cmd, event_status);
if (err)
@ -1533,7 +1504,18 @@ static int msm_cpe_lsm_ioctl_compat(struct snd_pcm_substream *substream,
break;
}
case SNDRV_LSM_REG_SND_MODEL_V2:
case SNDRV_LSM_SET_PARAMS:
/*
* In ideal cases, the compat_ioctl should never be called
* with the above unlocked ioctl commands. Print error
* and return error if it does.
*/
dev_err(rtd->dev,
"%s: Invalid cmd for compat_ioctl\n",
__func__);
err = -EINVAL;
break;
default:
err = msm_cpe_lsm_ioctl_shared(substream, cmd, arg);
break;

View File

@ -536,7 +536,6 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
memset(cal_block, 0, sizeof(*cal_block));
INIT_LIST_HEAD(&cal_block->list);
list_add_tail(&cal_block->list, &cal_type->cal_blocks);
cal_block->map_data.ion_map_handle = basic_cal->cal_data.mem_handle;
if (basic_cal->cal_data.mem_handle > 0) {
@ -568,7 +567,8 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
goto err;
}
cal_block->buffer_number = basic_cal->cal_hdr.buffer_number;
pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pa!\n",
list_add_tail(&cal_block->list, &cal_type->cal_blocks);
pr_debug("%s: created block for cal type %d, buf num %d, map handle %d, map size %zd paddr 0x%pK!\n",
__func__, cal_type->info.reg.cal_type,
cal_block->buffer_number,
cal_block->map_data.ion_map_handle,
@ -577,6 +577,8 @@ static struct cal_block_data *create_cal_block(struct cal_type_data *cal_type,
done:
return cal_block;
err:
kfree(cal_block->cal_info);
kfree(cal_block->client_info);
kfree(cal_block);
cal_block = NULL;
return cal_block;

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -1277,6 +1277,11 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai,
pr_err("%s: rx slot not found\n", __func__);
return -EINVAL;
}
if (rx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
pr_err("%s: invalid rx num %d\n", __func__, rx_num);
return -EINVAL;
}
for (i = 0; i < rx_num; i++) {
dai_data->port_config.slim_sch.shared_ch_mapping[i] =
rx_slot[i];
@ -1307,6 +1312,11 @@ static int msm_dai_q6_set_channel_map(struct snd_soc_dai *dai,
pr_err("%s: tx slot not found\n", __func__);
return -EINVAL;
}
if (tx_num > AFE_PORT_MAX_AUDIO_CHAN_CNT) {
pr_err("%s: invalid tx num %d\n", __func__, tx_num);
return -EINVAL;
}
for (i = 0; i < tx_num; i++) {
dai_data->port_config.slim_sch.shared_ch_mapping[i] =
tx_slot[i];

View File

@ -681,7 +681,7 @@ int msm_dolby_dap_param_to_set_control_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
int rc = 0, port_id, copp_idx;
uint32_t idx, j;
uint32_t idx, j, current_offset;
uint32_t device = ucontrol->value.integer.value[0];
uint32_t param_id = ucontrol->value.integer.value[1];
uint32_t offset = ucontrol->value.integer.value[2];
@ -758,6 +758,19 @@ int msm_dolby_dap_param_to_set_control_put(struct snd_kcontrol *kcontrol,
default: {
/* cache the parameters */
dolby_dap_params_modified[idx] += 1;
current_offset = dolby_dap_params_offset[idx] + offset;
if (current_offset >= TOTAL_LENGTH_DOLBY_PARAM) {
pr_err("%s: invalid offset %d at idx %d\n",
__func__, offset, idx);
return -EINVAL;
}
if ((0 == length) || (current_offset + length - 1
< current_offset) || (current_offset + length
> TOTAL_LENGTH_DOLBY_PARAM)) {
pr_err("%s: invalid length %d at idx %d\n",
__func__, length, idx);
return -EINVAL;
}
dolby_dap_params_length[idx] = length;
pr_debug("%s: param recvd deviceId=0x%x paramId=0x%x offset=%d length=%d\n",
__func__, device, param_id, offset, length);

View File

@ -234,7 +234,8 @@ static s32 _volume_cmds_alloc1(s32 size)
if (_vol_cmds) {
_vol_cmds_d = kzalloc(_vol_cmd_cnt * sizeof(struct vol_cmds_d),
GFP_KERNEL);
}
} else
_vol_cmd_cnt = 0;
if (_vol_cmds_d)
return 0;
_volume_cmds_free();

View File

@ -827,6 +827,11 @@ static int msm_pcm_playback_copy(struct snd_pcm_substream *substream, int a,
(sizeof(buf_node->frame.frm_hdr) +
sizeof(buf_node->frame.pktlen));
}
if (ret) {
pr_err("%s: copy from user failed %d\n",
__func__, ret);
return -EFAULT;
}
spin_lock_irqsave(&prtd->dsp_lock, dsp_flags);
list_add_tail(&buf_node->list, &prtd->in_queue);
spin_unlock_irqrestore(&prtd->dsp_lock, dsp_flags);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 2016, 2017 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -1061,9 +1061,10 @@ int adm_get_params(int port_id, int copp_idx, uint32_t module_id,
uint32_t param_id, uint32_t params_length, char *params)
{
struct adm_cmd_get_pp_params_v5 *adm_params = NULL;
int sz, rc = 0, i = 0;
int rc = 0, i = 0;
int port_idx, idx;
int *params_data = (int *)params;
uint64_t sz = 0;
port_id = afe_convert_virtual_to_portid(port_id);
port_idx = adm_validate_and_get_port_index(port_id);
@ -1072,7 +1073,16 @@ int adm_get_params(int port_id, int copp_idx, uint32_t module_id,
return -EINVAL;
}
sz = sizeof(struct adm_cmd_get_pp_params_v5) + params_length;
sz = (uint64_t)sizeof(struct adm_cmd_get_pp_params_v5) +
(uint64_t)params_length;
/*
* Check if the value of "sz" (which is ultimately assigned to
* "hdr.pkt_size") crosses U16_MAX.
*/
if (sz > U16_MAX) {
pr_err("%s: Invalid params_length\n", __func__);
return -EINVAL;
}
adm_params = kzalloc(sz, GFP_KERNEL);
if (!adm_params) {
pr_err("%s: adm params memory alloc failed", __func__);

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@ -2528,8 +2528,9 @@ int q6afe_audio_client_buf_alloc_contiguous(unsigned int dir,
struct afe_audio_buffer *buf;
size_t len;
if (!(ac) || ((dir != IN) && (dir != OUT))) {
pr_err("%s: ac %p dir %d\n", __func__, ac, dir);
if (!(ac) || !(bufsz) || ((dir != IN) && (dir != OUT))) {
pr_err("%s: ac %p bufsz %d dir %d\n", __func__, ac, bufsz,
dir);
return -EINVAL;
}
@ -3171,7 +3172,7 @@ static ssize_t afe_debug_write(struct file *filp,
lbuf[cnt] = '\0';
if (!strncmp(lb_str, "afe_loopback", 12)) {
if (!strcmp(lb_str, "afe_loopback")) {
rc = afe_get_parameters(lbuf, param, 3);
if (!rc) {
pr_info("%s: %lu %lu %lu\n", lb_str, param[0], param[1],
@ -3200,7 +3201,7 @@ static ssize_t afe_debug_write(struct file *filp,
rc = -EINVAL;
}
} else if (!strncmp(lb_str, "afe_loopback_gain", 17)) {
} else if (!strcmp(lb_str, "afe_loopback_gain")) {
rc = afe_get_parameters(lbuf, param, 2);
if (!rc) {
pr_info("%s: %s %lu %lu\n",

View File

@ -2846,7 +2846,8 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
int dir)
{
struct audio_buffer *buf_circ;
int bytes_to_alloc, rc, len;
int bytes_to_alloc, rc;
size_t len;
buf_circ = kzalloc(sizeof(struct audio_buffer), GFP_KERNEL);
@ -2865,7 +2866,7 @@ int q6asm_set_shared_circ_buff(struct audio_client *ac,
rc = msm_audio_ion_alloc("audio_client", &buf_circ->client,
&buf_circ->handle, bytes_to_alloc,
(ion_phys_addr_t *)&buf_circ->phys,
(size_t *)&len, &buf_circ->data);
&len, &buf_circ->data);
if (rc) {
pr_err("%s: Audio ION alloc is failed, rc = %d\n", __func__,
@ -2907,7 +2908,8 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac,
int dir)
{
struct audio_buffer *buf_pos = &ac->shared_pos_buf;
int len, rc;
int rc;
size_t len;
int bytes_to_alloc = sizeof(struct asm_shared_position_buffer);
mutex_lock(&ac->cmd_lock);
@ -2916,7 +2918,7 @@ int q6asm_set_shared_pos_buff(struct audio_client *ac,
rc = msm_audio_ion_alloc("audio_client", &buf_pos->client,
&buf_pos->handle, bytes_to_alloc,
(ion_phys_addr_t *)&buf_pos->phys, (size_t *)&len,
(ion_phys_addr_t *)&buf_pos->phys, &len,
&buf_pos->data);
if (rc) {
@ -4970,7 +4972,7 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
struct asm_buffer_node *buffer_node = NULL;
int rc = 0;
int i = 0;
int cmd_size = 0;
uint32_t cmd_size = 0;
uint32_t bufcnt_t;
uint32_t bufsz_t;
@ -4992,10 +4994,25 @@ static int q6asm_memory_map_regions(struct audio_client *ac, int dir,
bufsz_t = PAGE_ALIGN(bufsz_t);
}
if (bufcnt_t > (UINT_MAX
- sizeof(struct avs_cmd_shared_mem_map_regions))
/ sizeof(struct avs_shared_map_region_payload)) {
pr_err("%s: Unsigned Integer Overflow. bufcnt_t = %u\n",
__func__, bufcnt_t);
return -EINVAL;
}
cmd_size = sizeof(struct avs_cmd_shared_mem_map_regions)
+ (sizeof(struct avs_shared_map_region_payload)
* bufcnt_t);
if (bufcnt > (UINT_MAX / sizeof(struct asm_buffer_node))) {
pr_err("%s: Unsigned Integer Overflow. bufcnt = %u\n",
__func__, bufcnt);
return -EINVAL;
}
buffer_node = kzalloc(sizeof(struct asm_buffer_node) * bufcnt,
GFP_KERNEL);
if (!buffer_node) {

View File

@ -131,7 +131,7 @@ struct share_mem_buf {
struct mem_map_table {
dma_addr_t phys;
void *data;
uint32_t size; /* size of buffer */
size_t size; /* size of buffer */
struct ion_handle *handle;
struct ion_client *client;
};