lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <48759bfa-bd21-f28f-043f-7b866d1b7e04@samsung.com>
Date:   Fri, 11 Dec 2020 17:12:16 +0100
From:   Marek Szyprowski <m.szyprowski@...sung.com>
To:     Uwe Kleine-König <u.kleine-koenig@...gutronix.de>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        "Rafael J . Wysocki" <rafael@...nel.org>
Cc:     kernel@...gutronix.de, linux-kernel@...r.kernel.org,
        Russell King <rmk+kernel@....linux.org.uk>
Subject: Re: [PATCH 3/3] driver core: platform: use bus_type functions

Hi Uwe,

On 19.11.2020 13:46, Uwe Kleine-König wrote:
> This works towards the goal mentioned in 2006 in commit 594c8281f905
> ("[PATCH] Add bus_type probe, remove, shutdown methods.").
>
> The functions are moved to where the other bus_type functions are
> defined and renamed to match the already established naming scheme.
>
> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@...gutronix.de>
> ---
>   drivers/base/platform.c | 132 ++++++++++++++++++++--------------------
>   1 file changed, 65 insertions(+), 67 deletions(-)
>
> diff --git a/drivers/base/platform.c b/drivers/base/platform.c
> index b847f5f8f992..8ad06daa2eaa 100644
> --- a/drivers/base/platform.c
> +++ b/drivers/base/platform.c
> @@ -743,70 +743,6 @@ struct platform_device *platform_device_register_full(
>   }
>   EXPORT_SYMBOL_GPL(platform_device_register_full);
>   
> -static int platform_probe_fail(struct platform_device *pdev);
> -
> -static int platform_drv_probe(struct device *_dev)
> -{
> -	struct platform_driver *drv = to_platform_driver(_dev->driver);
> -	struct platform_device *dev = to_platform_device(_dev);
> -	int ret;
> -
> -	/*
> -	 * A driver registered using platform_driver_probe() cannot be bound
> -	 * again later because the probe function usually lives in __init code
> -	 * and so is gone. For these drivers .probe is set to
> -	 * platform_probe_fail in __platform_driver_probe(). Don't even
> -	 * prepare clocks and PM domains for these to match the traditional
> -	 * behaviour.
> -	 */
> -	if (unlikely(drv->probe == platform_probe_fail))
> -		return -ENXIO;
> -
> -	ret = of_clk_set_defaults(_dev->of_node, false);
> -	if (ret < 0)
> -		return ret;
> -
> -	ret = dev_pm_domain_attach(_dev, true);
> -	if (ret)
> -		goto out;
> -
> -	if (drv->probe) {
> -		ret = drv->probe(dev);
> -		if (ret)
> -			dev_pm_domain_detach(_dev, true);
> -	}
> -
> -out:
> -	if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
> -		dev_warn(_dev, "probe deferral not supported\n");
> -		ret = -ENXIO;
> -	}
> -
> -	return ret;
> -}
> -
> -static int platform_drv_remove(struct device *_dev)
> -{
> -	struct platform_driver *drv = to_platform_driver(_dev->driver);
> -	struct platform_device *dev = to_platform_device(_dev);
> -	int ret = 0;
> -
> -	if (drv->remove)
> -		ret = drv->remove(dev);
> -	dev_pm_domain_detach(_dev, true);
> -
> -	return ret;
> -}
> -
> -static void platform_drv_shutdown(struct device *_dev)
> -{
> -	struct platform_driver *drv = to_platform_driver(_dev->driver);
> -	struct platform_device *dev = to_platform_device(_dev);
> -
> -	if (drv->shutdown)
> -		drv->shutdown(dev);
> -}
> -
>   /**
>    * __platform_driver_register - register a driver for platform-level devices
>    * @drv: platform driver structure
> @@ -817,9 +753,6 @@ int __platform_driver_register(struct platform_driver *drv,
>   {
>   	drv->driver.owner = owner;
>   	drv->driver.bus = &platform_bus_type;
> -	drv->driver.probe = platform_drv_probe;
> -	drv->driver.remove = platform_drv_remove;
> -	drv->driver.shutdown = platform_drv_shutdown;
>   
>   	return driver_register(&drv->driver);
>   }
> @@ -1349,6 +1282,68 @@ static int platform_uevent(struct device *dev, struct kobj_uevent_env *env)
>   	return 0;
>   }
>   
> +static int platform_probe(struct device *_dev)
> +{
> +	struct platform_driver *drv = to_platform_driver(_dev->driver);
> +	struct platform_device *dev = to_platform_device(_dev);
> +	int ret;
> +
> +	/*
> +	 * A driver registered using platform_driver_probe() cannot be bound
> +	 * again later because the probe function usually lives in __init code
> +	 * and so is gone. For these drivers .probe is set to
> +	 * platform_probe_fail in __platform_driver_probe(). Don't even prepare
> +	 * clocks and PM domains for these to match the traditional behaviour.
> +	 */
> +	if (unlikely(drv->probe == platform_probe_fail))
> +		return -ENXIO;
> +
> +	ret = of_clk_set_defaults(_dev->of_node, false);
> +	if (ret < 0)
> +		return ret;
> +
> +	ret = dev_pm_domain_attach(_dev, true);
> +	if (ret)
> +		goto out;
> +
> +	if (drv->probe) {
> +		ret = drv->probe(dev);
> +		if (ret)
> +			dev_pm_domain_detach(_dev, true);
> +	}
> +
> +out:
> +	if (drv->prevent_deferred_probe && ret == -EPROBE_DEFER) {
> +		dev_warn(_dev, "probe deferral not supported\n");
> +		ret = -ENXIO;
> +	}
> +
> +	return ret;
> +}
> +
> +static int platform_remove(struct device *_dev)
> +{
> +	struct platform_driver *drv = to_platform_driver(_dev->driver);
> +	struct platform_device *dev = to_platform_device(_dev);
> +	int ret = 0;
> +
> +	if (drv->remove)
> +		ret = drv->remove(dev);
> +	dev_pm_domain_detach(_dev, true);
> +
> +	return ret;
> +}
> +
> +static void platform_shutdown(struct device *_dev)
> +{
> +	struct platform_driver *drv = to_platform_driver(_dev->driver);
> +	struct platform_device *dev = to_platform_device(_dev);
> +
> +	if (drv->shutdown)
> +		drv->shutdown(dev);
> +}

