Skip to content

Commit

Permalink
remove lots of IS_ERR_VALUE abuses
Browse files Browse the repository at this point in the history
Most users of IS_ERR_VALUE() in the kernel are wrong, as they
pass an 'int' into a function that takes an 'unsigned long'
argument. This happens to work because the type is sign-extended
on 64-bit architectures before it gets converted into an
unsigned type.

However, anything that passes an 'unsigned short' or 'unsigned int'
argument into IS_ERR_VALUE() is guaranteed to be broken, as are
8-bit integers and types that are wider than 'unsigned long'.

Andrzej Hajda has already fixed a lot of the worst abusers that
were causing actual bugs, but it would be nice to prevent any
users that are not passing 'unsigned long' arguments.

This patch changes all users of IS_ERR_VALUE() that I could find
on 32-bit ARM randconfig builds and x86 allmodconfig. For the
moment, this doesn't change the definition of IS_ERR_VALUE()
because there are probably still architecture specific users
elsewhere.

Almost all the warnings I got are for files that are better off
using 'if (err)' or 'if (err < 0)'.
The only legitimate user I could find that we get a warning for
is the (32-bit only) freescale fman driver, so I did not remove
the IS_ERR_VALUE() there but changed the type to 'unsigned long'.
For 9pfs, I just worked around one user whose calling conventions
are so obscure that I did not dare change the behavior.

I was using this definition for testing:

 #define IS_ERR_VALUE(x) ((unsigned long*)NULL == (typeof (x)*)NULL && \
       unlikely((unsigned long long)(x) >= (unsigned long long)(typeof(x))-MAX_ERRNO))

which ends up making all 16-bit or wider types work correctly with
the most plausible interpretation of what IS_ERR_VALUE() was supposed
to return according to its users, but also causes a compile-time
warning for any users that do not pass an 'unsigned long' argument.

I suggested this approach earlier this year, but back then we ended
up deciding to just fix the users that are obviously broken. After
the initial warning that caused me to get involved in the discussion
(fs/gfs2/dir.c) showed up again in the mainline kernel, Linus
asked me to send the whole thing again.

[ Updated the 9p parts as per Al Viro  - Linus ]

Signed-off-by: Arnd Bergmann <[email protected]>
Cc: Andrzej Hajda <[email protected]>
Cc: Andrew Morton <[email protected]>
Link: https://lkml.org/lkml/2016/1/7/363
Link: https://lkml.org/lkml/2016/5/27/486
Acked-by: Srinivas Kandagatla <[email protected]> # For nvmem part
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
arndb authored and torvalds committed May 27, 2016
1 parent 7ded384 commit 287980e
Show file tree
Hide file tree
Showing 38 changed files with 102 additions and 103 deletions.
22 changes: 11 additions & 11 deletions drivers/acpi/acpi_dbg.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ static int acpi_aml_write_kern(const char *buf, int len)
char *p;

ret = acpi_aml_lock_write(crc, ACPI_AML_OUT_KERN);
if (IS_ERR_VALUE(ret))
if (ret < 0)
return ret;
/* sync tail before inserting logs */
smp_mb();
Expand All @@ -286,7 +286,7 @@ static int acpi_aml_readb_kern(void)
char *p;

ret = acpi_aml_lock_read(crc, ACPI_AML_IN_KERN);
if (IS_ERR_VALUE(ret))
if (ret < 0)
return ret;
/* sync head before removing cmds */
smp_rmb();
Expand Down Expand Up @@ -330,7 +330,7 @@ static ssize_t acpi_aml_write_log(const char *msg)
goto again;
break;
}
if (IS_ERR_VALUE(ret))
if (ret < 0)
break;
size += ret;
count -= ret;
Expand Down Expand Up @@ -373,7 +373,7 @@ static ssize_t acpi_aml_read_cmd(char *msg, size_t count)
if (ret == 0)
goto again;
}
if (IS_ERR_VALUE(ret))
if (ret < 0)
break;
*(msg + size) = (char)ret;
size++;
Expand Down Expand Up @@ -526,7 +526,7 @@ static int acpi_aml_open(struct inode *inode, struct file *file)
}
acpi_aml_io.users++;
err_lock:
if (IS_ERR_VALUE(ret)) {
if (ret < 0) {
if (acpi_aml_active_reader == file)
acpi_aml_active_reader = NULL;
}
Expand Down Expand Up @@ -587,7 +587,7 @@ static int acpi_aml_read_user(char __user *buf, int len)
char *p;

ret = acpi_aml_lock_read(crc, ACPI_AML_OUT_USER);
if (IS_ERR_VALUE(ret))
if (ret < 0)
return ret;
/* sync head before removing logs */
smp_rmb();
Expand All @@ -602,7 +602,7 @@ static int acpi_aml_read_user(char __user *buf, int len)
crc->tail = (crc->tail + n) & (ACPI_AML_BUF_SIZE - 1);
ret = n;
out:
acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, !IS_ERR_VALUE(ret));
acpi_aml_unlock_fifo(ACPI_AML_OUT_USER, !ret);
return ret;
}

