Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F150790301
D7744.id19932.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D7744.id19932.diff
View Options
Index: sys/dev/hyperv/utilities/hv_shutdown.c
===================================================================
--- sys/dev/hyperv/utilities/hv_shutdown.c
+++ sys/dev/hyperv/utilities/hv_shutdown.c
@@ -22,28 +22,23 @@
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD$
*/
-/*
- * A common driver for all hyper-V util services.
- */
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
#include <sys/param.h>
-#include <sys/kernel.h>
#include <sys/bus.h>
-#include <sys/malloc.h>
+#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/reboot.h>
-#include <sys/timetc.h>
-#include <sys/syscallsubr.h>
#include <sys/systm.h>
#include <dev/hyperv/include/hyperv.h>
#include <dev/hyperv/include/vmbus.h>
-#include <dev/hyperv/utilities/hv_utilreg.h>
-#include "hv_util.h"
+#include <dev/hyperv/utilities/hv_util.h>
+#include <dev/hyperv/utilities/vmbus_icreg.h>
+
#include "vmbus_if.h"
static const struct vmbus_ic_desc vmbus_shutdown_descs[] = {
@@ -56,73 +51,78 @@
VMBUS_IC_DESC_END
};
-/**
- * Shutdown
- */
static void
-hv_shutdown_cb(struct vmbus_channel *channel, void *context)
+vmbus_shutdown_cb(struct vmbus_channel *chan, void *xsc)
{
- uint8_t* buf;
- uint8_t execute_shutdown = 0;
- hv_vmbus_icmsg_hdr* icmsghdrp;
- uint32_t recv_len;
- uint64_t request_id;
- int ret;
- hv_vmbus_shutdown_msg_data* shutdown_msg;
- hv_util_sc *softc;
-
- softc = (hv_util_sc*)context;
- buf = softc->receive_buffer;
-
- recv_len = softc->ic_buflen;
- ret = vmbus_chan_recv(channel, buf, &recv_len, &request_id);
- KASSERT(ret != ENOBUFS, ("hvshutdown recvbuf is not large enough"));
- /* XXX check recv_len to make sure that it contains enough data */
-
- if ((ret == 0) && recv_len > 0) {
-
- icmsghdrp = (struct hv_vmbus_icmsg_hdr *)
- &buf[sizeof(struct hv_vmbus_pipe_hdr)];
-
- if (icmsghdrp->icmsgtype == HV_ICMSGTYPE_NEGOTIATE) {
- int error;
-
- error = vmbus_ic_negomsg(softc, buf, &recv_len);
+ struct hv_util_sc *sc = xsc;
+ struct vmbus_icmsg_hdr *hdr;
+ struct vmbus_icmsg_shutdown *msg;
+ int dlen, error, do_shutdown = 0;
+ uint64_t xactid;
+ void *data;
+
+ /*
+ * Receive request.
+ */
+ data = sc->receive_buffer;
+ dlen = sc->ic_buflen;
+ error = vmbus_chan_recv(chan, data, &dlen, &xactid);
+ KASSERT(error != ENOBUFS, ("icbuf is not large enough"));
+ if (error)
+ return;
+
+ if (dlen < sizeof(*hdr)) {
+ device_printf(sc->ic_dev, "invalid data len %d\n", dlen);
+ return;
+ }
+ hdr = data;
+
+ /*
+ * Update request, which will be echoed back as response.
+ */
+ switch (hdr->ic_type) {
+ case VMBUS_ICMSG_TYPE_NEGOTIATE:
+ error = vmbus_ic_negomsg(sc, data, &dlen);
if (error)
return;
- } else {
- shutdown_msg =
- (struct hv_vmbus_shutdown_msg_data *)
- &buf[sizeof(struct hv_vmbus_pipe_hdr) +
- sizeof(struct hv_vmbus_icmsg_hdr)];
-
- switch (shutdown_msg->flags) {
- case 0:
- case 1:
- icmsghdrp->status = HV_S_OK;
- execute_shutdown = 1;
- if(bootverbose)
- printf("Shutdown request received -"
- " graceful shutdown initiated\n");
- break;
- default:
- icmsghdrp->status = HV_E_FAIL;
- execute_shutdown = 0;
- printf("Shutdown request received -"
- " Invalid request\n");
- break;
- }
- }
-
- icmsghdrp->icflags = HV_ICMSGHDRFLAG_TRANSACTION |
- HV_ICMSGHDRFLAG_RESPONSE;
-
- vmbus_chan_send(channel, VMBUS_CHANPKT_TYPE_INBAND, 0,
- buf, recv_len, request_id);
+ break;
+
+ case VMBUS_ICMSG_TYPE_SHUTDOWN:
+ if (dlen < VMBUS_ICMSG_SHUTDOWN_SIZE_MIN) {
+ device_printf(sc->ic_dev, "invalid shutdown len %d\n",
+ dlen);
+ return;
+ }
+ msg = data;
+
+ /* XXX ic_flags definition? */
+ if (msg->ic_haltflags == 0 || msg->ic_haltflags == 1) {
+ device_printf(sc->ic_dev, "shutdown requested\n");
+ hdr->ic_status = VMBUS_ICMSG_STATUS_OK;
+ do_shutdown = 1;
+ } else {
+ device_printf(sc->ic_dev, "unknown shutdown flags "
+ "0x%08x\n", msg->ic_haltflags);
+ hdr->ic_status = VMBUS_ICMSG_STATUS_FAIL;
+ }
+ break;
+
+ default:
+ device_printf(sc->ic_dev, "got 0x%08x icmsg\n", hdr->ic_type);
+ break;
}
- if (execute_shutdown)
- shutdown_nice(RB_POWEROFF);
+ /*
+ * Send response by echoing the updated request back.
+ */
+ hdr->ic_flags = VMBUS_ICMSG_FLAG_XACT | VMBUS_ICMSG_FLAG_RESP;
+ error = vmbus_chan_send(chan, VMBUS_CHANPKT_TYPE_INBAND, 0,
+ data, dlen, xactid);
+ if (error)
+ device_printf(sc->ic_dev, "resp send failed: %d\n", error);
+
+ if (do_shutdown)
+ shutdown_nice(RB_POWEROFF);
}
static int
@@ -135,7 +135,8 @@
static int
hv_shutdown_attach(device_t dev)
{
- return hv_util_attach(dev, hv_shutdown_cb);
+
+ return (hv_util_attach(dev, vmbus_shutdown_cb));
}
static device_method_t shutdown_methods[] = {
Index: sys/dev/hyperv/utilities/vmbus_icreg.h
===================================================================
--- sys/dev/hyperv/utilities/vmbus_icreg.h
+++ sys/dev/hyperv/utilities/vmbus_icreg.h
@@ -91,4 +91,15 @@
#define VMBUS_ICMSG_HEARTBEAT_SIZE_MIN \
__offsetof(struct vmbus_icmsg_heartbeat, ic_rsvd[0])
+struct vmbus_icmsg_shutdown {
+ struct vmbus_icmsg_hdr ic_hdr;
+ uint32_t ic_code;
+ uint32_t ic_timeo;
+ uint32_t ic_haltflags;
+ uint8_t ic_msg[2048];
+} __packed;
+
+#define VMBUS_ICMSG_SHUTDOWN_SIZE_MIN \
+ __offsetof(struct vmbus_icmsg_shutdown, ic_msg[0])
+
#endif /* !_VMBUS_ICREG_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Apr 5, 2:02 AM (15 h, 49 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30861043
Default Alt Text
D7744.id19932.diff (5 KB)
Attached To
Mode
D7744: hyperv/ic: Cleanup shutdown channel callback.
Attached
Detach File
Event Timeline
Log In to Comment