This will be called on unbound devices, what causes crash (observed on 
today's linux-next):

Will now restart.
8<--- cut here ---
Unable to handle kernel paging request at virtual address fffffff4
pgd = 289f4b67
[fffffff4] *pgd=6ffff841, *pte=00000000, *ppte=00000000
Internal error: Oops: 27 [#1] SMP ARM
Modules linked in: usb_f_ecm g_ether usb_f_rndis u_ether libcomposite 
brcmfmac sha256_generic libsha256 sha256_arm cfg80211 brcmutil 
panel_samsung_s6e8aa0 s5p_csi
CPU: 0 PID: 1715 Comm: reboot Not tainted 
5.10.0-rc7-next-20201211-00069-g1e8aa883315f #9935
Hardware name: Samsung Exynos (Flattened Device Tree)
PC is at platform_shutdown+0x8/0x18
LR is at device_shutdown+0x18c/0x25c
...
Flags: nZCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
Control: 10c5387d  Table: 4348404a  DAC: 00000051
Process reboot (pid: 1715, stack limit = 0xd050391e)
Stack: (0xc3405e60 to 0xc3406000)
[<c0a38bfc>] (platform_shutdown) from [<c0a34f78>] 
(device_shutdown+0x18c/0x25c)
[<c0a34f78>] (device_shutdown) from [<c036d3cc>] (kernel_restart+0xc/0x68)
[<c036d3cc>] (kernel_restart) from [<c036d680>] 
(__do_sys_reboot+0x154/0x1f0)
[<c036d680>] (__do_sys_reboot) from [<c03000c0>] (ret_fast_syscall+0x0/0x58)
Exception stack(0xc3405fa8 to 0xc3405ff0)
...
---[ end trace f39e94d5d6fd45bf ]---


> +
> +
>   int platform_dma_configure(struct device *dev)
>   {
>   	enum dev_dma_attr attr;
> @@ -1375,6 +1370,9 @@ struct bus_type platform_bus_type = {
>   	.dev_groups	= platform_dev_groups,
>   	.match		= platform_match,
>   	.uevent		= platform_uevent,
> +	.probe		= platform_probe,
> +	.remove		= platform_remove,
> +	.shutdown	= platform_shutdown,
>   	.dma_configure	= platform_dma_configure,
>   	.pm		= &platform_dev_pm_ops,
>   };

Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