hv_utils: Support host-initiated hibernation request
Update the Shutdown IC version to 3.2, which is required for the host to send the hibernation request. The user is expected to create the below udev rule file, which is applied upon the host-initiated hibernation request: root@localhost:~# cat /usr/lib/udev/rules.d/40-vm-hibernation.rules SUBSYSTEM=="vmbus", ACTION=="change", DRIVER=="hv_utils", ENV{EVENT}=="hibernate", RUN+="/usr/bin/systemctl hibernate" Signed-off-by: Dexuan Cui <decui@microsoft.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
3e9c72056e
commit
ffd1d4a493
|
@ -25,7 +25,9 @@
|
||||||
#define SD_MAJOR 3
|
#define SD_MAJOR 3
|
||||||
#define SD_MINOR 0
|
#define SD_MINOR 0
|
||||||
#define SD_MINOR_1 1
|
#define SD_MINOR_1 1
|
||||||
|
#define SD_MINOR_2 2
|
||||||
#define SD_VERSION_3_1 (SD_MAJOR << 16 | SD_MINOR_1)
|
#define SD_VERSION_3_1 (SD_MAJOR << 16 | SD_MINOR_1)
|
||||||
|
#define SD_VERSION_3_2 (SD_MAJOR << 16 | SD_MINOR_2)
|
||||||
#define SD_VERSION (SD_MAJOR << 16 | SD_MINOR)
|
#define SD_VERSION (SD_MAJOR << 16 | SD_MINOR)
|
||||||
|
|
||||||
#define SD_MAJOR_1 1
|
#define SD_MAJOR_1 1
|
||||||
|
@ -52,8 +54,9 @@ static int sd_srv_version;
|
||||||
static int ts_srv_version;
|
static int ts_srv_version;
|
||||||
static int hb_srv_version;
|
static int hb_srv_version;
|
||||||
|
|
||||||
#define SD_VER_COUNT 3
|
#define SD_VER_COUNT 4
|
||||||
static const int sd_versions[] = {
|
static const int sd_versions[] = {
|
||||||
|
SD_VERSION_3_2,
|
||||||
SD_VERSION_3_1,
|
SD_VERSION_3_1,
|
||||||
SD_VERSION,
|
SD_VERSION,
|
||||||
SD_VERSION_1
|
SD_VERSION_1
|
||||||
|
@ -78,9 +81,45 @@ static const int fw_versions[] = {
|
||||||
UTIL_WS2K8_FW_VERSION
|
UTIL_WS2K8_FW_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send the "hibernate" udev event in a thread context.
|
||||||
|
*/
|
||||||
|
struct hibernate_work_context {
|
||||||
|
struct work_struct work;
|
||||||
|
struct hv_device *dev;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct hibernate_work_context hibernate_context;
|
||||||
|
static bool hibernation_supported;
|
||||||
|
|
||||||
|
static void send_hibernate_uevent(struct work_struct *work)
|
||||||
|
{
|
||||||
|
char *uevent_env[2] = { "EVENT=hibernate", NULL };
|
||||||
|
struct hibernate_work_context *ctx;
|
||||||
|
|
||||||
|
ctx = container_of(work, struct hibernate_work_context, work);
|
||||||
|
|
||||||
|
kobject_uevent_env(&ctx->dev->device.kobj, KOBJ_CHANGE, uevent_env);
|
||||||
|
|
||||||
|
pr_info("Sent hibernation uevent\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int hv_shutdown_init(struct hv_util_service *srv)
|
||||||
|
{
|
||||||
|
struct vmbus_channel *channel = srv->channel;
|
||||||
|
|
||||||
|
INIT_WORK(&hibernate_context.work, send_hibernate_uevent);
|
||||||
|
hibernate_context.dev = channel->device_obj;
|
||||||
|
|
||||||
|
hibernation_supported = hv_is_hibernation_supported();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void shutdown_onchannelcallback(void *context);
|
static void shutdown_onchannelcallback(void *context);
|
||||||
static struct hv_util_service util_shutdown = {
|
static struct hv_util_service util_shutdown = {
|
||||||
.util_cb = shutdown_onchannelcallback,
|
.util_cb = shutdown_onchannelcallback,
|
||||||
|
.util_init = hv_shutdown_init,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int hv_timesync_init(struct hv_util_service *srv);
|
static int hv_timesync_init(struct hv_util_service *srv);
|
||||||
|
@ -191,6 +230,14 @@ static void shutdown_onchannelcallback(void *context)
|
||||||
pr_info("Restart request received -"
|
pr_info("Restart request received -"
|
||||||
" graceful restart initiated\n");
|
" graceful restart initiated\n");
|
||||||
break;
|
break;
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
pr_info("Hibernation request received\n");
|
||||||
|
icmsghdrp->status = hibernation_supported ?
|
||||||
|
HV_S_OK : HV_E_FAIL;
|
||||||
|
if (hibernation_supported)
|
||||||
|
work = &hibernate_context.work;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
icmsghdrp->status = HV_E_FAIL;
|
icmsghdrp->status = HV_E_FAIL;
|
||||||
pr_info("Shutdown request received -"
|
pr_info("Shutdown request received -"
|
||||||
|
|
Loading…
Reference in a new issue