Expand Down Expand Up @@ -634,7 +634,7 @@ static ssize_t acpi_aml_read(struct file *file, char __user *buf,
goto again;
}
}
if (IS_ERR_VALUE(ret)) {
if (ret < 0) {
if (!acpi_aml_running())
ret = 0;
break;
Expand All @@ -657,7 +657,7 @@ static int acpi_aml_write_user(const char __user *buf, int len)
char *p;

ret = acpi_aml_lock_write(crc, ACPI_AML_IN_USER);
if (IS_ERR_VALUE(ret))
if (ret < 0)
return ret;
/* sync tail before inserting cmds */
smp_mb();
Expand All @@ -672,7 +672,7 @@ static int acpi_aml_write_user(const char __user *buf, int len)
crc->head = (crc->head + n) & (ACPI_AML_BUF_SIZE - 1);
ret = n;
out:
acpi_aml_unlock_fifo(ACPI_AML_IN_USER, !IS_ERR_VALUE(ret));
acpi_aml_unlock_fifo(ACPI_AML_IN_USER, !ret);
return n;
}

Expand Down Expand Up @@ -704,7 +704,7 @@ static ssize_t acpi_aml_write(struct file *file, const char __user *buf,
goto again;
}
}
if (IS_ERR_VALUE(ret)) {
if (ret < 0) {
if (!acpi_aml_running())
ret = 0;
break;
Expand Down
2 changes: 1 addition & 1 deletion drivers/ata/sata_highbank.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ static void highbank_set_em_messages(struct device *dev,

for (i = 0; i < SGPIO_PINS; i++) {
err = of_get_named_gpio(np, "calxeda,sgpio-gpio", i);
if (IS_ERR_VALUE(err))
if (err < 0)
return;

pdata->sgpio_gpio[i] = err;
Expand Down
2 changes: 1 addition & 1 deletion drivers/clk/tegra/clk-tegra210.c
Original file line number Diff line number Diff line change
Expand Up @@ -1221,7 +1221,7 @@ static int tegra210_pll_fixed_mdiv_cfg(struct clk_hw *hw,
p = rate >= params->vco_min ? 1 : -EINVAL;
}

if (IS_ERR_VALUE(p))
if (p < 0)
return -EINVAL;

cfg->m = tegra_pll_get_fixed_mdiv(hw, input_rate);
Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/omap-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static int omap_target(struct cpufreq_policy *policy, unsigned int index)

freq = new_freq * 1000;
ret = clk_round_rate(policy->clk, freq);
if (IS_ERR_VALUE(ret)) {
if (ret < 0) {
dev_warn(mpu_dev,
"CPUfreq: Cannot find matching frequency for %lu\n",
freq);
Expand Down
2 changes: 1 addition & 1 deletion drivers/crypto/caam/ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ int caam_get_era(void)
ret = of_property_read_u32(caam_node, "fsl,sec-era", &prop);
of_node_put(caam_node);

return IS_ERR_VALUE(ret) ? -ENOTSUPP : prop;
return ret ? -ENOTSUPP : prop;
}
EXPORT_SYMBOL(caam_get_era);

Expand Down
16 changes: 8 additions & 8 deletions drivers/dma/sun4i-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,25 +461,25 @@ generate_ndma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,

/* Source burst */
ret = convert_burst(sconfig->src_maxburst);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH(ret);

/* Destination burst */
ret = convert_burst(sconfig->dst_maxburst);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH(ret);

/* Source bus width */
ret = convert_buswidth(sconfig->src_addr_width);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH(ret);

/* Destination bus width */
ret = convert_buswidth(sconfig->dst_addr_width);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH(ret);

Expand Down Expand Up @@ -518,25 +518,25 @@ generate_ddma_promise(struct dma_chan *chan, dma_addr_t src, dma_addr_t dest,

/* Source burst */
ret = convert_burst(sconfig->src_maxburst);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_SRC_BURST_LENGTH(ret);

/* Destination burst */
ret = convert_burst(sconfig->dst_maxburst);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_DST_BURST_LENGTH(ret);

/* Source bus width */
ret = convert_buswidth(sconfig->src_addr_width);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_SRC_DATA_WIDTH(ret);

/* Destination bus width */
ret = convert_buswidth(sconfig->dst_addr_width);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto fail;
promise->cfg |= SUN4I_DMA_CFG_DST_DATA_WIDTH(ret);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpio/gpio-xlp.c
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,7 @@ static int xlp_gpio_probe(struct platform_device *pdev)
irq_base = irq_alloc_descs(-1, 0, gc->ngpio, 0);
else
irq_base = irq_alloc_descs(-1, XLP_GPIO_IRQ_BASE, gc->ngpio, 0);
if (IS_ERR_VALUE(irq_base)) {
if (irq_base < 0) {
dev_err(&pdev->dev, "Failed to allocate IRQ numbers\n");
return irq_base;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/sti/sti_vtg.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ static int vtg_probe(struct platform_device *pdev)
return -EPROBE_DEFER;
} else {
vtg->irq = platform_get_irq(pdev, 0);
if (IS_ERR_VALUE(vtg->irq)) {
if (vtg->irq < 0) {
DRM_ERROR("Failed to get VTG interrupt\n");
return vtg->irq;
}
Expand All @@ -447,7 +447,7 @@ static int vtg_probe(struct platform_device *pdev)
ret = devm_request_threaded_irq(dev, vtg->irq, vtg_irq,
vtg_irq_thread, IRQF_ONESHOT,
dev_name(dev), vtg);
if (IS_ERR_VALUE(ret)) {
if (ret < 0) {
DRM_ERROR("Failed to register VTG interrupt\n");
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/tilcdc/tilcdc_tfp410.c
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ static int tfp410_probe(struct platform_device *pdev)

tfp410_mod->gpio = of_get_named_gpio_flags(node, "powerdn-gpio",
0, NULL);
if (IS_ERR_VALUE(tfp410_mod->gpio)) {
if (tfp410_mod->gpio < 0) {
dev_warn(&pdev->dev, "No power down GPIO\n");
} else {
ret = gpio_request(tfp410_mod->gpio, "DVI_PDn");
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/host1x/hw/intr_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ static int _host1x_intr_init_host_sync(struct host1x *host, u32 cpm,
err = devm_request_irq(host->dev, host->intr_syncpt_irq,
syncpt_thresh_isr, IRQF_SHARED,
"host1x_syncpt", host);
if (IS_ERR_VALUE(err)) {
if (err < 0) {
WARN_ON(1);
return err;
}
Expand Down
18 changes: 9 additions & 9 deletions drivers/iommu/arm-smmu-v3.c
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,7 @@ static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;

asid = arm_smmu_bitmap_alloc(smmu->asid_map, smmu->asid_bits);
if (IS_ERR_VALUE(asid))
if (asid < 0)
return asid;

cfg->cdptr = dmam_alloc_coherent(smmu->dev, CTXDESC_CD_DWORDS << 3,
Expand Down Expand Up @@ -1508,7 +1508,7 @@ static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;

vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
if (IS_ERR_VALUE(vmid))
if (vmid < 0)
return vmid;

cfg->vmid = (u16)vmid;
Expand Down Expand Up @@ -1569,7 +1569,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
smmu_domain->pgtbl_ops = pgtbl_ops;

ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
if (IS_ERR_VALUE(ret))
if (ret < 0)
free_io_pgtable_ops(pgtbl_ops);

return ret;
Expand Down Expand Up @@ -1642,7 +1642,7 @@ static void arm_smmu_detach_dev(struct device *dev)
struct arm_smmu_group *smmu_group = arm_smmu_group_get(dev);

smmu_group->ste.bypass = true;
if (IS_ERR_VALUE(arm_smmu_install_ste_for_group(smmu_group)))
if (arm_smmu_install_ste_for_group(smmu_group) < 0)
dev_warn(dev, "failed to install bypass STE\n");

smmu_group->domain = NULL;
Expand Down Expand Up @@ -1694,7 +1694,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
smmu_group->ste.bypass = domain->type == IOMMU_DOMAIN_DMA;

ret = arm_smmu_install_ste_for_group(smmu_group);
if (IS_ERR_VALUE(ret))
if (ret < 0)
smmu_group->domain = NULL;

out_unlock:
Expand Down Expand Up @@ -2235,7 +2235,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
arm_smmu_evtq_handler,
arm_smmu_evtq_thread,
0, "arm-smmu-v3-evtq", smmu);
if (IS_ERR_VALUE(ret))
if (ret < 0)
dev_warn(smmu->dev, "failed to enable evtq irq\n");
}

Expand All @@ -2244,15 +2244,15 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
ret = devm_request_irq(smmu->dev, irq,
arm_smmu_cmdq_sync_handler, 0,
"arm-smmu-v3-cmdq-sync", smmu);
if (IS_ERR_VALUE(ret))
if (ret < 0)
dev_warn(smmu->dev, "failed to enable cmdq-sync irq\n");
}

irq = smmu->gerr_irq;
if (irq) {
ret = devm_request_irq(smmu->dev, irq, arm_smmu_gerror_handler,
0, "arm-smmu-v3-gerror", smmu);
if (IS_ERR_VALUE(ret))
if (ret < 0)
dev_warn(smmu->dev, "failed to enable gerror irq\n");
}

Expand All @@ -2264,7 +2264,7 @@ static int arm_smmu_setup_irqs(struct arm_smmu_device *smmu)
arm_smmu_priq_thread,
0, "arm-smmu-v3-priq",
smmu);
if (IS_ERR_VALUE(ret))
if (ret < 0)
dev_warn(smmu->dev,
"failed to enable priq irq\n");
else
Expand Down
8 changes: 4 additions & 4 deletions drivers/iommu/arm-smmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -950,7 +950,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,

ret = __arm_smmu_alloc_bitmap(smmu->context_map, start,
smmu->num_context_banks);
if (IS_ERR_VALUE(ret))
if (ret < 0)
goto out_unlock;

cfg->cbndx = ret;
Expand Down Expand Up @@ -989,7 +989,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
ret = request_irq(irq, arm_smmu_context_fault, IRQF_SHARED,
"arm-smmu-context-fault", domain);
if (IS_ERR_VALUE(ret)) {
if (ret < 0) {
dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
cfg->irptndx, irq);
cfg->irptndx = INVALID_IRPTNDX;
Expand Down Expand Up @@ -1099,7 +1099,7 @@ static int arm_smmu_master_configure_smrs(struct arm_smmu_device *smmu,
for (i = 0; i < cfg->num_streamids; ++i) {
int idx = __arm_smmu_alloc_bitmap(smmu->smr_map, 0,
smmu->num_mapping_groups);
if (IS_ERR_VALUE(idx)) {
if (idx < 0) {
dev_err(smmu->dev, "failed to allocate free SMR\n");
goto err_free_smrs;
}
Expand Down Expand Up @@ -1233,7 +1233,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)

/* Ensure that the domain is finalised */
ret = arm_smmu_init_domain_context(domain, smmu);
if (IS_ERR_VALUE(ret))
if (ret < 0)
return ret;

/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-clps711x.c
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ static int __init _clps711x_intc_init(struct device_node *np,
writel_relaxed(0, clps711x_intc->intmr[2]);

err = irq_alloc_descs(-1, 0, ARRAY_SIZE(clps711x_irqs), numa_node_id());
if (IS_ERR_VALUE(err))
if (err < 0)
goto out_iounmap;

clps711x_intc->ops.map = clps711x_intc_irq_map;
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-gic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1123,7 +1123,7 @@ static int __init __gic_init_bases(struct gic_chip_data *gic, int irq_start,

irq_base = irq_alloc_descs(irq_start, 16, gic_irqs,
numa_node_id());
if (IS_ERR_VALUE(irq_base)) {
if (irq_base < 0) {
WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
irq_start);
irq_base = irq_start;
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/irq-hip04.c
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ hip04_of_init(struct device_node *node, struct device_node *parent)
nr_irqs -= hwirq_base; /* calculate # of irqs to allocate */

irq_base = irq_alloc_descs(-1, hwirq_base, nr_irqs, numa_node_id());
if (IS_ERR_VALUE(irq_base)) {
if (irq_base < 0) {
pr_err("failed to allocate IRQ numbers\n");
return -EINVAL;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/irqchip/spear-shirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ static int __init shirq_init(struct spear_shirq **shirq_blocks, int block_nr,
nr_irqs += shirq_blocks[i]->nr_irqs;

virq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
if (IS_ERR_VALUE(virq_base)) {
if (virq_base < 0) {
pr_err("%s: irq desc alloc failed\n", __func__);
goto err_unmap;
}
Expand Down
Loading

0 comments on commit 287980e

Please sign in to comment.