summaryrefslogtreecommitdiff
path: root/sys/xen
diff options
context:
space:
mode:
authorRoger Pau Monné <royger@FreeBSD.org>2017-03-07 09:16:51 +0000
committerRoger Pau Monné <royger@FreeBSD.org>2017-03-07 09:16:51 +0000
commit8dee0e9bd64849deca80da9052c806e764ef026c (patch)
tree8a90eb2b376d4cfc1722f58a22b0ec4bf0f7b581 /sys/xen
parentacd63c37d6702be2ca95b55e5d62baff86c97f71 (diff)
downloadsrc-test2-8dee0e9bd64849deca80da9052c806e764ef026c.tar.gz
src-test2-8dee0e9bd64849deca80da9052c806e764ef026c.zip
xen: add support for canceled suspend
When running on Xen, it's possible that a suspend request to the hypervisor fails (return from HYPERVISOR_suspend different than 0). This means that the suspend hasn't succeed, and the resume procedure needs to properly handle this case. First of all, when such situation happens there's no need to reset the vector callback, hypercall page, shared info, event channels or grant table, because it's state is preserved. Also, the PV drivers don't need to be reset to the initial state, since the connection with the backed has not been interrupted. Submitted by: Liuyingdong <liuyingdong@huawei.com> Reviewed by: royger MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D9635
Notes
Notes: svn path=/head/; revision=314840
Diffstat (limited to 'sys/xen')
-rw-r--r--sys/xen/xen-os.h2
-rw-r--r--sys/xen/xenbus/xenbusb.c5
2 files changed, 7 insertions, 0 deletions
diff --git a/sys/xen/xen-os.h b/sys/xen/xen-os.h
index 96e084fe6013..044433ae3d36 100644
--- a/sys/xen/xen-os.h
+++ b/sys/xen/xen-os.h
@@ -56,6 +56,8 @@ extern char *console_page;
extern int xen_disable_pv_disks;
extern int xen_disable_pv_nics;
+extern bool xen_suspend_cancelled;
+
enum xen_domain_type {
XEN_NATIVE, /* running on bare hardware */
XEN_PV_DOMAIN, /* running in a PV domain */
diff --git a/sys/xen/xenbus/xenbusb.c b/sys/xen/xenbus/xenbusb.c
index 3a0e54353cbe..8b755e2a62c3 100644
--- a/sys/xen/xenbus/xenbusb.c
+++ b/sys/xen/xenbus/xenbusb.c
@@ -791,6 +791,11 @@ xenbusb_resume(device_t dev)
if (device_get_state(kids[i]) == DS_NOTPRESENT)
continue;
+ if (xen_suspend_cancelled) {
+ DEVICE_RESUME(kids[i]);
+ continue;
+ }
+
ivars = device_get_ivars(kids[i]);
xs_unregister_watch(&ivars->xd_otherend_watch);