Revision 61bf318eac2c13356f7bd1c6a05421ef504ccc8a authored by Sergei Trofimovich on 13 March 2021, 05:08:27 UTC, committed by Linus Torvalds on 13 March 2021, 19:27:31 UTC
In https://bugs.gentoo.org/769614 Dmitry noticed that `ptrace(PTRACE_GET_SYSCALL_INFO)` does not return error sign properly. The bug is in mismatch between get/set errors: static inline long syscall_get_error(struct task_struct *task, struct pt_regs *regs) { return regs->r10 == -1 ? regs->r8:0; } static inline long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) { return regs->r8; } static inline void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, int error, long val) { if (error) { /* error < 0, but ia64 uses > 0 return value */ regs->r8 = -error; regs->r10 = -1; } else { regs->r8 = val; regs->r10 = 0; } } Tested on v5.10 on rx3600 machine (ia64 9040 CPU). Link: https://lkml.kernel.org/r/20210221002554.333076-2-slyfox@gentoo.org Link: https://bugs.gentoo.org/769614 Signed-off-by: Sergei Trofimovich <slyfox@gentoo.org> Reported-by: Dmitry V. Levin <ldv@altlinux.org> Reviewed-by: Dmitry V. Levin <ldv@altlinux.org> Cc: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de> Cc: Oleg Nesterov <oleg@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
1 parent 0ceb1ac
wm831x-spi.c
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* wm831x-spi.c -- SPI access for Wolfson WM831x PMICs
*
* Copyright 2009,2010 Wolfson Microelectronics PLC.
*
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/pm.h>
#include <linux/spi/spi.h>
#include <linux/regmap.h>
#include <linux/err.h>
#include <linux/mfd/wm831x/core.h>
static int wm831x_spi_probe(struct spi_device *spi)
{
struct wm831x_pdata *pdata = dev_get_platdata(&spi->dev);
const struct spi_device_id *id = spi_get_device_id(spi);
const struct of_device_id *of_id;
struct wm831x *wm831x;
enum wm831x_parent type;
int ret;
if (spi->dev.of_node) {
of_id = of_match_device(wm831x_of_match, &spi->dev);
if (!of_id) {
dev_err(&spi->dev, "Failed to match device\n");
return -ENODEV;
}
type = (enum wm831x_parent)of_id->data;
} else {
type = (enum wm831x_parent)id->driver_data;
}
wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL);
if (wm831x == NULL)
return -ENOMEM;
spi->mode = SPI_MODE_0;
spi_set_drvdata(spi, wm831x);
wm831x->dev = &spi->dev;
wm831x->type = type;
wm831x->regmap = devm_regmap_init_spi(spi, &wm831x_regmap_config);
if (IS_ERR(wm831x->regmap)) {
ret = PTR_ERR(wm831x->regmap);
dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
ret);
return ret;
}
if (pdata)
memcpy(&wm831x->pdata, pdata, sizeof(*pdata));
return wm831x_device_init(wm831x, spi->irq);
}
static int wm831x_spi_suspend(struct device *dev)
{
struct wm831x *wm831x = dev_get_drvdata(dev);
return wm831x_device_suspend(wm831x);
}
static int wm831x_spi_poweroff(struct device *dev)
{
struct wm831x *wm831x = dev_get_drvdata(dev);
wm831x_device_shutdown(wm831x);
return 0;
}
static const struct dev_pm_ops wm831x_spi_pm = {
.freeze = wm831x_spi_suspend,
.suspend = wm831x_spi_suspend,
.poweroff = wm831x_spi_poweroff,
};
static const struct spi_device_id wm831x_spi_ids[] = {
{ "wm8310", WM8310 },
{ "wm8311", WM8311 },
{ "wm8312", WM8312 },
{ "wm8320", WM8320 },
{ "wm8321", WM8321 },
{ "wm8325", WM8325 },
{ "wm8326", WM8326 },
{ },
};
static struct spi_driver wm831x_spi_driver = {
.driver = {
.name = "wm831x",
.pm = &wm831x_spi_pm,
.of_match_table = of_match_ptr(wm831x_of_match),
.suppress_bind_attrs = true,
},
.id_table = wm831x_spi_ids,
.probe = wm831x_spi_probe,
};
static int __init wm831x_spi_init(void)
{
int ret;
ret = spi_register_driver(&wm831x_spi_driver);
if (ret != 0)
pr_err("Failed to register WM831x SPI driver: %d\n", ret);
return 0;
}
subsys_initcall(wm831x_spi_init);
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...