diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 11:24:12 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-06-02 11:24:12 -0400 |
commit | 9f888b3a10782de27864659d4ab48eb6ef2c0bf3 (patch) | |
tree | 1331567fbf6de97bbbb62850b0f332a3ca3db2b5 /drivers/xen | |
parent | 5d70dacd4e7c3ef596ae03a933481a3f6805c7a6 (diff) | |
parent | 77945ca73e9a66cae25882fcab33ae0c6692763f (diff) |
Merge tag 'stable/for-linus-3.16-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip into next
Pull Xen updates from David Vrabel:
"xen: features and fixes for 3.16-rc0
- support foreign mappings in PVH domains (needed when dom0 is PVH)
- fix mapping high MMIO regions in x86 PV guests (this is also the
first half of removing the PAGE_IOMAP PTE flag).
- ARM suspend/resume support.
- ARM multicall support"
* tag 'stable/for-linus-3.16-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip:
x86/xen: map foreign pfns for autotranslated guests
xen-acpi-processor: Don't display errors when we get -ENOSYS
xen/pciback: Document the entry points for 'pcistub_put_pci_dev'
xen/pciback: Document when the 'unbind' and 'bind' functions are called.
xen-pciback: Document when we FLR an PCI device.
xen-pciback: First reset, then free.
xen-pciback: Cleanup up pcistub_put_pci_dev
x86/xen: do not use _PAGE_IOMAP in xen_remap_domain_mfn_range()
x86/xen: set regions above the end of RAM as 1:1
x86/xen: only warn once if bad MFNs are found during setup
x86/xen: compactly store large identity ranges in the p2m
x86/xen: fix set_phys_range_identity() if pfn_e > MAX_P2M_PFN
x86/xen: rename early_p2m_alloc() and early_p2m_alloc_middle()
xen/x86: set panic notifier priority to minimum
arm,arm64/xen: introduce HYPERVISOR_suspend()
xen: refactor suspend pre/post hooks
arm: xen: export HYPERVISOR_multicall to modules.
arm64: introduce virt_to_pfn
arm/xen: Remove definiition of virt_to_pfn in asm/xen/page.h
arm: xen: implement multicall hypercall support.
Diffstat (limited to 'drivers/xen')
-rw-r--r-- | drivers/xen/manage.c | 45 | ||||
-rw-r--r-- | drivers/xen/xen-acpi-processor.c | 4 | ||||
-rw-r--r-- | drivers/xen/xen-pciback/pci_stub.c | 25 | ||||
-rw-r--r-- | drivers/xen/xen-pciback/xenbus.c | 4 |
4 files changed, 33 insertions, 45 deletions
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c index 32f9236c959f..c3667b202f2f 100644 --- a/drivers/xen/manage.c +++ b/drivers/xen/manage.c | |||
@@ -41,9 +41,6 @@ static enum shutdown_state shutting_down = SHUTDOWN_INVALID; | |||
41 | 41 | ||
42 | struct suspend_info { | 42 | struct suspend_info { |
43 | int cancelled; | 43 | int cancelled; |
44 | unsigned long arg; /* extra hypercall argument */ | ||
45 | void (*pre)(void); | ||
46 | void (*post)(int cancelled); | ||
47 | }; | 44 | }; |
48 | 45 | ||
49 | static RAW_NOTIFIER_HEAD(xen_resume_notifier); | 46 | static RAW_NOTIFIER_HEAD(xen_resume_notifier); |
@@ -61,26 +58,6 @@ void xen_resume_notifier_unregister(struct notifier_block *nb) | |||
61 | EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister); | 58 | EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister); |
62 | 59 | ||
63 | #ifdef CONFIG_HIBERNATE_CALLBACKS | 60 | #ifdef CONFIG_HIBERNATE_CALLBACKS |
64 | static void xen_hvm_post_suspend(int cancelled) | ||
65 | { | ||
66 | xen_arch_hvm_post_suspend(cancelled); | ||
67 | gnttab_resume(); | ||
68 | } | ||
69 | |||
70 | static void xen_pre_suspend(void) | ||
71 | { | ||
72 | xen_mm_pin_all(); | ||
73 | gnttab_suspend(); | ||
74 | xen_arch_pre_suspend(); | ||
75 | } | ||
76 | |||
77 | static void xen_post_suspend(int cancelled) | ||
78 | { | ||
79 | xen_arch_post_suspend(cancelled); | ||
80 | gnttab_resume(); | ||
81 | xen_mm_unpin_all(); | ||
82 | } | ||
83 | |||
84 | static int xen_suspend(void *data) | 61 | static int xen_suspend(void *data) |
85 | { | 62 | { |
86 | struct suspend_info *si = data; | 63 | struct suspend_info *si = data; |
@@ -94,18 +71,20 @@ static int xen_suspend(void *data) | |||
94 | return err; | 71 | return err; |
95 | } | 72 | } |
96 | 73 | ||
97 | if (si->pre) | 74 | gnttab_suspend(); |
98 | si->pre(); | 75 | xen_arch_pre_suspend(); |
99 | 76 | ||
100 | /* | 77 | /* |
101 | * This hypercall returns 1 if suspend was cancelled | 78 | * This hypercall returns 1 if suspend was cancelled |
102 | * or the domain was merely checkpointed, and 0 if it | 79 | * or the domain was merely checkpointed, and 0 if it |
103 | * is resuming in a new domain. | 80 | * is resuming in a new domain. |
104 | */ | 81 | */ |
105 | si->cancelled = HYPERVISOR_suspend(si->arg); | 82 | si->cancelled = HYPERVISOR_suspend(xen_pv_domain() |
83 | ? virt_to_mfn(xen_start_info) | ||
84 | : 0); | ||
106 | 85 | ||
107 | if (si->post) | 86 | xen_arch_post_suspend(si->cancelled); |
108 | si->post(si->cancelled); | 87 | gnttab_resume(); |
109 | 88 | ||
110 | if (!si->cancelled) { | 89 | if (!si->cancelled) { |
111 | xen_irq_resume(); | 90 | xen_irq_resume(); |
@@ -154,16 +133,6 @@ static void do_suspend(void) | |||
154 | 133 | ||
155 | si.cancelled = 1; | 134 | si.cancelled = 1; |
156 | 135 | ||
157 | if (xen_hvm_domain()) { | ||
158 | si.arg = 0UL; | ||
159 | si.pre = NULL; | ||
160 | si.post = &xen_hvm_post_suspend; | ||
161 | } else { | ||
162 | si.arg = virt_to_mfn(xen_start_info); | ||
163 | si.pre = &xen_pre_suspend; | ||
164 | si.post = &xen_post_suspend; | ||
165 | } | ||
166 | |||
167 | err = stop_machine(xen_suspend, &si, cpumask_of(0)); | 136 | err = stop_machine(xen_suspend, &si, cpumask_of(0)); |
168 | 137 | ||
169 | raw_notifier_call_chain(&xen_resume_notifier, 0, NULL); | 138 | raw_notifier_call_chain(&xen_resume_notifier, 0, NULL); |
diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c index 82358d14ecf1..59fc190f1e92 100644 --- a/drivers/xen/xen-acpi-processor.c +++ b/drivers/xen/xen-acpi-processor.c | |||
@@ -127,7 +127,7 @@ static int push_cxx_to_hypervisor(struct acpi_processor *_pr) | |||
127 | pr_debug(" C%d: %s %d uS\n", | 127 | pr_debug(" C%d: %s %d uS\n", |
128 | cx->type, cx->desc, (u32)cx->latency); | 128 | cx->type, cx->desc, (u32)cx->latency); |
129 | } | 129 | } |
130 | } else if (ret != -EINVAL) | 130 | } else if ((ret != -EINVAL) && (ret != -ENOSYS)) |
131 | /* EINVAL means the ACPI ID is incorrect - meaning the ACPI | 131 | /* EINVAL means the ACPI ID is incorrect - meaning the ACPI |
132 | * table is referencing a non-existing CPU - which can happen | 132 | * table is referencing a non-existing CPU - which can happen |
133 | * with broken ACPI tables. */ | 133 | * with broken ACPI tables. */ |
@@ -259,7 +259,7 @@ static int push_pxx_to_hypervisor(struct acpi_processor *_pr) | |||
259 | (u32) perf->states[i].power, | 259 | (u32) perf->states[i].power, |
260 | (u32) perf->states[i].transition_latency); | 260 | (u32) perf->states[i].transition_latency); |
261 | } | 261 | } |
262 | } else if (ret != -EINVAL) | 262 | } else if ((ret != -EINVAL) && (ret != -ENOSYS)) |
263 | /* EINVAL means the ACPI ID is incorrect - meaning the ACPI | 263 | /* EINVAL means the ACPI ID is incorrect - meaning the ACPI |
264 | * table is referencing a non-existing CPU - which can happen | 264 | * table is referencing a non-existing CPU - which can happen |
265 | * with broken ACPI tables. */ | 265 | * with broken ACPI tables. */ |
diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 62fcd485f0a7..d57a173685f3 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c | |||
@@ -242,6 +242,15 @@ struct pci_dev *pcistub_get_pci_dev(struct xen_pcibk_device *pdev, | |||
242 | return found_dev; | 242 | return found_dev; |
243 | } | 243 | } |
244 | 244 | ||
245 | /* | ||
246 | * Called when: | ||
247 | * - XenBus state has been reconfigure (pci unplug). See xen_pcibk_remove_device | ||
248 | * - XenBus state has been disconnected (guest shutdown). See xen_pcibk_xenbus_remove | ||
249 | * - 'echo BDF > unbind' on pciback module with no guest attached. See pcistub_remove | ||
250 | * - 'echo BDF > unbind' with a guest still using it. See pcistub_remove | ||
251 | * | ||
252 | * As such we have to be careful. | ||
253 | */ | ||
245 | void pcistub_put_pci_dev(struct pci_dev *dev) | 254 | void pcistub_put_pci_dev(struct pci_dev *dev) |
246 | { | 255 | { |
247 | struct pcistub_device *psdev, *found_psdev = NULL; | 256 | struct pcistub_device *psdev, *found_psdev = NULL; |
@@ -272,16 +281,16 @@ void pcistub_put_pci_dev(struct pci_dev *dev) | |||
272 | * and want to inhibit the user from fiddling with 'reset' | 281 | * and want to inhibit the user from fiddling with 'reset' |
273 | */ | 282 | */ |
274 | pci_reset_function(dev); | 283 | pci_reset_function(dev); |
275 | pci_restore_state(psdev->dev); | 284 | pci_restore_state(dev); |
276 | 285 | ||
277 | /* This disables the device. */ | 286 | /* This disables the device. */ |
278 | xen_pcibk_reset_device(found_psdev->dev); | 287 | xen_pcibk_reset_device(dev); |
279 | 288 | ||
280 | /* And cleanup up our emulated fields. */ | 289 | /* And cleanup up our emulated fields. */ |
281 | xen_pcibk_config_free_dyn_fields(found_psdev->dev); | 290 | xen_pcibk_config_reset_dev(dev); |
282 | xen_pcibk_config_reset_dev(found_psdev->dev); | 291 | xen_pcibk_config_free_dyn_fields(dev); |
283 | 292 | ||
284 | xen_unregister_device_domain_owner(found_psdev->dev); | 293 | xen_unregister_device_domain_owner(dev); |
285 | 294 | ||
286 | spin_lock_irqsave(&found_psdev->lock, flags); | 295 | spin_lock_irqsave(&found_psdev->lock, flags); |
287 | found_psdev->pdev = NULL; | 296 | found_psdev->pdev = NULL; |
@@ -493,6 +502,8 @@ static int pcistub_seize(struct pci_dev *dev) | |||
493 | return err; | 502 | return err; |
494 | } | 503 | } |
495 | 504 | ||
505 | /* Called when 'bind'. This means we must _NOT_ call pci_reset_function or | ||
506 | * other functions that take the sysfs lock. */ | ||
496 | static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) | 507 | static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) |
497 | { | 508 | { |
498 | int err = 0; | 509 | int err = 0; |
@@ -520,6 +531,8 @@ out: | |||
520 | return err; | 531 | return err; |
521 | } | 532 | } |
522 | 533 | ||
534 | /* Called when 'unbind'. This means we must _NOT_ call pci_reset_function or | ||
535 | * other functions that take the sysfs lock. */ | ||
523 | static void pcistub_remove(struct pci_dev *dev) | 536 | static void pcistub_remove(struct pci_dev *dev) |
524 | { | 537 | { |
525 | struct pcistub_device *psdev, *found_psdev = NULL; | 538 | struct pcistub_device *psdev, *found_psdev = NULL; |
@@ -551,6 +564,8 @@ static void pcistub_remove(struct pci_dev *dev) | |||
551 | pr_warn("****** shutdown driver domain before binding device\n"); | 564 | pr_warn("****** shutdown driver domain before binding device\n"); |
552 | pr_warn("****** to other drivers or domains\n"); | 565 | pr_warn("****** to other drivers or domains\n"); |
553 | 566 | ||
567 | /* N.B. This ends up calling pcistub_put_pci_dev which ends up | ||
568 | * doing the FLR. */ | ||
554 | xen_pcibk_release_pci_dev(found_psdev->pdev, | 569 | xen_pcibk_release_pci_dev(found_psdev->pdev, |
555 | found_psdev->dev); | 570 | found_psdev->dev); |
556 | } | 571 | } |
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c index a9ed867afaba..4a7e6e0a5f4c 100644 --- a/drivers/xen/xen-pciback/xenbus.c +++ b/drivers/xen/xen-pciback/xenbus.c | |||
@@ -93,6 +93,8 @@ static void free_pdev(struct xen_pcibk_device *pdev) | |||
93 | 93 | ||
94 | xen_pcibk_disconnect(pdev); | 94 | xen_pcibk_disconnect(pdev); |
95 | 95 | ||
96 | /* N.B. This calls pcistub_put_pci_dev which does the FLR on all | ||
97 | * of the PCIe devices. */ | ||
96 | xen_pcibk_release_devices(pdev); | 98 | xen_pcibk_release_devices(pdev); |
97 | 99 | ||
98 | dev_set_drvdata(&pdev->xdev->dev, NULL); | 100 | dev_set_drvdata(&pdev->xdev->dev, NULL); |
@@ -286,6 +288,8 @@ static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev, | |||
286 | dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id); | 288 | dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id); |
287 | xen_unregister_device_domain_owner(dev); | 289 | xen_unregister_device_domain_owner(dev); |
288 | 290 | ||
291 | /* N.B. This ends up calling pcistub_put_pci_dev which ends up | ||
292 | * doing the FLR. */ | ||
289 | xen_pcibk_release_pci_dev(pdev, dev); | 293 | xen_pcibk_release_pci_dev(pdev, dev); |
290 | 294 | ||
291 | out: | 295 | out: |