Commit ffb384c2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'char-misc-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc

Pull char/misc driver fixes from Greg KH:
 "Here are some small char/misc and other driver fixes for 6.0-rc4.

  Included in here are:

   - binder fixes for previous fixes, and a few more fixes uncovered by
     them.

   - iio driver fixes

   - soundwire driver fixes

   - fastrpc driver fixes for memory corruption on some hardware

   - peci driver fix

   - mhi driver fix

  All of these have been in linux-next with no reported problems"

* tag 'char-misc-6.0-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc:
  binder: fix alloc->vma_vm_mm null-ptr dereference
  misc: fastrpc: increase maximum session count
  misc: fastrpc: fix memory corruption on open
  misc: fastrpc: fix memory corruption on probe
  soundwire: qcom: fix device status array range
  bus: mhi: host: Fix up null pointer access in mhi_irq_handler
  soundwire: qcom: remove duplicate reset control get
  iio: light: cm32181: make cm32181_pm_ops static
  iio: ad7292: Prevent regulator double disable
  dt-bindings: iio: gyroscope: bosch,bmg160: correct number of pins
  iio: adc: mcp3911: use correct formula for AD conversion
  iio: adc: mcp3911: correct "microchip,device-addr" property
  Revert "binder_alloc: Add missing mmap_lock calls when using the VMA"
  binder_alloc: Add missing mmap_lock calls when using the VMA
  binder: fix UAF of ref->proc caused by race condition
  iio: light: cm3605: Fix an error handling path in cm3605_probe()
  iio: adc: mcp3911: make use of the sign bit
  peci: cpu: Fix use-after-free in adev_release()
  peci: aspeed: fix error check return value of platform_get_irq()
