Skip to content

Commit 3e9c720

Browse files
dcuiSasha Levin
authored andcommitted
hv_utils: Support host-initiated restart request
The hv_utils driver currently supports a "shutdown" operation initiated from the Hyper-V host. Newer versions of Hyper-V also support a "restart" operation. So add support for the updated protocol version that has "restart" support, and perform a clean reboot when such a message is received from Hyper-V. To test the restart functionality, run this PowerShell command on the Hyper-V host: Restart-VM <vmname> -Type Reboot Signed-off-by: Dexuan Cui <[email protected]> Reviewed-by: Michael Kelley <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 9fc3c01 commit 3e9c720

File tree

1 file changed

+31
-8
lines changed

1 file changed

+31
-8
lines changed

drivers/hv/hv_util.c

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424

2525
#define SD_MAJOR 3
2626
#define SD_MINOR 0
27+
#define SD_MINOR_1 1
28+
#define SD_VERSION_3_1 (SD_MAJOR << 16 | SD_MINOR_1)
2729
#define SD_VERSION (SD_MAJOR << 16 | SD_MINOR)
2830

2931
#define SD_MAJOR_1 1
@@ -50,8 +52,9 @@ static int sd_srv_version;
5052
static int ts_srv_version;
5153
static int hb_srv_version;
5254

53-
#define SD_VER_COUNT 2
55+
#define SD_VER_COUNT 3
5456
static const int sd_versions[] = {
57+
SD_VERSION_3_1,
5558
SD_VERSION,
5659
SD_VERSION_1
5760
};
@@ -118,17 +121,27 @@ static void perform_shutdown(struct work_struct *dummy)
118121
orderly_poweroff(true);
119122
}
120123

124+
static void perform_restart(struct work_struct *dummy)
125+
{
126+
orderly_reboot();
127+
}
128+
121129
/*
122130
* Perform the shutdown operation in a thread context.
123131
*/
124132
static DECLARE_WORK(shutdown_work, perform_shutdown);
125133

134+
/*
135+
* Perform the restart operation in a thread context.
136+
*/
137+
static DECLARE_WORK(restart_work, perform_restart);
138+
126139
static void shutdown_onchannelcallback(void *context)
127140
{
128141
struct vmbus_channel *channel = context;
142+
struct work_struct *work = NULL;
129143
u32 recvlen;
130144
u64 requestid;
131-
bool execute_shutdown = false;
132145
u8 *shut_txf_buf = util_shutdown.recv_buffer;
133146

134147
struct shutdown_msg_data *shutdown_msg;
@@ -157,19 +170,29 @@ static void shutdown_onchannelcallback(void *context)
157170
sizeof(struct vmbuspipe_hdr) +
158171
sizeof(struct icmsg_hdr)];
159172

173+
/*
174+
* shutdown_msg->flags can be 0(shut down), 2(reboot),
175+
* or 4(hibernate). It may bitwise-OR 1, which means
176+
* performing the request by force. Linux always tries
177+
* to perform the request by force.
178+
*/
160179
switch (shutdown_msg->flags) {
161180
case 0:
162181
case 1:
163182
icmsghdrp->status = HV_S_OK;
164-
execute_shutdown = true;
165-
183+
work = &shutdown_work;
166184
pr_info("Shutdown request received -"
167185
" graceful shutdown initiated\n");
168186
break;
187+
case 2:
188+
case 3:
189+
icmsghdrp->status = HV_S_OK;
190+
work = &restart_work;
191+
pr_info("Restart request received -"
192+
" graceful restart initiated\n");
193+
break;
169194
default:
170195
icmsghdrp->status = HV_E_FAIL;
171-
execute_shutdown = false;
172-
173196
pr_info("Shutdown request received -"
174197
" Invalid request\n");
175198
break;
@@ -184,8 +207,8 @@ static void shutdown_onchannelcallback(void *context)
184207
VM_PKT_DATA_INBAND, 0);
185208
}
186209

187-
if (execute_shutdown == true)
188-
schedule_work(&shutdown_work);
210+
if (work)
211+
schedule_work(work);
189212
}
190213

191214
/*

0 commit comments

Comments
 (0)