mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 21:00:53 +07:00
s390/watchdog: add support for LPAR operation (diag288)
Add the LPAR variant of the diag 288 watchdog to the driver. The only available action on timeout for LPAR is a PSW restart. Signed-off-by: Philipp Hachtmann <phacht@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
f7a94db4e9
commit
646f919e93
@ -1304,6 +1304,8 @@ config DIAG288_WATCHDOG
|
|||||||
provide a virtual watchdog timer to their guest that cause a
|
provide a virtual watchdog timer to their guest that cause a
|
||||||
user define Control Program command to be executed after a
|
user define Control Program command to be executed after a
|
||||||
timeout.
|
timeout.
|
||||||
|
LPAR provides a very similar interface. This driver handles
|
||||||
|
both.
|
||||||
|
|
||||||
To compile this driver as a module, choose M here. The module
|
To compile this driver as a module, choose M here. The module
|
||||||
will be called vmwatchdog.
|
will be called vmwatchdog.
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
/*
|
/*
|
||||||
* Watchdog driver for z/VM using the diag 288 interface.
|
* Watchdog driver for z/VM and LPAR using the diag 288 interface.
|
||||||
*
|
*
|
||||||
* Under z/VM, expiration of the watchdog will send a "system restart" command
|
* Under z/VM, expiration of the watchdog will send a "system restart" command
|
||||||
* to CP.
|
* to CP.
|
||||||
*
|
*
|
||||||
* The command can be altered using the module parameter "cmd".
|
* The command can be altered using the module parameter "cmd". This is
|
||||||
|
* not recommended because it's only supported on z/VM but not whith LPAR.
|
||||||
|
*
|
||||||
|
* On LPAR, the watchdog will always trigger a system restart. the module
|
||||||
|
* paramter cmd is meaningless here.
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2004, 2013
|
* Copyright IBM Corp. 2004, 2013
|
||||||
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
|
* Author(s): Arnd Bergmann (arndb@de.ibm.com)
|
||||||
@ -41,6 +46,9 @@
|
|||||||
#define WDT_FUNC_CANCEL 2
|
#define WDT_FUNC_CANCEL 2
|
||||||
#define WDT_FUNC_CONCEAL 0x80000000
|
#define WDT_FUNC_CONCEAL 0x80000000
|
||||||
|
|
||||||
|
/* Action codes for LPAR watchdog */
|
||||||
|
#define LPARWDT_RESTART 0
|
||||||
|
|
||||||
static char wdt_cmd[MAX_CMDLEN] = DEFAULT_CMD;
|
static char wdt_cmd[MAX_CMDLEN] = DEFAULT_CMD;
|
||||||
static bool conceal_on;
|
static bool conceal_on;
|
||||||
static bool nowayout_info = WATCHDOG_NOWAYOUT;
|
static bool nowayout_info = WATCHDOG_NOWAYOUT;
|
||||||
@ -89,6 +97,12 @@ static int __diag288_vm(unsigned int func, unsigned int timeout,
|
|||||||
return __diag288(func, timeout, virt_to_phys(cmd), len);
|
return __diag288(func, timeout, virt_to_phys(cmd), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __diag288_lpar(unsigned int func, unsigned int timeout,
|
||||||
|
unsigned long action)
|
||||||
|
{
|
||||||
|
return __diag288(func, timeout, action, 0);
|
||||||
|
}
|
||||||
|
|
||||||
static int wdt_start(struct watchdog_device *dev)
|
static int wdt_start(struct watchdog_device *dev)
|
||||||
{
|
{
|
||||||
char *ebc_cmd;
|
char *ebc_cmd;
|
||||||
@ -113,6 +127,11 @@ static int wdt_start(struct watchdog_device *dev)
|
|||||||
kfree(ebc_cmd);
|
kfree(ebc_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MACHINE_IS_LPAR) {
|
||||||
|
ret = __diag288_lpar(WDT_FUNC_INIT,
|
||||||
|
dev->timeout, LPARWDT_RESTART);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("The watchdog cannot be activated\n");
|
pr_err("The watchdog cannot be activated\n");
|
||||||
return ret;
|
return ret;
|
||||||
@ -149,7 +168,8 @@ static int wdt_ping(struct watchdog_device *dev)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* It seems to be ok to z/VM to use the init function to
|
* It seems to be ok to z/VM to use the init function to
|
||||||
* retrigger the watchdog.
|
* retrigger the watchdog. On LPAR WDT_FUNC_CHANGE must
|
||||||
|
* be used when the watchdog is running.
|
||||||
*/
|
*/
|
||||||
func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL)
|
func = conceal_on ? (WDT_FUNC_INIT | WDT_FUNC_CONCEAL)
|
||||||
: WDT_FUNC_INIT;
|
: WDT_FUNC_INIT;
|
||||||
@ -159,6 +179,9 @@ static int wdt_ping(struct watchdog_device *dev)
|
|||||||
kfree(ebc_cmd);
|
kfree(ebc_cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MACHINE_IS_LPAR)
|
||||||
|
ret = __diag288_lpar(WDT_FUNC_CHANGE, dev->timeout, 0);
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
pr_err("The watchdog timer cannot be started or reset\n");
|
pr_err("The watchdog timer cannot be started or reset\n");
|
||||||
return ret;
|
return ret;
|
||||||
@ -256,12 +279,18 @@ static int __init diag288_init(void)
|
|||||||
pr_err("The watchdog cannot be initialized\n");
|
pr_err("The watchdog cannot be initialized\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
} else if (MACHINE_IS_LPAR) {
|
||||||
|
pr_info("The watchdog device driver detected an LPAR environment\n");
|
||||||
|
if (__diag288_lpar(WDT_FUNC_INIT, 30, LPARWDT_RESTART)) {
|
||||||
|
pr_err("The watchdog cannot be initialized\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pr_err("Linux runs in an environment that does not support the diag288 watchdog\n");
|
pr_err("Linux runs in an environment that does not support the diag288 watchdog\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (__diag288_vm(WDT_FUNC_CANCEL, 0, NULL, 0)) {
|
if (__diag288_lpar(WDT_FUNC_CANCEL, 0, 0)) {
|
||||||
pr_err("The watchdog cannot be deactivated\n");
|
pr_err("The watchdog cannot be deactivated\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user