aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/Kconfig7
-rw-r--r--drivers/xen/balloon.c3
-rw-r--r--drivers/xen/privcmd.c2
-rw-r--r--drivers/xen/tmem.c93
-rw-r--r--drivers/xen/xen-pciback/pci_stub.c4
-rw-r--r--drivers/xen/xen-selfballoon.c47
-rw-r--r--drivers/xen/xenbus/xenbus_client.c5
-rw-r--r--drivers/xen/xenbus/xenbus_comms.h1
-rw-r--r--drivers/xen/xenbus/xenbus_dev_backend.c21
-rw-r--r--drivers/xen/xenbus/xenbus_probe.c27
-rw-r--r--drivers/xen/xenbus/xenbus_probe.h7
-rw-r--r--drivers/xen/xenbus/xenbus_probe_frontend.c37
12 files changed, 126 insertions, 128 deletions
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index f03bf501527f..9e02d60a364b 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -19,11 +19,10 @@ config XEN_SELFBALLOONING
19 by the current usage of anonymous memory ("committed AS") and 19 by the current usage of anonymous memory ("committed AS") and
20 controlled by various sysfs-settable parameters. Configuring 20 controlled by various sysfs-settable parameters. Configuring
21 FRONTSWAP is highly recommended; if it is not configured, self- 21 FRONTSWAP is highly recommended; if it is not configured, self-
22 ballooning is disabled by default but can be enabled with the 22 ballooning is disabled by default. If FRONTSWAP is configured,
23 'selfballooning' kernel boot parameter. If FRONTSWAP is configured,
24 frontswap-selfshrinking is enabled by default but can be disabled 23 frontswap-selfshrinking is enabled by default but can be disabled
25 with the 'noselfshrink' kernel boot parameter; and self-ballooning 24 with the 'tmem.selfshrink=0' kernel boot parameter; and self-ballooning
26 is enabled by default but can be disabled with the 'noselfballooning' 25 is enabled by default but can be disabled with the 'tmem.selfballooning=0'
27 kernel boot parameter. Note that systems without a sufficiently 26 kernel boot parameter. Note that systems without a sufficiently
28 large swap device should not enable self-ballooning. 27 large swap device should not enable self-ballooning.
29 28
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index a56776dbe095..930fb6817901 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -407,7 +407,8 @@ static enum bp_state decrease_reservation(unsigned long nr_pages, gfp_t gfp)
407 nr_pages = ARRAY_SIZE(frame_list); 407 nr_pages = ARRAY_SIZE(frame_list);
408 408
409 for (i = 0; i < nr_pages; i++) { 409 for (i = 0; i < nr_pages; i++) {
410 if ((page = alloc_page(gfp)) == NULL) { 410 page = alloc_page(gfp);
411 if (page == NULL) {
411 nr_pages = i; 412 nr_pages = i;
412 state = BP_EAGAIN; 413 state = BP_EAGAIN;
413 break; 414 break;
diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c
index ca2b00e9d558..2cfc24d76fc5 100644
--- a/drivers/xen/privcmd.c
+++ b/drivers/xen/privcmd.c
@@ -504,7 +504,7 @@ static void privcmd_close(struct vm_area_struct *vma)
504 struct page **pages = vma->vm_private_data; 504 struct page **pages = vma->vm_private_data;
505 int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; 505 int numpgs = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
506 506
507 if (!xen_feature(XENFEAT_auto_translated_physmap || !numpgs || !pages)) 507 if (!xen_feature(XENFEAT_auto_translated_physmap) || !numpgs || !pages)
508 return; 508 return;
509 509
510 xen_unmap_domain_mfn_range(vma, numpgs, pages); 510 xen_unmap_domain_mfn_range(vma, numpgs, pages);
diff --git a/drivers/xen/tmem.c b/drivers/xen/tmem.c
index e3600be4e7fa..0f0493c63371 100644
--- a/drivers/xen/tmem.c
+++ b/drivers/xen/tmem.c
@@ -11,11 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/pagemap.h> 12#include <linux/pagemap.h>
13#include <linux/cleancache.h> 13#include <linux/cleancache.h>
14
15/* temporary ifdef until include/linux/frontswap.h is upstream */
16#ifdef CONFIG_FRONTSWAP
17#include <linux/frontswap.h> 14#include <linux/frontswap.h>
18#endif
19 15
20#include <xen/xen.h> 16#include <xen/xen.h>
21#include <xen/interface/xen.h> 17#include <xen/interface/xen.h>
@@ -24,6 +20,36 @@
24#include <asm/xen/hypervisor.h> 20#include <asm/xen/hypervisor.h>
25#include <xen/tmem.h> 21#include <xen/tmem.h>
26 22
23#ifndef CONFIG_XEN_TMEM_MODULE
24bool __read_mostly tmem_enabled = false;
25
26static int __init enable_tmem(char *s)
27{
28 tmem_enabled = true;
29 return 1;
30}
31__setup("tmem", enable_tmem);
32#endif
33
34#ifdef CONFIG_CLEANCACHE
35static bool cleancache __read_mostly = true;
36module_param(cleancache, bool, S_IRUGO);
37static bool selfballooning __read_mostly = true;
38module_param(selfballooning, bool, S_IRUGO);
39#endif /* CONFIG_CLEANCACHE */
40
41#ifdef CONFIG_FRONTSWAP
42static bool frontswap __read_mostly = true;
43module_param(frontswap, bool, S_IRUGO);
44#else /* CONFIG_FRONTSWAP */
45#define frontswap (0)
46#endif /* CONFIG_FRONTSWAP */
47
48#ifdef CONFIG_XEN_SELFBALLOONING
49static bool selfshrinking __read_mostly = true;
50module_param(selfshrinking, bool, S_IRUGO);
51#endif /* CONFIG_XEN_SELFBALLOONING */
52
27#define TMEM_CONTROL 0 53#define TMEM_CONTROL 0
28#define TMEM_NEW_POOL 1 54#define TMEM_NEW_POOL 1
29#define TMEM_DESTROY_POOL 2 55#define TMEM_DESTROY_POOL 2
@@ -129,16 +155,6 @@ static int xen_tmem_flush_object(u32 pool_id, struct tmem_oid oid)
129 return xen_tmem_op(TMEM_FLUSH_OBJECT, pool_id, oid, 0, 0, 0, 0, 0); 155 return xen_tmem_op(TMEM_FLUSH_OBJECT, pool_id, oid, 0, 0, 0, 0, 0);
130} 156}
131 157
132#ifndef CONFIG_XEN_TMEM_MODULE
133bool __read_mostly tmem_enabled = false;
134
135static int __init enable_tmem(char *s)
136{
137 tmem_enabled = true;
138 return 1;
139}
140__setup("tmem", enable_tmem);
141#endif
142 158
143#ifdef CONFIG_CLEANCACHE 159#ifdef CONFIG_CLEANCACHE
144static int xen_tmem_destroy_pool(u32 pool_id) 160static int xen_tmem_destroy_pool(u32 pool_id)
@@ -230,20 +246,6 @@ static int tmem_cleancache_init_shared_fs(char *uuid, size_t pagesize)
230 return xen_tmem_new_pool(shared_uuid, TMEM_POOL_SHARED, pagesize); 246 return xen_tmem_new_pool(shared_uuid, TMEM_POOL_SHARED, pagesize);
231} 247}
232 248
233static bool disable_cleancache __read_mostly;
234static bool disable_selfballooning __read_mostly;
235#ifdef CONFIG_XEN_TMEM_MODULE
236module_param(disable_cleancache, bool, S_IRUGO);
237module_param(disable_selfballooning, bool, S_IRUGO);
238#else
239static int __init no_cleancache(char *s)
240{
241 disable_cleancache = true;
242 return 1;
243}
244__setup("nocleancache", no_cleancache);
245#endif
246
247static struct cleancache_ops tmem_cleancache_ops = { 249static struct cleancache_ops tmem_cleancache_ops = {
248 .put_page = tmem_cleancache_put_page, 250 .put_page = tmem_cleancache_put_page,
249 .get_page = tmem_cleancache_get_page, 251 .get_page = tmem_cleancache_get_page,
@@ -361,20 +363,6 @@ static void tmem_frontswap_init(unsigned ignored)
361 xen_tmem_new_pool(private, TMEM_POOL_PERSIST, PAGE_SIZE); 363 xen_tmem_new_pool(private, TMEM_POOL_PERSIST, PAGE_SIZE);
362} 364}
363 365
364static bool disable_frontswap __read_mostly;
365static bool disable_frontswap_selfshrinking __read_mostly;
366#ifdef CONFIG_XEN_TMEM_MODULE
367module_param(disable_frontswap, bool, S_IRUGO);
368module_param(disable_frontswap_selfshrinking, bool, S_IRUGO);
369#else
370static int __init no_frontswap(char *s)
371{
372 disable_frontswap = true;
373 return 1;
374}
375__setup("nofrontswap", no_frontswap);
376#endif
377
378static struct frontswap_ops tmem_frontswap_ops = { 366static struct frontswap_ops tmem_frontswap_ops = {
379 .store = tmem_frontswap_store, 367 .store = tmem_frontswap_store,
380 .load = tmem_frontswap_load, 368 .load = tmem_frontswap_load,
@@ -382,8 +370,6 @@ static struct frontswap_ops tmem_frontswap_ops = {
382 .invalidate_area = tmem_frontswap_flush_area, 370 .invalidate_area = tmem_frontswap_flush_area,
383 .init = tmem_frontswap_init 371 .init = tmem_frontswap_init
384}; 372};
385#else /* CONFIG_FRONTSWAP */
386#define disable_frontswap_selfshrinking 1
387#endif 373#endif
388 374
389static int xen_tmem_init(void) 375static int xen_tmem_init(void)
@@ -391,12 +377,12 @@ static int xen_tmem_init(void)
391 if (!xen_domain()) 377 if (!xen_domain())
392 return 0; 378 return 0;
393#ifdef CONFIG_FRONTSWAP 379#ifdef CONFIG_FRONTSWAP
394 if (tmem_enabled && !disable_frontswap) { 380 if (tmem_enabled && frontswap) {
395 char *s = ""; 381 char *s = "";
396 struct frontswap_ops *old_ops = 382 struct frontswap_ops *old_ops;
397 frontswap_register_ops(&tmem_frontswap_ops);
398 383
399 tmem_frontswap_poolid = -1; 384 tmem_frontswap_poolid = -1;
385 old_ops = frontswap_register_ops(&tmem_frontswap_ops);
400 if (IS_ERR(old_ops) || old_ops) { 386 if (IS_ERR(old_ops) || old_ops) {
401 if (IS_ERR(old_ops)) 387 if (IS_ERR(old_ops))
402 return PTR_ERR(old_ops); 388 return PTR_ERR(old_ops);
@@ -408,7 +394,7 @@ static int xen_tmem_init(void)
408#endif 394#endif
409#ifdef CONFIG_CLEANCACHE 395#ifdef CONFIG_CLEANCACHE
410 BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid)); 396 BUG_ON(sizeof(struct cleancache_filekey) != sizeof(struct tmem_oid));
411 if (tmem_enabled && !disable_cleancache) { 397 if (tmem_enabled && cleancache) {
412 char *s = ""; 398 char *s = "";
413 struct cleancache_ops *old_ops = 399 struct cleancache_ops *old_ops =
414 cleancache_register_ops(&tmem_cleancache_ops); 400 cleancache_register_ops(&tmem_cleancache_ops);
@@ -419,8 +405,15 @@ static int xen_tmem_init(void)
419 } 405 }
420#endif 406#endif
421#ifdef CONFIG_XEN_SELFBALLOONING 407#ifdef CONFIG_XEN_SELFBALLOONING
422 xen_selfballoon_init(!disable_selfballooning, 408 /*
423 !disable_frontswap_selfshrinking); 409 * There is no point of driving pages to the swap system if they
410 * aren't going anywhere in tmem universe.
411 */
412 if (!frontswap) {
413 selfshrinking = false;
414 selfballooning = false;
415 }
416 xen_selfballoon_init(selfballooning, selfshrinking);
424#endif 417#endif
425 return 0; 418 return 0;
426} 419}
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c
index a2278ba7fb27..4e8ba38aa0c9 100644
--- a/drivers/xen/xen-pciback/pci_stub.c
+++ b/drivers/xen/xen-pciback/pci_stub.c
@@ -106,7 +106,7 @@ static void pcistub_device_release(struct kref *kref)
106 else 106 else
107 pci_restore_state(dev); 107 pci_restore_state(dev);
108 108
109 if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { 109 if (dev->msix_cap) {
110 struct physdev_pci_device ppdev = { 110 struct physdev_pci_device ppdev = {
111 .seg = pci_domain_nr(dev->bus), 111 .seg = pci_domain_nr(dev->bus),
112 .bus = dev->bus->number, 112 .bus = dev->bus->number,
@@ -371,7 +371,7 @@ static int pcistub_init_device(struct pci_dev *dev)
371 if (err) 371 if (err)
372 goto config_release; 372 goto config_release;
373 373
374 if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) { 374 if (dev->msix_cap) {
375 struct physdev_pci_device ppdev = { 375 struct physdev_pci_device ppdev = {
376 .seg = pci_domain_nr(dev->bus), 376 .seg = pci_domain_nr(dev->bus),
377 .bus = dev->bus->number, 377 .bus = dev->bus->number,
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c
index f2ef569c7cc1..f70984a892aa 100644
--- a/drivers/xen/xen-selfballoon.c
+++ b/drivers/xen/xen-selfballoon.c
@@ -53,15 +53,12 @@
53 * System configuration note: Selfballooning should not be enabled on 53 * System configuration note: Selfballooning should not be enabled on
54 * systems without a sufficiently large swap device configured; for best 54 * systems without a sufficiently large swap device configured; for best
55 * results, it is recommended that total swap be increased by the size 55 * results, it is recommended that total swap be increased by the size
56 * of the guest memory. Also, while technically not required to be 56 * of the guest memory. Note, that selfballooning should be disabled by default
57 * configured, it is highly recommended that frontswap also be configured 57 * if frontswap is not configured. Similarly selfballooning should be enabled
58 * and enabled when selfballooning is running. So, selfballooning 58 * by default if frontswap is configured and can be disabled with the
59 * is disabled by default if frontswap is not configured and can only 59 * "tmem.selfballooning=0" kernel boot option. Finally, when frontswap is
60 * be enabled with the "selfballooning" kernel boot option; similarly 60 * configured, frontswap-selfshrinking can be disabled with the
61 * selfballooning is enabled by default if frontswap is configured and 61 * "tmem.selfshrink=0" kernel boot option.
62 * can be disabled with the "noselfballooning" kernel boot option. Finally,
63 * when frontswap is configured, frontswap-selfshrinking can be disabled
64 * with the "noselfshrink" kernel boot option.
65 * 62 *
66 * Selfballooning is disallowed in domain0 and force-disabled. 63 * Selfballooning is disallowed in domain0 and force-disabled.
67 * 64 *
@@ -120,9 +117,6 @@ static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process);
120/* Enable/disable with sysfs. */ 117/* Enable/disable with sysfs. */
121static bool frontswap_selfshrinking __read_mostly; 118static bool frontswap_selfshrinking __read_mostly;
122 119
123/* Enable/disable with kernel boot option. */
124static bool use_frontswap_selfshrink = true;
125
126/* 120/*
127 * The default values for the following parameters were deemed reasonable 121 * The default values for the following parameters were deemed reasonable
128 * by experimentation, may be workload-dependent, and can all be 122 * by experimentation, may be workload-dependent, and can all be
@@ -176,35 +170,6 @@ static void frontswap_selfshrink(void)
176 frontswap_shrink(tgt_frontswap_pages); 170 frontswap_shrink(tgt_frontswap_pages);
177} 171}
178 172
179static int __init xen_nofrontswap_selfshrink_setup(char *s)
180{
181 use_frontswap_selfshrink = false;
182 return 1;
183}
184
185__setup("noselfshrink", xen_nofrontswap_selfshrink_setup);
186
187/* Disable with kernel boot option. */
188static bool use_selfballooning = true;
189
190static int __init xen_noselfballooning_setup(char *s)
191{
192 use_selfballooning = false;
193 return 1;
194}
195
196__setup("noselfballooning", xen_noselfballooning_setup);
197#else /* !CONFIG_FRONTSWAP */
198/* Enable with kernel boot option. */
199static bool use_selfballooning;
200
201static int __init xen_selfballooning_setup(char *s)
202{
203 use_selfballooning = true;
204 return 1;
205}
206
207__setup("selfballooning", xen_selfballooning_setup);
208#endif /* CONFIG_FRONTSWAP */ 173#endif /* CONFIG_FRONTSWAP */
209 174
210#define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) 175#define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 61786be9138b..ec097d6f964d 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -534,7 +534,7 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
534 534
535 err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr); 535 err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr);
536 if (err) 536 if (err)
537 goto out_err; 537 goto out_err_free_ballooned_pages;
538 538
539 spin_lock(&xenbus_valloc_lock); 539 spin_lock(&xenbus_valloc_lock);
540 list_add(&node->next, &xenbus_valloc_pages); 540 list_add(&node->next, &xenbus_valloc_pages);
@@ -543,8 +543,9 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
543 *vaddr = addr; 543 *vaddr = addr;
544 return 0; 544 return 0;
545 545
546 out_err: 546 out_err_free_ballooned_pages:
547 free_xenballooned_pages(1, &node->page); 547 free_xenballooned_pages(1, &node->page);
548 out_err:
548 kfree(node); 549 kfree(node);
549 return err; 550 return err;
550} 551}
diff --git a/drivers/xen/xenbus/xenbus_comms.h b/drivers/xen/xenbus/xenbus_comms.h
index c8abd3b8a6c4..e74f9c1fbd80 100644
--- a/drivers/xen/xenbus/xenbus_comms.h
+++ b/drivers/xen/xenbus/xenbus_comms.h
@@ -45,6 +45,7 @@ int xb_wait_for_data_to_read(void);
45int xs_input_avail(void); 45int xs_input_avail(void);
46extern struct xenstore_domain_interface *xen_store_interface; 46extern struct xenstore_domain_interface *xen_store_interface;
47extern int xen_store_evtchn; 47extern int xen_store_evtchn;
48extern enum xenstore_init xen_store_domain_type;
48 49
49extern const struct file_operations xen_xenbus_fops; 50extern const struct file_operations xen_xenbus_fops;
50 51
diff --git a/drivers/xen/xenbus/xenbus_dev_backend.c b/drivers/xen/xenbus/xenbus_dev_backend.c
index d73000800762..a6f42fc01407 100644
--- a/drivers/xen/xenbus/xenbus_dev_backend.c
+++ b/drivers/xen/xenbus/xenbus_dev_backend.c
@@ -70,22 +70,21 @@ static long xenbus_alloc(domid_t domid)
70 return err; 70 return err;
71} 71}
72 72
73static long xenbus_backend_ioctl(struct file *file, unsigned int cmd, unsigned long data) 73static long xenbus_backend_ioctl(struct file *file, unsigned int cmd,
74 unsigned long data)
74{ 75{
75 if (!capable(CAP_SYS_ADMIN)) 76 if (!capable(CAP_SYS_ADMIN))
76 return -EPERM; 77 return -EPERM;
77 78
78 switch (cmd) { 79 switch (cmd) {
79 case IOCTL_XENBUS_BACKEND_EVTCHN: 80 case IOCTL_XENBUS_BACKEND_EVTCHN:
80 if (xen_store_evtchn > 0) 81 if (xen_store_evtchn > 0)
81 return xen_store_evtchn; 82 return xen_store_evtchn;
82 return -ENODEV; 83 return -ENODEV;
83 84 case IOCTL_XENBUS_BACKEND_SETUP:
84 case IOCTL_XENBUS_BACKEND_SETUP: 85 return xenbus_alloc(data);
85 return xenbus_alloc(data); 86 default:
86 87 return -ENOTTY;
87 default:
88 return -ENOTTY;
89 } 88 }
90} 89}
91 90
diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c
index 3325884c693f..56cfaaa9d006 100644
--- a/drivers/xen/xenbus/xenbus_probe.c
+++ b/drivers/xen/xenbus/xenbus_probe.c
@@ -69,6 +69,9 @@ EXPORT_SYMBOL_GPL(xen_store_evtchn);
69struct xenstore_domain_interface *xen_store_interface; 69struct xenstore_domain_interface *xen_store_interface;
70EXPORT_SYMBOL_GPL(xen_store_interface); 70EXPORT_SYMBOL_GPL(xen_store_interface);
71 71
72enum xenstore_init xen_store_domain_type;
73EXPORT_SYMBOL_GPL(xen_store_domain_type);
74
72static unsigned long xen_store_mfn; 75static unsigned long xen_store_mfn;
73 76
74static BLOCKING_NOTIFIER_HEAD(xenstore_chain); 77static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
@@ -719,17 +722,11 @@ static int __init xenstored_local_init(void)
719 return err; 722 return err;
720} 723}
721 724
722enum xenstore_init {
723 UNKNOWN,
724 PV,
725 HVM,
726 LOCAL,
727};
728static int __init xenbus_init(void) 725static int __init xenbus_init(void)
729{ 726{
730 int err = 0; 727 int err = 0;
731 enum xenstore_init usage = UNKNOWN;
732 uint64_t v = 0; 728 uint64_t v = 0;
729 xen_store_domain_type = XS_UNKNOWN;
733 730
734 if (!xen_domain()) 731 if (!xen_domain())
735 return -ENODEV; 732 return -ENODEV;
@@ -737,29 +734,29 @@ static int __init xenbus_init(void)
737 xenbus_ring_ops_init(); 734 xenbus_ring_ops_init();
738 735
739 if (xen_pv_domain()) 736 if (xen_pv_domain())
740 usage = PV; 737 xen_store_domain_type = XS_PV;
741 if (xen_hvm_domain()) 738 if (xen_hvm_domain())
742 usage = HVM; 739 xen_store_domain_type = XS_HVM;
743 if (xen_hvm_domain() && xen_initial_domain()) 740 if (xen_hvm_domain() && xen_initial_domain())
744 usage = LOCAL; 741 xen_store_domain_type = XS_LOCAL;
745 if (xen_pv_domain() && !xen_start_info->store_evtchn) 742 if (xen_pv_domain() && !xen_start_info->store_evtchn)
746 usage = LOCAL; 743 xen_store_domain_type = XS_LOCAL;
747 if (xen_pv_domain() && xen_start_info->store_evtchn) 744 if (xen_pv_domain() && xen_start_info->store_evtchn)
748 xenstored_ready = 1; 745 xenstored_ready = 1;
749 746
750 switch (usage) { 747 switch (xen_store_domain_type) {
751 case LOCAL: 748 case XS_LOCAL:
752 err = xenstored_local_init(); 749 err = xenstored_local_init();
753 if (err) 750 if (err)
754 goto out_error; 751 goto out_error;
755 xen_store_interface = mfn_to_virt(xen_store_mfn); 752 xen_store_interface = mfn_to_virt(xen_store_mfn);
756 break; 753 break;
757 case PV: 754 case XS_PV:
758 xen_store_evtchn = xen_start_info->store_evtchn; 755 xen_store_evtchn = xen_start_info->store_evtchn;
759 xen_store_mfn = xen_start_info->store_mfn; 756 xen_store_mfn = xen_start_info->store_mfn;
760 xen_store_interface = mfn_to_virt(xen_store_mfn); 757 xen_store_interface = mfn_to_virt(xen_store_mfn);
761 break; 758 break;
762 case HVM: 759 case XS_HVM:
763 err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v); 760 err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
764 if (err) 761 if (err)
765 goto out_error; 762 goto out_error;
diff --git a/drivers/xen/xenbus/xenbus_probe.h b/drivers/xen/xenbus/xenbus_probe.h
index bb4f92ed8730..146f857a36f8 100644
--- a/drivers/xen/xenbus/xenbus_probe.h
+++ b/drivers/xen/xenbus/xenbus_probe.h
@@ -47,6 +47,13 @@ struct xen_bus_type {
47 struct bus_type bus; 47 struct bus_type bus;
48}; 48};
49 49
50enum xenstore_init {
51 XS_UNKNOWN,
52 XS_PV,
53 XS_HVM,
54 XS_LOCAL,
55};
56
50extern struct device_attribute xenbus_dev_attrs[]; 57extern struct device_attribute xenbus_dev_attrs[];
51 58
52extern int xenbus_match(struct device *_dev, struct device_driver *_drv); 59extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
diff --git a/drivers/xen/xenbus/xenbus_probe_frontend.c b/drivers/xen/xenbus/xenbus_probe_frontend.c
index 3159a37d966d..a7e25073de19 100644
--- a/drivers/xen/xenbus/xenbus_probe_frontend.c
+++ b/drivers/xen/xenbus/xenbus_probe_frontend.c
@@ -29,6 +29,8 @@
29#include "xenbus_probe.h" 29#include "xenbus_probe.h"
30 30
31 31
32static struct workqueue_struct *xenbus_frontend_wq;
33
32/* device/<type>/<id> => <type>-<id> */ 34/* device/<type>/<id> => <type>-<id> */
33static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename) 35static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename)
34{ 36{
@@ -89,9 +91,40 @@ static void backend_changed(struct xenbus_watch *watch,
89 xenbus_otherend_changed(watch, vec, len, 1); 91 xenbus_otherend_changed(watch, vec, len, 1);
90} 92}
91 93
94static void xenbus_frontend_delayed_resume(struct work_struct *w)
95{
96 struct xenbus_device *xdev = container_of(w, struct xenbus_device, work);
97
98 xenbus_dev_resume(&xdev->dev);
99}
100
101static int xenbus_frontend_dev_resume(struct device *dev)
102{
103 /*
104 * If xenstored is running in this domain, we cannot access the backend
105 * state at the moment, so we need to defer xenbus_dev_resume
106 */
107 if (xen_store_domain_type == XS_LOCAL) {
108 struct xenbus_device *xdev = to_xenbus_device(dev);
109
110 if (!xenbus_frontend_wq) {
111 pr_err("%s: no workqueue to process delayed resume\n",
112 xdev->nodename);
113 return -EFAULT;
114 }
115
116 INIT_WORK(&xdev->work, xenbus_frontend_delayed_resume);
117 queue_work(xenbus_frontend_wq, &xdev->work);
118
119 return 0;
120 }
121
122 return xenbus_dev_resume(dev);
123}
124
92static const struct dev_pm_ops xenbus_pm_ops = { 125static const struct dev_pm_ops xenbus_pm_ops = {
93 .suspend = xenbus_dev_suspend, 126 .suspend = xenbus_dev_suspend,
94 .resume = xenbus_dev_resume, 127 .resume = xenbus_frontend_dev_resume,
95 .freeze = xenbus_dev_suspend, 128 .freeze = xenbus_dev_suspend,
96 .thaw = xenbus_dev_cancel, 129 .thaw = xenbus_dev_cancel,
97 .restore = xenbus_dev_resume, 130 .restore = xenbus_dev_resume,
@@ -440,6 +473,8 @@ static int __init xenbus_probe_frontend_init(void)
440 473
441 register_xenstore_notifier(&xenstore_notifier); 474 register_xenstore_notifier(&xenstore_notifier);
442 475
476 xenbus_frontend_wq = create_workqueue("xenbus_frontend");
477
443 return 0; 478 return 0;
444} 479}
445subsys_initcall(xenbus_probe_frontend_init); 480subsys_initcall(xenbus_probe_frontend_init);