return rc;
}
+static int shutdown_remote(xendevicemodel_handle *dm, int reason,
+ const char *what)
+{
+ int ret = -1;
+ sched_remote_shutdown_t *arg;
+
+ arg = xencall_alloc_buffer(dm->call, sizeof(*arg));
+ if ( arg == NULL )
+ {
+ LOGE(ERROR, "unable to allocate memory for %s hypercall", what);
+ goto err;
+ }
+
+ arg->domain_id = dm->domid;
+ arg->reason = reason;
+ ret = xencall2(dm->call, __HYPERVISOR_sched_op,
+ SCHEDOP_remote_shutdown,
+ (uintptr_t)arg);
+
+ if ( ret )
+ LOGE(ERROR, "%s hypercall failed", what);
+
+ xencall_free_buffer(dm->call, arg);
+
+ err:
+ return ret;
+}
+
+int xendevicemodel_shutdown(xendevicemodel_handle *dm)
+{
+ return shutdown_remote(dm, SHUTDOWN_poweroff, "shutdown");
+}
+
+int xendevicemodel_reboot(xendevicemodel_handle *dm)
+{
+ return shutdown_remote(dm, SHUTDOWN_reboot, "reboot");
+}
+
+static int set_s3_state(xendevicemodel_handle *dm, int state,
+ const char *what)
+{
+ xen_hvm_param_t *arg;
+ int ret = -1;
+
+ arg = xencall_alloc_buffer(dm->call, sizeof(*arg));
+ if ( arg == NULL )
+ {
+ LOGE(ERROR, "unable to allocate memory for %s hypercall", what);
+ goto err;
+ }
+
+ arg->domid = dm->domid;
+ arg->index = HVM_PARAM_ACPI_S_STATE;
+ arg->value = state;
+
+ ret = xencall2(dm->call, __HYPERVISOR_hvm_op,
+ HVMOP_set_param, (uintptr_t)arg);
+
+ if ( ret )
+ LOGE(ERROR, "%s hypercall failed", what);
+
+ xencall_free_buffer(dm->call, arg);
+
+ err:
+ return ret;
+}
+
+int xendevicemodel_s3_suspend(xendevicemodel_handle *dm)
+{
+ return set_s3_state(dm, 3, "s3 suspend");
+}
+
+int xendevicemodel_s3_awaken(xendevicemodel_handle *dm)
+{
+ return set_s3_state(dm, 0, "s3 awaken");
+}
+
+
/*
* Local variables:
* mode: C
*/
int xendevicemodel_close(xendevicemodel_handle *dm);
+/*
+ * Indicate domain lifecycle changes to the hypervisor.
+ *
+ * shutdown, reboot and s3_suspend indicate to the hypervisor that
+ * emulation has resulted in the given guest behaviour.
+ *
+ * s3_awaken indicates that some event has woken the guest from S3.
+ *
+ * All functions log on failure.
+ */
+int xendevicemodel_shutdown(xendevicemodel_handle *dm);
+int xendevicemodel_reboot(xendevicemodel_handle *dm);
+int xendevicemodel_s3_suspend(xendevicemodel_handle *dm);
+int xendevicemodel_s3_awaken(xendevicemodel_handle *dm);
+
#endif
/*
* Local variables: