cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

watchdog_core.c (13258B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 *	watchdog_core.c
      4 *
      5 *	(c) Copyright 2008-2011 Alan Cox <alan@lxorguk.ukuu.org.uk>,
      6 *						All Rights Reserved.
      7 *
      8 *	(c) Copyright 2008-2011 Wim Van Sebroeck <wim@iguana.be>.
      9 *
     10 *	This source code is part of the generic code that can be used
     11 *	by all the watchdog timer drivers.
     12 *
     13 *	Based on source code of the following authors:
     14 *	  Matt Domsch <Matt_Domsch@dell.com>,
     15 *	  Rob Radez <rob@osinvestor.com>,
     16 *	  Rusty Lynch <rusty@linux.co.intel.com>
     17 *	  Satyam Sharma <satyam@infradead.org>
     18 *	  Randy Dunlap <randy.dunlap@oracle.com>
     19 *
     20 *	Neither Alan Cox, CymruNet Ltd., Wim Van Sebroeck nor Iguana vzw.
     21 *	admit liability nor provide warranty for any of this software.
     22 *	This material is provided "AS-IS" and at no charge.
     23 */
     24
     25#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     26
     27#include <linux/module.h>	/* For EXPORT_SYMBOL/module stuff/... */
     28#include <linux/types.h>	/* For standard types */
     29#include <linux/errno.h>	/* For the -ENODEV/... values */
     30#include <linux/kernel.h>	/* For printk/panic/... */
     31#include <linux/reboot.h>	/* For restart handler */
     32#include <linux/watchdog.h>	/* For watchdog specific items */
     33#include <linux/init.h>		/* For __init/__exit/... */
     34#include <linux/idr.h>		/* For ida_* macros */
     35#include <linux/err.h>		/* For IS_ERR macros */
     36#include <linux/of.h>		/* For of_get_timeout_sec */
     37#include <linux/suspend.h>
     38
     39#include "watchdog_core.h"	/* For watchdog_dev_register/... */
     40
     41static DEFINE_IDA(watchdog_ida);
     42
     43static int stop_on_reboot = -1;
     44module_param(stop_on_reboot, int, 0444);
     45MODULE_PARM_DESC(stop_on_reboot, "Stop watchdogs on reboot (0=keep watching, 1=stop)");
     46
     47/*
     48 * Deferred Registration infrastructure.
     49 *
     50 * Sometimes watchdog drivers needs to be loaded as soon as possible,
     51 * for example when it's impossible to disable it. To do so,
     52 * raising the initcall level of the watchdog driver is a solution.
     53 * But in such case, the miscdev is maybe not ready (subsys_initcall), and
     54 * watchdog_core need miscdev to register the watchdog as a char device.
     55 *
     56 * The deferred registration infrastructure offer a way for the watchdog
     57 * subsystem to register a watchdog properly, even before miscdev is ready.
     58 */
     59
     60static DEFINE_MUTEX(wtd_deferred_reg_mutex);
     61static LIST_HEAD(wtd_deferred_reg_list);
     62static bool wtd_deferred_reg_done;
     63
     64static void watchdog_deferred_registration_add(struct watchdog_device *wdd)
     65{
     66	list_add_tail(&wdd->deferred,
     67		      &wtd_deferred_reg_list);
     68}
     69
     70static void watchdog_deferred_registration_del(struct watchdog_device *wdd)
     71{
     72	struct list_head *p, *n;
     73	struct watchdog_device *wdd_tmp;
     74
     75	list_for_each_safe(p, n, &wtd_deferred_reg_list) {
     76		wdd_tmp = list_entry(p, struct watchdog_device,
     77				     deferred);
     78		if (wdd_tmp == wdd) {
     79			list_del(&wdd_tmp->deferred);
     80			break;
     81		}
     82	}
     83}
     84
     85static void watchdog_check_min_max_timeout(struct watchdog_device *wdd)
     86{
     87	/*
     88	 * Check that we have valid min and max timeout values, if
     89	 * not reset them both to 0 (=not used or unknown)
     90	 */
     91	if (!wdd->max_hw_heartbeat_ms && wdd->min_timeout > wdd->max_timeout) {
     92		pr_info("Invalid min and max timeout values, resetting to 0!\n");
     93		wdd->min_timeout = 0;
     94		wdd->max_timeout = 0;
     95	}
     96}
     97
     98/**
     99 * watchdog_init_timeout() - initialize the timeout field
    100 * @wdd: watchdog device
    101 * @timeout_parm: timeout module parameter
    102 * @dev: Device that stores the timeout-sec property
    103 *
    104 * Initialize the timeout field of the watchdog_device struct with either the
    105 * timeout module parameter (if it is valid value) or the timeout-sec property
    106 * (only if it is a valid value and the timeout_parm is out of bounds).
    107 * If none of them are valid then we keep the old value (which should normally
    108 * be the default timeout value). Note that for the module parameter, '0' means
    109 * 'use default' while it is an invalid value for the timeout-sec property.
    110 * It should simply be dropped if you want to use the default value then.
    111 *
    112 * A zero is returned on success or -EINVAL if all provided values are out of
    113 * bounds.
    114 */
    115int watchdog_init_timeout(struct watchdog_device *wdd,
    116				unsigned int timeout_parm, struct device *dev)
    117{
    118	const char *dev_str = wdd->parent ? dev_name(wdd->parent) :
    119			      (const char *)wdd->info->identity;
    120	unsigned int t = 0;
    121	int ret = 0;
    122
    123	watchdog_check_min_max_timeout(wdd);
    124
    125	/* check the driver supplied value (likely a module parameter) first */
    126	if (timeout_parm) {
    127		if (!watchdog_timeout_invalid(wdd, timeout_parm)) {
    128			wdd->timeout = timeout_parm;
    129			return 0;
    130		}
    131		pr_err("%s: driver supplied timeout (%u) out of range\n",
    132			dev_str, timeout_parm);
    133		ret = -EINVAL;
    134	}
    135
    136	/* try to get the timeout_sec property */
    137	if (dev && dev->of_node &&
    138	    of_property_read_u32(dev->of_node, "timeout-sec", &t) == 0) {
    139		if (t && !watchdog_timeout_invalid(wdd, t)) {
    140			wdd->timeout = t;
    141			return 0;
    142		}
    143		pr_err("%s: DT supplied timeout (%u) out of range\n", dev_str, t);
    144		ret = -EINVAL;
    145	}
    146
    147	if (ret < 0 && wdd->timeout)
    148		pr_warn("%s: falling back to default timeout (%u)\n", dev_str,
    149			wdd->timeout);
    150
    151	return ret;
    152}
    153EXPORT_SYMBOL_GPL(watchdog_init_timeout);
    154
    155static int watchdog_reboot_notifier(struct notifier_block *nb,
    156				    unsigned long code, void *data)
    157{
    158	struct watchdog_device *wdd;
    159
    160	wdd = container_of(nb, struct watchdog_device, reboot_nb);
    161	if (code == SYS_DOWN || code == SYS_HALT) {
    162		if (watchdog_active(wdd) || watchdog_hw_running(wdd)) {
    163			int ret;
    164
    165			ret = wdd->ops->stop(wdd);
    166			if (ret)
    167				return NOTIFY_BAD;
    168		}
    169	}
    170
    171	return NOTIFY_DONE;
    172}
    173
    174static int watchdog_restart_notifier(struct notifier_block *nb,
    175				     unsigned long action, void *data)
    176{
    177	struct watchdog_device *wdd = container_of(nb, struct watchdog_device,
    178						   restart_nb);
    179
    180	int ret;
    181
    182	ret = wdd->ops->restart(wdd, action, data);
    183	if (ret)
    184		return NOTIFY_BAD;
    185
    186	return NOTIFY_DONE;
    187}
    188
    189static int watchdog_pm_notifier(struct notifier_block *nb, unsigned long mode,
    190				void *data)
    191{
    192	struct watchdog_device *wdd;
    193	int ret = 0;
    194
    195	wdd = container_of(nb, struct watchdog_device, pm_nb);
    196
    197	switch (mode) {
    198	case PM_HIBERNATION_PREPARE:
    199	case PM_RESTORE_PREPARE:
    200	case PM_SUSPEND_PREPARE:
    201		ret = watchdog_dev_suspend(wdd);
    202		break;
    203	case PM_POST_HIBERNATION:
    204	case PM_POST_RESTORE:
    205	case PM_POST_SUSPEND:
    206		ret = watchdog_dev_resume(wdd);
    207		break;
    208	}
    209
    210	if (ret)
    211		return NOTIFY_BAD;
    212
    213	return NOTIFY_DONE;
    214}
    215
    216/**
    217 * watchdog_set_restart_priority - Change priority of restart handler
    218 * @wdd: watchdog device
    219 * @priority: priority of the restart handler, should follow these guidelines:
    220 *   0:   use watchdog's restart function as last resort, has limited restart
    221 *        capabilies
    222 *   128: default restart handler, use if no other handler is expected to be
    223 *        available and/or if restart is sufficient to restart the entire system
    224 *   255: preempt all other handlers
    225 *
    226 * If a wdd->ops->restart function is provided when watchdog_register_device is
    227 * called, it will be registered as a restart handler with the priority given
    228 * here.
    229 */
    230void watchdog_set_restart_priority(struct watchdog_device *wdd, int priority)
    231{
    232	wdd->restart_nb.priority = priority;
    233}
    234EXPORT_SYMBOL_GPL(watchdog_set_restart_priority);
    235
    236static int __watchdog_register_device(struct watchdog_device *wdd)
    237{
    238	int ret, id = -1;
    239
    240	if (wdd == NULL || wdd->info == NULL || wdd->ops == NULL)
    241		return -EINVAL;
    242
    243	/* Mandatory operations need to be supported */
    244	if (!wdd->ops->start || (!wdd->ops->stop && !wdd->max_hw_heartbeat_ms))
    245		return -EINVAL;
    246
    247	watchdog_check_min_max_timeout(wdd);
    248
    249	/*
    250	 * Note: now that all watchdog_device data has been verified, we
    251	 * will not check this anymore in other functions. If data gets
    252	 * corrupted in a later stage then we expect a kernel panic!
    253	 */
    254
    255	/* Use alias for watchdog id if possible */
    256	if (wdd->parent) {
    257		ret = of_alias_get_id(wdd->parent->of_node, "watchdog");
    258		if (ret >= 0)
    259			id = ida_simple_get(&watchdog_ida, ret,
    260					    ret + 1, GFP_KERNEL);
    261	}
    262
    263	if (id < 0)
    264		id = ida_simple_get(&watchdog_ida, 0, MAX_DOGS, GFP_KERNEL);
    265
    266	if (id < 0)
    267		return id;
    268	wdd->id = id;
    269
    270	ret = watchdog_dev_register(wdd);
    271	if (ret) {
    272		ida_simple_remove(&watchdog_ida, id);
    273		if (!(id == 0 && ret == -EBUSY))
    274			return ret;
    275
    276		/* Retry in case a legacy watchdog module exists */
    277		id = ida_simple_get(&watchdog_ida, 1, MAX_DOGS, GFP_KERNEL);
    278		if (id < 0)
    279			return id;
    280		wdd->id = id;
    281
    282		ret = watchdog_dev_register(wdd);
    283		if (ret) {
    284			ida_simple_remove(&watchdog_ida, id);
    285			return ret;
    286		}
    287	}
    288
    289	/* Module parameter to force watchdog policy on reboot. */
    290	if (stop_on_reboot != -1) {
    291		if (stop_on_reboot)
    292			set_bit(WDOG_STOP_ON_REBOOT, &wdd->status);
    293		else
    294			clear_bit(WDOG_STOP_ON_REBOOT, &wdd->status);
    295	}
    296
    297	if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
    298		if (!wdd->ops->stop)
    299			pr_warn("watchdog%d: stop_on_reboot not supported\n", wdd->id);
    300		else {
    301			wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
    302
    303			ret = register_reboot_notifier(&wdd->reboot_nb);
    304			if (ret) {
    305				pr_err("watchdog%d: Cannot register reboot notifier (%d)\n",
    306					wdd->id, ret);
    307				watchdog_dev_unregister(wdd);
    308				ida_simple_remove(&watchdog_ida, id);
    309				return ret;
    310			}
    311		}
    312	}
    313
    314	if (wdd->ops->restart) {
    315		wdd->restart_nb.notifier_call = watchdog_restart_notifier;
    316
    317		ret = register_restart_handler(&wdd->restart_nb);
    318		if (ret)
    319			pr_warn("watchdog%d: Cannot register restart handler (%d)\n",
    320				wdd->id, ret);
    321	}
    322
    323	if (test_bit(WDOG_NO_PING_ON_SUSPEND, &wdd->status)) {
    324		wdd->pm_nb.notifier_call = watchdog_pm_notifier;
    325
    326		ret = register_pm_notifier(&wdd->pm_nb);
    327		if (ret)
    328			pr_warn("watchdog%d: Cannot register pm handler (%d)\n",
    329				wdd->id, ret);
    330	}
    331
    332	return 0;
    333}
    334
    335/**
    336 * watchdog_register_device() - register a watchdog device
    337 * @wdd: watchdog device
    338 *
    339 * Register a watchdog device with the kernel so that the
    340 * watchdog timer can be accessed from userspace.
    341 *
    342 * A zero is returned on success and a negative errno code for
    343 * failure.
    344 */
    345
    346int watchdog_register_device(struct watchdog_device *wdd)
    347{
    348	const char *dev_str;
    349	int ret = 0;
    350
    351	mutex_lock(&wtd_deferred_reg_mutex);
    352	if (wtd_deferred_reg_done)
    353		ret = __watchdog_register_device(wdd);
    354	else
    355		watchdog_deferred_registration_add(wdd);
    356	mutex_unlock(&wtd_deferred_reg_mutex);
    357
    358	if (ret) {
    359		dev_str = wdd->parent ? dev_name(wdd->parent) :
    360			  (const char *)wdd->info->identity;
    361		pr_err("%s: failed to register watchdog device (err = %d)\n",
    362			dev_str, ret);
    363	}
    364
    365	return ret;
    366}
    367EXPORT_SYMBOL_GPL(watchdog_register_device);
    368
    369static void __watchdog_unregister_device(struct watchdog_device *wdd)
    370{
    371	if (wdd == NULL)
    372		return;
    373
    374	if (wdd->ops->restart)
    375		unregister_restart_handler(&wdd->restart_nb);
    376
    377	if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status))
    378		unregister_reboot_notifier(&wdd->reboot_nb);
    379
    380	watchdog_dev_unregister(wdd);
    381	ida_simple_remove(&watchdog_ida, wdd->id);
    382}
    383
    384/**
    385 * watchdog_unregister_device() - unregister a watchdog device
    386 * @wdd: watchdog device to unregister
    387 *
    388 * Unregister a watchdog device that was previously successfully
    389 * registered with watchdog_register_device().
    390 */
    391
    392void watchdog_unregister_device(struct watchdog_device *wdd)
    393{
    394	mutex_lock(&wtd_deferred_reg_mutex);
    395	if (wtd_deferred_reg_done)
    396		__watchdog_unregister_device(wdd);
    397	else
    398		watchdog_deferred_registration_del(wdd);
    399	mutex_unlock(&wtd_deferred_reg_mutex);
    400}
    401
    402EXPORT_SYMBOL_GPL(watchdog_unregister_device);
    403
    404static void devm_watchdog_unregister_device(struct device *dev, void *res)
    405{
    406	watchdog_unregister_device(*(struct watchdog_device **)res);
    407}
    408
    409/**
    410 * devm_watchdog_register_device() - resource managed watchdog_register_device()
    411 * @dev: device that is registering this watchdog device
    412 * @wdd: watchdog device
    413 *
    414 * Managed watchdog_register_device(). For watchdog device registered by this
    415 * function,  watchdog_unregister_device() is automatically called on driver
    416 * detach. See watchdog_register_device() for more information.
    417 */
    418int devm_watchdog_register_device(struct device *dev,
    419				struct watchdog_device *wdd)
    420{
    421	struct watchdog_device **rcwdd;
    422	int ret;
    423
    424	rcwdd = devres_alloc(devm_watchdog_unregister_device, sizeof(*rcwdd),
    425			     GFP_KERNEL);
    426	if (!rcwdd)
    427		return -ENOMEM;
    428
    429	ret = watchdog_register_device(wdd);
    430	if (!ret) {
    431		*rcwdd = wdd;
    432		devres_add(dev, rcwdd);
    433	} else {
    434		devres_free(rcwdd);
    435	}
    436
    437	return ret;
    438}
    439EXPORT_SYMBOL_GPL(devm_watchdog_register_device);
    440
    441static int __init watchdog_deferred_registration(void)
    442{
    443	mutex_lock(&wtd_deferred_reg_mutex);
    444	wtd_deferred_reg_done = true;
    445	while (!list_empty(&wtd_deferred_reg_list)) {
    446		struct watchdog_device *wdd;
    447
    448		wdd = list_first_entry(&wtd_deferred_reg_list,
    449				       struct watchdog_device, deferred);
    450		list_del(&wdd->deferred);
    451		__watchdog_register_device(wdd);
    452	}
    453	mutex_unlock(&wtd_deferred_reg_mutex);
    454	return 0;
    455}
    456
    457static int __init watchdog_init(void)
    458{
    459	int err;
    460
    461	err = watchdog_dev_init();
    462	if (err < 0)
    463		return err;
    464
    465	watchdog_deferred_registration();
    466	return 0;
    467}
    468
    469static void __exit watchdog_exit(void)
    470{
    471	watchdog_dev_exit();
    472	ida_destroy(&watchdog_ida);
    473}
    474
    475subsys_initcall_sync(watchdog_init);
    476module_exit(watchdog_exit);
    477
    478MODULE_AUTHOR("Alan Cox <alan@lxorguk.ukuu.org.uk>");
    479MODULE_AUTHOR("Wim Van Sebroeck <wim@iguana.be>");
    480MODULE_DESCRIPTION("WatchDog Timer Driver Core");
    481MODULE_LICENSE("GPL");