parents fd59585c 0f022aaa
...@@ -24,8 +24,10 @@ properties: ...@@ -24,8 +24,10 @@ properties:
interrupts: interrupts:
minItems: 1 minItems: 1
maxItems: 2
description: description:
Should be configured with type IRQ_TYPE_EDGE_RISING. Should be configured with type IRQ_TYPE_EDGE_RISING.
If two interrupts are provided, expected order is INT1 and INT2.
required: required:
- compatible - compatible
......
...@@ -1385,6 +1385,18 @@ static int binder_inc_ref_for_node(struct binder_proc *proc, ...@@ -1385,6 +1385,18 @@ static int binder_inc_ref_for_node(struct binder_proc *proc,
} }
ret = binder_inc_ref_olocked(ref, strong, target_list); ret = binder_inc_ref_olocked(ref, strong, target_list);
*rdata = ref->data; *rdata = ref->data;
if (ret && ref == new_ref) {
/*
* Cleanup the failed reference here as the target
* could now be dead and have already released its
* references by now. Calling on the new reference
* with strong=0 and a tmp_refs will not decrement
* the node. The new_ref gets kfree'd below.
*/
binder_cleanup_ref_olocked(new_ref);
ref = NULL;
}
binder_proc_unlock(proc); binder_proc_unlock(proc);
if (new_ref && ref != new_ref) if (new_ref && ref != new_ref)
/* /*
......
...@@ -322,7 +322,6 @@ static inline void binder_alloc_set_vma(struct binder_alloc *alloc, ...@@ -322,7 +322,6 @@ static inline void binder_alloc_set_vma(struct binder_alloc *alloc,
*/ */
if (vma) { if (vma) {
vm_start = vma->vm_start; vm_start = vma->vm_start;
alloc->vma_vm_mm = vma->vm_mm;
mmap_assert_write_locked(alloc->vma_vm_mm); mmap_assert_write_locked(alloc->vma_vm_mm);
} else { } else {
mmap_assert_locked(alloc->vma_vm_mm); mmap_assert_locked(alloc->vma_vm_mm);
...@@ -795,7 +794,6 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc, ...@@ -795,7 +794,6 @@ int binder_alloc_mmap_handler(struct binder_alloc *alloc,
binder_insert_free_buffer(alloc, buffer); binder_insert_free_buffer(alloc, buffer);
alloc->free_async_space = alloc->buffer_size / 2; alloc->free_async_space = alloc->buffer_size / 2;
binder_alloc_set_vma(alloc, vma); binder_alloc_set_vma(alloc, vma);
mmgrab(alloc->vma_vm_mm);
return 0; return 0;
...@@ -1091,6 +1089,8 @@ static struct shrinker binder_shrinker = { ...@@ -1091,6 +1089,8 @@ static struct shrinker binder_shrinker = {
void binder_alloc_init(struct binder_alloc *alloc) void binder_alloc_init(struct binder_alloc *alloc)
{ {
alloc->pid = current->group_leader->pid; alloc->pid = current->group_leader->pid;
alloc->vma_vm_mm = current->mm;
mmgrab(alloc->vma_vm_mm);
mutex_init(&alloc->mutex); mutex_init(&alloc->mutex);
INIT_LIST_HEAD(&alloc->buffers); INIT_LIST_HEAD(&alloc->buffers);
} }
......
...@@ -430,12 +430,25 @@ irqreturn_t mhi_irq_handler(int irq_number, void *dev) ...@@ -430,12 +430,25 @@ irqreturn_t mhi_irq_handler(int irq_number, void *dev)
{ {
struct mhi_event *mhi_event = dev; struct mhi_event *mhi_event = dev;
struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl; struct mhi_controller *mhi_cntrl = mhi_event->mhi_cntrl;
struct mhi_event_ctxt *er_ctxt = struct mhi_event_ctxt *er_ctxt;
&mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
struct mhi_ring *ev_ring = &mhi_event->ring; struct mhi_ring *ev_ring = &mhi_event->ring;
dma_addr_t ptr = le64_to_cpu(er_ctxt->rp); dma_addr_t ptr;
void *dev_rp; void *dev_rp;
/*
* If CONFIG_DEBUG_SHIRQ is set, the IRQ handler will get invoked during __free_irq()
* and by that time mhi_ctxt() would've freed. So check for the existence of mhi_ctxt
* before handling the IRQs.
*/
if (!mhi_cntrl->mhi_ctxt) {
dev_dbg(&mhi_cntrl->mhi_dev->dev,
"mhi_ctxt has been freed\n");
return IRQ_HANDLED;
}
er_ctxt = &mhi_cntrl->mhi_ctxt->er_ctxt[mhi_event->er_index];
ptr = le64_to_cpu(er_ctxt->rp);
if (!is_valid_ring_ptr(ev_ring, ptr)) { if (!is_valid_ring_ptr(ev_ring, ptr)) {
dev_err(&mhi_cntrl->mhi_dev->dev, dev_err(&mhi_cntrl->mhi_dev->dev,
"Event ring rp points outside of the event ring\n"); "Event ring rp points outside of the event ring\n");
......
...@@ -287,10 +287,8 @@ static int ad7292_probe(struct spi_device *spi) ...@@ -287,10 +287,8 @@ static int ad7292_probe(struct spi_device *spi)
ret = devm_add_action_or_reset(&spi->dev, ret = devm_add_action_or_reset(&spi->dev,
ad7292_regulator_disable, st); ad7292_regulator_disable, st);
if (ret) { if (ret)
regulator_disable(st->reg);
return ret; return ret;
}
ret = regulator_get_voltage(st->reg); ret = regulator_get_voltage(st->reg);
if (ret < 0) if (ret < 0)
......
...@@ -40,8 +40,8 @@ ...@@ -40,8 +40,8 @@
#define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3) #define MCP3911_CHANNEL(x) (MCP3911_REG_CHANNEL0 + x * 3)
#define MCP3911_OFFCAL(x) (MCP3911_REG_OFFCAL_CH0 + x * 6) #define MCP3911_OFFCAL(x) (MCP3911_REG_OFFCAL_CH0 + x * 6)
/* Internal voltage reference in uV */ /* Internal voltage reference in mV */
#define MCP3911_INT_VREF_UV 1200000 #define MCP3911_INT_VREF_MV 1200
#define MCP3911_REG_READ(reg, id) ((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff) #define MCP3911_REG_READ(reg, id) ((((reg) << 1) | ((id) << 5) | (1 << 0)) & 0xff)
#define MCP3911_REG_WRITE(reg, id) ((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff) #define MCP3911_REG_WRITE(reg, id) ((((reg) << 1) | ((id) << 5) | (0 << 0)) & 0xff)
...@@ -113,6 +113,8 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev, ...@@ -113,6 +113,8 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
if (ret) if (ret)
goto out; goto out;
*val = sign_extend32(*val, 23);
ret = IIO_VAL_INT; ret = IIO_VAL_INT;
break; break;
...@@ -137,11 +139,18 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev, ...@@ -137,11 +139,18 @@ static int mcp3911_read_raw(struct iio_dev *indio_dev,
*val = ret / 1000; *val = ret / 1000;
} else { } else {
*val = MCP3911_INT_VREF_UV; *val = MCP3911_INT_VREF_MV;
} }
*val2 = 24; /*
ret = IIO_VAL_FRACTIONAL_LOG2; * For 24bit Conversion
* Raw = ((Voltage)/(Vref) * 2^23 * Gain * 1.5
* Voltage = Raw * (Vref)/(2^23 * Gain * 1.5)
*/
/* val2 = (2^23 * 1.5) */
*val2 = 12582912;
ret = IIO_VAL_FRACTIONAL;
break; break;
} }
...@@ -208,7 +217,14 @@ static int mcp3911_config(struct mcp3911 *adc) ...@@ -208,7 +217,14 @@ static int mcp3911_config(struct mcp3911 *adc)
u32 configreg; u32 configreg;
int ret; int ret;
device_property_read_u32(dev, "device-addr", &adc->dev_addr); ret = device_property_read_u32(dev, "microchip,device-addr", &adc->dev_addr);
/*
* Fallback to "device-addr" due to historical mismatch between
* dt-bindings and implementation
*/
if (ret)
device_property_read_u32(dev, "device-addr", &adc->dev_addr);
if (adc->dev_addr > 3) { if (adc->dev_addr > 3) {
dev_err(&adc->spi->dev, dev_err(&adc->spi->dev,
"invalid device address (%i). Must be in range 0-3.\n", "invalid device address (%i). Must be in range 0-3.\n",
......
...@@ -505,7 +505,7 @@ static int cm32181_resume(struct device *dev) ...@@ -505,7 +505,7 @@ static int cm32181_resume(struct device *dev)
cm32181->conf_regs[CM32181_REG_ADDR_CMD]); cm32181->conf_regs[CM32181_REG_ADDR_CMD]);
} }
DEFINE_SIMPLE_DEV_PM_OPS(cm32181_pm_ops, cm32181_suspend, cm32181_resume); static DEFINE_SIMPLE_DEV_PM_OPS(cm32181_pm_ops, cm32181_suspend, cm32181_resume);
static const struct of_device_id cm32181_of_match[] = { static const struct of_device_id cm32181_of_match[] = {
{ .compatible = "capella,cm3218" }, { .compatible = "capella,cm3218" },
......
...@@ -226,8 +226,10 @@ static int cm3605_probe(struct platform_device *pdev) ...@@ -226,8 +226,10 @@ static int cm3605_probe(struct platform_device *pdev)
} }
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) if (irq < 0) {
return dev_err_probe(dev, irq, "failed to get irq\n"); ret = dev_err_probe(dev, irq, "failed to get irq\n");
goto out_disable_aset;
}
ret = devm_request_threaded_irq(dev, irq, cm3605_prox_irq, ret = devm_request_threaded_irq(dev, irq, cm3605_prox_irq,
NULL, 0, "cm3605", indio_dev); NULL, 0, "cm3605", indio_dev);
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#define SDSP_DOMAIN_ID (2) #define SDSP_DOMAIN_ID (2)
#define CDSP_DOMAIN_ID (3) #define CDSP_DOMAIN_ID (3)
#define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/ #define FASTRPC_DEV_MAX 4 /* adsp, mdsp, slpi, cdsp*/
#define FASTRPC_MAX_SESSIONS 13 /*12 compute, 1 cpz*/ #define FASTRPC_MAX_SESSIONS 14
#define FASTRPC_MAX_VMIDS 16 #define FASTRPC_MAX_VMIDS 16
#define FASTRPC_ALIGN 128 #define FASTRPC_ALIGN 128
#define FASTRPC_MAX_FDLIST 16 #define FASTRPC_MAX_FDLIST 16
...@@ -1943,7 +1943,12 @@ static int fastrpc_cb_probe(struct platform_device *pdev) ...@@ -1943,7 +1943,12 @@ static int fastrpc_cb_probe(struct platform_device *pdev)
of_property_read_u32(dev->of_node, "qcom,nsessions", &sessions); of_property_read_u32(dev->of_node, "qcom,nsessions", &sessions);
spin_lock_irqsave(&cctx->lock, flags); spin_lock_irqsave(&cctx->lock, flags);
sess = &cctx->session[cctx->sesscount]; if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) {
dev_err(&pdev->dev, "too many sessions\n");
spin_unlock_irqrestore(&cctx->lock, flags);
return -ENOSPC;
}
sess = &cctx->session[cctx->sesscount++];
sess->used = false; sess->used = false;
sess->valid = true; sess->valid = true;
sess->dev = dev; sess->dev = dev;
...@@ -1956,13 +1961,12 @@ static int fastrpc_cb_probe(struct platform_device *pdev) ...@@ -1956,13 +1961,12 @@ static int fastrpc_cb_probe(struct platform_device *pdev)
struct fastrpc_session_ctx *dup_sess; struct fastrpc_session_ctx *dup_sess;
for (i = 1; i < sessions; i++) { for (i = 1; i < sessions; i++) {
if (cctx->sesscount++ >= FASTRPC_MAX_SESSIONS) if (cctx->sesscount >= FASTRPC_MAX_SESSIONS)
break; break;
dup_sess = &cctx->session[cctx->sesscount]; dup_sess = &cctx->session[cctx->sesscount++];
memcpy(dup_sess, sess, sizeof(*dup_sess)); memcpy(dup_sess, sess, sizeof(*dup_sess));
} }
} }
cctx->sesscount++;
spin_unlock_irqrestore(&cctx->lock, flags); spin_unlock_irqrestore(&cctx->lock, flags);
rc = dma_set_mask(dev, DMA_BIT_MASK(32)); rc = dma_set_mask(dev, DMA_BIT_MASK(32));
if (rc) { if (rc) {
......
...@@ -523,7 +523,7 @@ static int aspeed_peci_probe(struct platform_device *pdev) ...@@ -523,7 +523,7 @@ static int aspeed_peci_probe(struct platform_device *pdev)
return PTR_ERR(priv->base); return PTR_ERR(priv->base);
priv->irq = platform_get_irq(pdev, 0); priv->irq = platform_get_irq(pdev, 0);
if (!priv->irq) if (priv->irq < 0)
return priv->irq; return priv->irq;
ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_peci_irq_handler, ret = devm_request_irq(&pdev->dev, priv->irq, aspeed_peci_irq_handler,
......
...@@ -188,8 +188,6 @@ static void adev_release(struct device *dev) ...@@ -188,8 +188,6 @@ static void adev_release(struct device *dev)
{ {
struct auxiliary_device *adev = to_auxiliary_dev(dev); struct auxiliary_device *adev = to_auxiliary_dev(dev);
auxiliary_device_uninit(adev);
kfree(adev->name); kfree(adev->name);
kfree(adev); kfree(adev);
} }
...@@ -234,6 +232,7 @@ static void unregister_adev(void *_adev) ...@@ -234,6 +232,7 @@ static void unregister_adev(void *_adev)
struct auxiliary_device *adev = _adev; struct auxiliary_device *adev = _adev;
auxiliary_device_delete(adev); auxiliary_device_delete(adev);
auxiliary_device_uninit(adev);
} }
static int devm_adev_add(struct device *dev, int idx) static int devm_adev_add(struct device *dev, int idx)
......
...@@ -169,7 +169,7 @@ struct qcom_swrm_ctrl { ...@@ -169,7 +169,7 @@ struct qcom_swrm_ctrl {
u8 wcmd_id; u8 wcmd_id;
struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS]; struct qcom_swrm_port_config pconfig[QCOM_SDW_MAX_PORTS];
struct sdw_stream_runtime *sruntime[SWRM_MAX_DAIS]; struct sdw_stream_runtime *sruntime[SWRM_MAX_DAIS];
enum sdw_slave_status status[SDW_MAX_DEVICES]; enum sdw_slave_status status[SDW_MAX_DEVICES + 1];
int (*reg_read)(struct qcom_swrm_ctrl *ctrl, int reg, u32 *val); int (*reg_read)(struct qcom_swrm_ctrl *ctrl, int reg, u32 *val);
int (*reg_write)(struct qcom_swrm_ctrl *ctrl, int reg, int val); int (*reg_write)(struct qcom_swrm_ctrl *ctrl, int reg, int val);
u32 slave_status; u32 slave_status;
...@@ -420,7 +420,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl) ...@@ -420,7 +420,7 @@ static int qcom_swrm_get_alert_slave_dev_num(struct qcom_swrm_ctrl *ctrl)
ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val); ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
for (dev_num = 0; dev_num < SDW_MAX_DEVICES; dev_num++) { for (dev_num = 0; dev_num <= SDW_MAX_DEVICES; dev_num++) {
status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ)); status = (val >> (dev_num * SWRM_MCP_SLV_STATUS_SZ));
if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) { if ((status & SWRM_MCP_SLV_STATUS_MASK) == SDW_SLAVE_ALERT) {
...@@ -440,7 +440,7 @@ static void qcom_swrm_get_device_status(struct qcom_swrm_ctrl *ctrl) ...@@ -440,7 +440,7 @@ static void qcom_swrm_get_device_status(struct qcom_swrm_ctrl *ctrl)
ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val); ctrl->reg_read(ctrl, SWRM_MCP_SLV_STATUS, &val);
ctrl->slave_status = val; ctrl->slave_status = val;
for (i = 0; i < SDW_MAX_DEVICES; i++) { for (i = 0; i <= SDW_MAX_DEVICES; i++) {
u32 s; u32 s;
s = (val >> (i * 2)); s = (val >> (i * 2));
...@@ -1356,10 +1356,6 @@ static int qcom_swrm_probe(struct platform_device *pdev) ...@@ -1356,10 +1356,6 @@ static int qcom_swrm_probe(struct platform_device *pdev)
ctrl->bus.compute_params = &qcom_swrm_compute_params; ctrl->bus.compute_params = &qcom_swrm_compute_params;
ctrl->bus.clk_stop_timeout = 300; ctrl->bus.clk_stop_timeout = 300;
ctrl->audio_cgcr = devm_reset_control_get_exclusive(dev, "swr_audio_cgcr");
if (IS_ERR(ctrl->audio_cgcr))
dev_err(dev, "Failed to get audio_cgcr reset required for soundwire-v1.6.0\n");
ret = qcom_swrm_get_port_config(ctrl); ret = qcom_swrm_get_port_config(ctrl);
if (ret) if (ret)
goto err_clk; goto err_clk;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment