Skip to content

Commit ffd1d4a

Browse files
dcuiSasha Levin
authored andcommitted
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 <[email protected]> Reviewed-by: Michael Kelley <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 3e9c720 commit ffd1d4a

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

drivers/hv/hv_util.c

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@
2525
#define SD_MAJOR 3
2626
#define SD_MINOR 0
2727
#define SD_MINOR_1 1
28+
#define SD_MINOR_2 2
2829
#define SD_VERSION_3_1 (SD_MAJOR << 16 | SD_MINOR_1)
30+
#define SD_VERSION_3_2 (SD_MAJOR << 16 | SD_MINOR_2)
2931
#define SD_VERSION (SD_MAJOR << 16 | SD_MINOR)
3032

3133
#define SD_MAJOR_1 1
@@ -52,8 +54,9 @@ static int sd_srv_version;
5254
static int ts_srv_version;
5355
static int hb_srv_version;
5456

55-
#define SD_VER_COUNT 3
57+
#define SD_VER_COUNT 4
5658
static const int sd_versions[] = {
59+
SD_VERSION_3_2,
5760
SD_VERSION_3_1,
5861
SD_VERSION,
5962
SD_VERSION_1
@@ -78,9 +81,45 @@ static const int fw_versions[] = {
7881
UTIL_WS2K8_FW_VERSION
7982
};
8083

84+
/*
85+
* Send the "hibernate" udev event in a thread context.
86+
*/
87+
struct hibernate_work_context {
88+
struct work_struct work;
89+
struct hv_device *dev;
90+
};
91+
92+
static struct hibernate_work_context hibernate_context;
93+
static bool hibernation_supported;
94+
95+
static void send_hibernate_uevent(struct work_struct *work)
96+
{
97+
char *uevent_env[2] = { "EVENT=hibernate", NULL };
98+
struct hibernate_work_context *ctx;
99+
100+
ctx = container_of(work, struct hibernate_work_context, work);
101+
102+
kobject_uevent_env(&ctx->dev->device.kobj, KOBJ_CHANGE, uevent_env);
103+
104+
pr_info("Sent hibernation uevent\n");
105+
}
106+
107+
static int hv_shutdown_init(struct hv_util_service *srv)
108+
{
109+
struct vmbus_channel *channel = srv->channel;
110+
111+
INIT_WORK(&hibernate_context.work, send_hibernate_uevent);
112+
hibernate_context.dev = channel->device_obj;
113+
114+
hibernation_supported = hv_is_hibernation_supported();
115+
116+
return 0;
117+
}
118+
81119
static void shutdown_onchannelcallback(void *context);
82120
static struct hv_util_service util_shutdown = {
83121
.util_cb = shutdown_onchannelcallback,
122+
.util_init = hv_shutdown_init,
84123
};
85124

86125
static int hv_timesync_init(struct hv_util_service *srv);
@@ -191,6 +230,14 @@ static void shutdown_onchannelcallback(void *context)
191230
pr_info("Restart request received -"
192231
" graceful restart initiated\n");
193232
break;
233+
case 4:
234+
case 5:
235+
pr_info("Hibernation request received\n");
236+
icmsghdrp->status = hibernation_supported ?
237+
HV_S_OK : HV_E_FAIL;
238+
if (hibernation_supported)
239+
work = &hibernate_context.work;
240+
break;
194241
default:
195242
icmsghdrp->status = HV_E_FAIL;
196243
pr_info("Shutdown request received -"

0 commit comments

Comments
 (0)