From aa8532c32216ae07c3813b9aeb774517878a7573 Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Thu, 8 May 2014 11:09:23 +0100 Subject: xen: refactor suspend pre/post hooks New architectures currently have to provide implementations of 5 different functions: xen_arch_pre_suspend(), xen_arch_post_suspend(), xen_arch_hvm_post_suspend(), xen_mm_pin_all(), and xen_mm_unpin_all(). Refactor the suspend code to only require xen_arch_pre_suspend() and xen_arch_post_suspend(). Signed-off-by: David Vrabel Reviewed-by: Boris Ostrovsky --- drivers/xen/manage.c | 45 +++++++-------------------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) (limited to 'drivers/xen') 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; struct suspend_info { int cancelled; - unsigned long arg; /* extra hypercall argument */ - void (*pre)(void); - void (*post)(int cancelled); }; static RAW_NOTIFIER_HEAD(xen_resume_notifier); @@ -61,26 +58,6 @@ void xen_resume_notifier_unregister(struct notifier_block *nb) EXPORT_SYMBOL_GPL(xen_resume_notifier_unregister); #ifdef CONFIG_HIBERNATE_CALLBACKS -static void xen_hvm_post_suspend(int cancelled) -{ - xen_arch_hvm_post_suspend(cancelled); - gnttab_resume(); -} - -static void xen_pre_suspend(void) -{ - xen_mm_pin_all(); - gnttab_suspend(); - xen_arch_pre_suspend(); -} - -static void xen_post_suspend(int cancelled) -{ - xen_arch_post_suspend(cancelled); - gnttab_resume(); - xen_mm_unpin_all(); -} - static int xen_suspend(void *data) { struct suspend_info *si = data; @@ -94,18 +71,20 @@ static int xen_suspend(void *data) return err; } - if (si->pre) - si->pre(); + gnttab_suspend(); + xen_arch_pre_suspend(); /* * This hypercall returns 1 if suspend was cancelled * or the domain was merely checkpointed, and 0 if it * is resuming in a new domain. */ - si->cancelled = HYPERVISOR_suspend(si->arg); + si->cancelled = HYPERVISOR_suspend(xen_pv_domain() + ? virt_to_mfn(xen_start_info) + : 0); - if (si->post) - si->post(si->cancelled); + xen_arch_post_suspend(si->cancelled); + gnttab_resume(); if (!si->cancelled) { xen_irq_resume(); @@ -154,16 +133,6 @@ static void do_suspend(void) si.cancelled = 1; - if (xen_hvm_domain()) { - si.arg = 0UL; - si.pre = NULL; - si.post = &xen_hvm_post_suspend; - } else { - si.arg = virt_to_mfn(xen_start_info); - si.pre = &xen_pre_suspend; - si.post = &xen_post_suspend; - } - err = stop_machine(xen_suspend, &si, cpumask_of(0)); raw_notifier_call_chain(&xen_resume_notifier, 0, NULL); -- cgit From 8899035eec4105a10149817fdaf684f127670f8c Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 3 Dec 2013 21:34:03 -0500 Subject: xen-pciback: Cleanup up pcistub_put_pci_dev We are using 'psdev->dev','found_psdev->dev', and 'dev' at the same time - and they all point to the same structure. To keep it straight lets just use one - 'dev'. Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: Jan Beulich Reviewed-by: David Vrabel --- drivers/xen/xen-pciback/pci_stub.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/xen') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 62fcd485f0a7..5300a216896d 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -272,16 +272,16 @@ void pcistub_put_pci_dev(struct pci_dev *dev) * and want to inhibit the user from fiddling with 'reset' */ pci_reset_function(dev); - pci_restore_state(psdev->dev); + pci_restore_state(dev); /* This disables the device. */ - xen_pcibk_reset_device(found_psdev->dev); + xen_pcibk_reset_device(dev); /* And cleanup up our emulated fields. */ - xen_pcibk_config_free_dyn_fields(found_psdev->dev); - xen_pcibk_config_reset_dev(found_psdev->dev); + xen_pcibk_config_free_dyn_fields(dev); + xen_pcibk_config_reset_dev(dev); - xen_unregister_device_domain_owner(found_psdev->dev); + xen_unregister_device_domain_owner(dev); spin_lock_irqsave(&found_psdev->lock, flags); found_psdev->pdev = NULL; -- cgit From fcb8ce968fb5d476cbb3f1547ade0c05fc2f6c59 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 3 Dec 2013 21:37:24 -0500 Subject: xen-pciback: First reset, then free. We were doing the operations of freeing and reset in the wrong order. Granted nothing broke because the reset functions just set bar->which = 0. But nonethless this was incorrect. Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: Jan Beulich Reviewed-by: David Vrabel --- drivers/xen/xen-pciback/pci_stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/xen') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 5300a216896d..36dd4f3685f0 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -278,8 +278,8 @@ void pcistub_put_pci_dev(struct pci_dev *dev) xen_pcibk_reset_device(dev); /* And cleanup up our emulated fields. */ - xen_pcibk_config_free_dyn_fields(dev); xen_pcibk_config_reset_dev(dev); + xen_pcibk_config_free_dyn_fields(dev); xen_unregister_device_domain_owner(dev); -- cgit From 8be9df6d4b6b53112abb078cb58827767471d797 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 3 Dec 2013 21:47:37 -0500 Subject: xen-pciback: Document when we FLR an PCI device. When the toolstack wants us to drop or add an PCI device it changes the XenBus state to Configuring - and as result of that we find out which devices we should still be exporting out and which ones not. For the ones we don't need anymore we need to do an PCI reset so that it is ready for the next guest. Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: David Vrabel --- drivers/xen/xen-pciback/pci_stub.c | 2 ++ drivers/xen/xen-pciback/xenbus.c | 4 ++++ 2 files changed, 6 insertions(+) (limited to 'drivers/xen') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 36dd4f3685f0..b84426a7f88d 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -551,6 +551,8 @@ static void pcistub_remove(struct pci_dev *dev) pr_warn("****** shutdown driver domain before binding device\n"); pr_warn("****** to other drivers or domains\n"); + /* N.B. This ends up calling pcistub_put_pci_dev which ends up + * doing the FLR. */ xen_pcibk_release_pci_dev(found_psdev->pdev, found_psdev->dev); } 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) xen_pcibk_disconnect(pdev); + /* N.B. This calls pcistub_put_pci_dev which does the FLR on all + * of the PCIe devices. */ xen_pcibk_release_devices(pdev); dev_set_drvdata(&pdev->xdev->dev, NULL); @@ -286,6 +288,8 @@ static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev, dev_dbg(&dev->dev, "unregistering for %d\n", pdev->xdev->otherend_id); xen_unregister_device_domain_owner(dev); + /* N.B. This ends up calling pcistub_put_pci_dev which ends up + * doing the FLR. */ xen_pcibk_release_pci_dev(pdev, dev); out: -- cgit From 24d8bf1b0a12a92171c6f08a665c6ff3f0788c91 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Mon, 21 Apr 2014 15:43:08 -0400 Subject: xen/pciback: Document when the 'unbind' and 'bind' functions are called. And also mention that you cannot do any pci_reset_function, pci_reset_slot, or such calls. This is because they take the same lock as SysFS does - and we would end up with a dead-lock if we call those functions. Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: David Vrabel --- drivers/xen/xen-pciback/pci_stub.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers/xen') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index b84426a7f88d..1539becad139 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -493,6 +493,8 @@ static int pcistub_seize(struct pci_dev *dev) return err; } +/* Called when 'bind'. This means we must _NOT_ call pci_reset_function or + * other functions that take the sysfs lock. */ static int pcistub_probe(struct pci_dev *dev, const struct pci_device_id *id) { int err = 0; @@ -520,6 +522,8 @@ out: return err; } +/* Called when 'unbind'. This means we must _NOT_ call pci_reset_function or + * other functions that take the sysfs lock. */ static void pcistub_remove(struct pci_dev *dev) { struct pcistub_device *psdev, *found_psdev = NULL; -- cgit From 0a9fd0152929db372ff61b0d6c280fdd34ae8bdb Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Tue, 22 Apr 2014 10:48:17 -0400 Subject: xen/pciback: Document the entry points for 'pcistub_put_pci_dev' which are quite a few. It should be evident that dealing with that many options is a bit complex. Signed-off-by: Konrad Rzeszutek Wilk Reviewed-by: David Vrabel --- drivers/xen/xen-pciback/pci_stub.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/xen') diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 1539becad139..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, return found_dev; } +/* + * Called when: + * - XenBus state has been reconfigure (pci unplug). See xen_pcibk_remove_device + * - XenBus state has been disconnected (guest shutdown). See xen_pcibk_xenbus_remove + * - 'echo BDF > unbind' on pciback module with no guest attached. See pcistub_remove + * - 'echo BDF > unbind' with a guest still using it. See pcistub_remove + * + * As such we have to be careful. + */ void pcistub_put_pci_dev(struct pci_dev *dev) { struct pcistub_device *psdev, *found_psdev = NULL; -- cgit From 1a4b50f674d0d2f66569f08d063996971b7d48f2 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 19 Mar 2014 16:03:23 -0400 Subject: xen-acpi-processor: Don't display errors when we get -ENOSYS which is a perfectly legal error. This can be triggered if the user has booted Xen with the no-cpuidle parameter. Reported-by-and-Tested-by: Don Slutz Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/xen-acpi-processor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/xen') 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) pr_debug(" C%d: %s %d uS\n", cx->type, cx->desc, (u32)cx->latency); } - } else if (ret != -EINVAL) + } else if ((ret != -EINVAL) && (ret != -ENOSYS)) /* EINVAL means the ACPI ID is incorrect - meaning the ACPI * table is referencing a non-existing CPU - which can happen * with broken ACPI tables. */ @@ -259,7 +259,7 @@ static int push_pxx_to_hypervisor(struct acpi_processor *_pr) (u32) perf->states[i].power, (u32) perf->states[i].transition_latency); } - } else if (ret != -EINVAL) + } else if ((ret != -EINVAL) && (ret != -ENOSYS)) /* EINVAL means the ACPI ID is incorrect - meaning the ACPI * table is referencing a non-existing CPU - which can happen * with broken ACPI tables. */ -- cgit