mirror of
https://github.com/torvalds/linux.git
synced 2024-11-24 21:21:41 +00:00
Fixes:
- Use proper error paths - Clean up APIC IPI usage (incorrect arguments) - Delay XenBus frontend resume is backend (xenstored) is not running - Fix build error with various combinations of CONFIG_ -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.13 (GNU/Linux) iQEcBAABAgAGBQJRp59pAAoJEFjIrFwIi8fJRIYIAKvRh2Dp/AB44ZN97MW/QhEN NUvrSTYr2HlqcUW7bv0ScrMLb0LlFeo+9s/bo0KI2+2F+zK822WPC+2KEZmzQIVs q261dNsA3/HoyBDOLwWjatjsSus+njBOEgDIwARPwhkoon4fRXBnRJVMy+0bZC3I fpd1nlUy0J7jW0QLO5ueKqd5ZN0Mkwn2H4+D8TOPVYHCnk3mT2W+qLCEJmkMxOuZ iFYy95K1ky5r0leUUwCTUIGLmgftoh0Qo/RweXSmzuLiZrY+5ilike3gxQSiAjsM lIjq+gKXNJJGz4M6wbOTfDzb/WQnKD+2PqlsbulrTD7E6RD6wIsqG/zvc1RqHqw= =9gi8 -----END PGP SIGNATURE----- Merge tag 'stable/for-linus-3.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen Pull Xen fixes from Konrad Rzeszutek Wilk: - Use proper error paths - Clean up APIC IPI usage (incorrect arguments) - Delay XenBus frontend resume is backend (xenstored) is not running - Fix build error with various combinations of CONFIG_ * tag 'stable/for-linus-3.10-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen: xenbus_client.c: correct exit path for xenbus_map_ring_valloc_hvm xen-pciback: more uses of cached MSI-X capability offset xen: Clean up apic ipi interface xenbus: save xenstore local status for later use xenbus: delay xenbus frontend resume if xenstored is not running xmem/tmem: fix 'undefined variable' build error.
This commit is contained in:
commit
3655b22de0
@ -576,24 +576,22 @@ void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
|
||||
{
|
||||
unsigned cpu;
|
||||
unsigned int this_cpu = smp_processor_id();
|
||||
int xen_vector = xen_map_vector(vector);
|
||||
|
||||
if (!(num_online_cpus() > 1))
|
||||
if (!(num_online_cpus() > 1) || (xen_vector < 0))
|
||||
return;
|
||||
|
||||
for_each_cpu_and(cpu, mask, cpu_online_mask) {
|
||||
if (this_cpu == cpu)
|
||||
continue;
|
||||
|
||||
xen_smp_send_call_function_single_ipi(cpu);
|
||||
xen_send_IPI_one(cpu, xen_vector);
|
||||
}
|
||||
}
|
||||
|
||||
void xen_send_IPI_allbutself(int vector)
|
||||
{
|
||||
int xen_vector = xen_map_vector(vector);
|
||||
|
||||
if (xen_vector >= 0)
|
||||
xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector);
|
||||
xen_send_IPI_mask_allbutself(cpu_online_mask, vector);
|
||||
}
|
||||
|
||||
static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
|
||||
|
@ -5,7 +5,6 @@ extern void xen_send_IPI_mask(const struct cpumask *mask,
|
||||
extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
|
||||
int vector);
|
||||
extern void xen_send_IPI_allbutself(int vector);
|
||||
extern void physflat_send_IPI_allbutself(int vector);
|
||||
extern void xen_send_IPI_all(int vector);
|
||||
extern void xen_send_IPI_self(int vector);
|
||||
|
||||
|
@ -41,6 +41,8 @@ module_param(selfballooning, bool, S_IRUGO);
|
||||
#ifdef CONFIG_FRONTSWAP
|
||||
static bool frontswap __read_mostly = true;
|
||||
module_param(frontswap, bool, S_IRUGO);
|
||||
#else /* CONFIG_FRONTSWAP */
|
||||
#define frontswap (0)
|
||||
#endif /* CONFIG_FRONTSWAP */
|
||||
|
||||
#ifdef CONFIG_XEN_SELFBALLOONING
|
||||
|
@ -106,7 +106,7 @@ static void pcistub_device_release(struct kref *kref)
|
||||
else
|
||||
pci_restore_state(dev);
|
||||
|
||||
if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
|
||||
if (dev->msix_cap) {
|
||||
struct physdev_pci_device ppdev = {
|
||||
.seg = pci_domain_nr(dev->bus),
|
||||
.bus = dev->bus->number,
|
||||
@ -371,7 +371,7 @@ static int pcistub_init_device(struct pci_dev *dev)
|
||||
if (err)
|
||||
goto config_release;
|
||||
|
||||
if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
|
||||
if (dev->msix_cap) {
|
||||
struct physdev_pci_device ppdev = {
|
||||
.seg = pci_domain_nr(dev->bus),
|
||||
.bus = dev->bus->number,
|
||||
|
@ -534,7 +534,7 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
|
||||
|
||||
err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr);
|
||||
if (err)
|
||||
goto out_err;
|
||||
goto out_err_free_ballooned_pages;
|
||||
|
||||
spin_lock(&xenbus_valloc_lock);
|
||||
list_add(&node->next, &xenbus_valloc_pages);
|
||||
@ -543,8 +543,9 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
|
||||
*vaddr = addr;
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
out_err_free_ballooned_pages:
|
||||
free_xenballooned_pages(1, &node->page);
|
||||
out_err:
|
||||
kfree(node);
|
||||
return err;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ int xb_wait_for_data_to_read(void);
|
||||
int xs_input_avail(void);
|
||||
extern struct xenstore_domain_interface *xen_store_interface;
|
||||
extern int xen_store_evtchn;
|
||||
extern enum xenstore_init xen_store_domain_type;
|
||||
|
||||
extern const struct file_operations xen_xenbus_fops;
|
||||
|
||||
|
@ -69,6 +69,9 @@ EXPORT_SYMBOL_GPL(xen_store_evtchn);
|
||||
struct xenstore_domain_interface *xen_store_interface;
|
||||
EXPORT_SYMBOL_GPL(xen_store_interface);
|
||||
|
||||
enum xenstore_init xen_store_domain_type;
|
||||
EXPORT_SYMBOL_GPL(xen_store_domain_type);
|
||||
|
||||
static unsigned long xen_store_mfn;
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
|
||||
@ -719,17 +722,11 @@ static int __init xenstored_local_init(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
enum xenstore_init {
|
||||
UNKNOWN,
|
||||
PV,
|
||||
HVM,
|
||||
LOCAL,
|
||||
};
|
||||
static int __init xenbus_init(void)
|
||||
{
|
||||
int err = 0;
|
||||
enum xenstore_init usage = UNKNOWN;
|
||||
uint64_t v = 0;
|
||||
xen_store_domain_type = XS_UNKNOWN;
|
||||
|
||||
if (!xen_domain())
|
||||
return -ENODEV;
|
||||
@ -737,29 +734,29 @@ static int __init xenbus_init(void)
|
||||
xenbus_ring_ops_init();
|
||||
|
||||
if (xen_pv_domain())
|
||||
usage = PV;
|
||||
xen_store_domain_type = XS_PV;
|
||||
if (xen_hvm_domain())
|
||||
usage = HVM;
|
||||
xen_store_domain_type = XS_HVM;
|
||||
if (xen_hvm_domain() && xen_initial_domain())
|
||||
usage = LOCAL;
|
||||
xen_store_domain_type = XS_LOCAL;
|
||||
if (xen_pv_domain() && !xen_start_info->store_evtchn)
|
||||
usage = LOCAL;
|
||||
xen_store_domain_type = XS_LOCAL;
|
||||
if (xen_pv_domain() && xen_start_info->store_evtchn)
|
||||
xenstored_ready = 1;
|
||||
|
||||
switch (usage) {
|
||||
case LOCAL:
|
||||
switch (xen_store_domain_type) {
|
||||
case XS_LOCAL:
|
||||
err = xenstored_local_init();
|
||||
if (err)
|
||||
goto out_error;
|
||||
xen_store_interface = mfn_to_virt(xen_store_mfn);
|
||||
break;
|
||||
case PV:
|
||||
case XS_PV:
|
||||
xen_store_evtchn = xen_start_info->store_evtchn;
|
||||
xen_store_mfn = xen_start_info->store_mfn;
|
||||
xen_store_interface = mfn_to_virt(xen_store_mfn);
|
||||
break;
|
||||
case HVM:
|
||||
case XS_HVM:
|
||||
err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
|
||||
if (err)
|
||||
goto out_error;
|
||||
|
@ -47,6 +47,13 @@ struct xen_bus_type {
|
||||
struct bus_type bus;
|
||||
};
|
||||
|
||||
enum xenstore_init {
|
||||
XS_UNKNOWN,
|
||||
XS_PV,
|
||||
XS_HVM,
|
||||
XS_LOCAL,
|
||||
};
|
||||
|
||||
extern struct device_attribute xenbus_dev_attrs[];
|
||||
|
||||
extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include "xenbus_probe.h"
|
||||
|
||||
|
||||
static struct workqueue_struct *xenbus_frontend_wq;
|
||||
|
||||
/* device/<type>/<id> => <type>-<id> */
|
||||
static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename)
|
||||
{
|
||||
@ -89,9 +91,40 @@ static void backend_changed(struct xenbus_watch *watch,
|
||||
xenbus_otherend_changed(watch, vec, len, 1);
|
||||
}
|
||||
|
||||
static void xenbus_frontend_delayed_resume(struct work_struct *w)
|
||||
{
|
||||
struct xenbus_device *xdev = container_of(w, struct xenbus_device, work);
|
||||
|
||||
xenbus_dev_resume(&xdev->dev);
|
||||
}
|
||||
|
||||
static int xenbus_frontend_dev_resume(struct device *dev)
|
||||
{
|
||||
/*
|
||||
* If xenstored is running in this domain, we cannot access the backend
|
||||
* state at the moment, so we need to defer xenbus_dev_resume
|
||||
*/
|
||||
if (xen_store_domain_type == XS_LOCAL) {
|
||||
struct xenbus_device *xdev = to_xenbus_device(dev);
|
||||
|
||||
if (!xenbus_frontend_wq) {
|
||||
pr_err("%s: no workqueue to process delayed resume\n",
|
||||
xdev->nodename);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
INIT_WORK(&xdev->work, xenbus_frontend_delayed_resume);
|
||||
queue_work(xenbus_frontend_wq, &xdev->work);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return xenbus_dev_resume(dev);
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops xenbus_pm_ops = {
|
||||
.suspend = xenbus_dev_suspend,
|
||||
.resume = xenbus_dev_resume,
|
||||
.resume = xenbus_frontend_dev_resume,
|
||||
.freeze = xenbus_dev_suspend,
|
||||
.thaw = xenbus_dev_cancel,
|
||||
.restore = xenbus_dev_resume,
|
||||
@ -440,6 +473,8 @@ static int __init xenbus_probe_frontend_init(void)
|
||||
|
||||
register_xenstore_notifier(&xenstore_notifier);
|
||||
|
||||
xenbus_frontend_wq = create_workqueue("xenbus_frontend");
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(xenbus_probe_frontend_init);
|
||||
|
@ -70,6 +70,7 @@ struct xenbus_device {
|
||||
struct device dev;
|
||||
enum xenbus_state state;
|
||||
struct completion down;
|
||||
struct work_struct work;
|
||||
};
|
||||
|
||||
static inline struct xenbus_device *to_xenbus_device(struct device *dev)
|
||||
|
Loading…
Reference in New Issue
Block a user