mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 16:41:25 +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
10 changed files with 68 additions and 27 deletions
|
@ -576,24 +576,22 @@ void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
|
||||||
{
|
{
|
||||||
unsigned cpu;
|
unsigned cpu;
|
||||||
unsigned int this_cpu = smp_processor_id();
|
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;
|
return;
|
||||||
|
|
||||||
for_each_cpu_and(cpu, mask, cpu_online_mask) {
|
for_each_cpu_and(cpu, mask, cpu_online_mask) {
|
||||||
if (this_cpu == cpu)
|
if (this_cpu == cpu)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
xen_smp_send_call_function_single_ipi(cpu);
|
xen_send_IPI_one(cpu, xen_vector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void xen_send_IPI_allbutself(int vector)
|
void xen_send_IPI_allbutself(int vector)
|
||||||
{
|
{
|
||||||
int xen_vector = xen_map_vector(vector);
|
xen_send_IPI_mask_allbutself(cpu_online_mask, vector);
|
||||||
|
|
||||||
if (xen_vector >= 0)
|
|
||||||
xen_send_IPI_mask_allbutself(cpu_online_mask, xen_vector);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
|
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,
|
extern void xen_send_IPI_mask_allbutself(const struct cpumask *mask,
|
||||||
int vector);
|
int vector);
|
||||||
extern void xen_send_IPI_allbutself(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_all(int vector);
|
||||||
extern void xen_send_IPI_self(int vector);
|
extern void xen_send_IPI_self(int vector);
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,8 @@ module_param(selfballooning, bool, S_IRUGO);
|
||||||
#ifdef CONFIG_FRONTSWAP
|
#ifdef CONFIG_FRONTSWAP
|
||||||
static bool frontswap __read_mostly = true;
|
static bool frontswap __read_mostly = true;
|
||||||
module_param(frontswap, bool, S_IRUGO);
|
module_param(frontswap, bool, S_IRUGO);
|
||||||
|
#else /* CONFIG_FRONTSWAP */
|
||||||
|
#define frontswap (0)
|
||||||
#endif /* CONFIG_FRONTSWAP */
|
#endif /* CONFIG_FRONTSWAP */
|
||||||
|
|
||||||
#ifdef CONFIG_XEN_SELFBALLOONING
|
#ifdef CONFIG_XEN_SELFBALLOONING
|
||||||
|
|
|
@ -106,7 +106,7 @@ static void pcistub_device_release(struct kref *kref)
|
||||||
else
|
else
|
||||||
pci_restore_state(dev);
|
pci_restore_state(dev);
|
||||||
|
|
||||||
if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
|
if (dev->msix_cap) {
|
||||||
struct physdev_pci_device ppdev = {
|
struct physdev_pci_device ppdev = {
|
||||||
.seg = pci_domain_nr(dev->bus),
|
.seg = pci_domain_nr(dev->bus),
|
||||||
.bus = dev->bus->number,
|
.bus = dev->bus->number,
|
||||||
|
@ -371,7 +371,7 @@ static int pcistub_init_device(struct pci_dev *dev)
|
||||||
if (err)
|
if (err)
|
||||||
goto config_release;
|
goto config_release;
|
||||||
|
|
||||||
if (pci_find_capability(dev, PCI_CAP_ID_MSIX)) {
|
if (dev->msix_cap) {
|
||||||
struct physdev_pci_device ppdev = {
|
struct physdev_pci_device ppdev = {
|
||||||
.seg = pci_domain_nr(dev->bus),
|
.seg = pci_domain_nr(dev->bus),
|
||||||
.bus = dev->bus->number,
|
.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);
|
err = xenbus_map_ring(dev, gnt_ref, &node->handle, addr);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_err;
|
goto out_err_free_ballooned_pages;
|
||||||
|
|
||||||
spin_lock(&xenbus_valloc_lock);
|
spin_lock(&xenbus_valloc_lock);
|
||||||
list_add(&node->next, &xenbus_valloc_pages);
|
list_add(&node->next, &xenbus_valloc_pages);
|
||||||
|
@ -543,8 +543,9 @@ static int xenbus_map_ring_valloc_hvm(struct xenbus_device *dev,
|
||||||
*vaddr = addr;
|
*vaddr = addr;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_err:
|
out_err_free_ballooned_pages:
|
||||||
free_xenballooned_pages(1, &node->page);
|
free_xenballooned_pages(1, &node->page);
|
||||||
|
out_err:
|
||||||
kfree(node);
|
kfree(node);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ int xb_wait_for_data_to_read(void);
|
||||||
int xs_input_avail(void);
|
int xs_input_avail(void);
|
||||||
extern struct xenstore_domain_interface *xen_store_interface;
|
extern struct xenstore_domain_interface *xen_store_interface;
|
||||||
extern int xen_store_evtchn;
|
extern int xen_store_evtchn;
|
||||||
|
extern enum xenstore_init xen_store_domain_type;
|
||||||
|
|
||||||
extern const struct file_operations xen_xenbus_fops;
|
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;
|
struct xenstore_domain_interface *xen_store_interface;
|
||||||
EXPORT_SYMBOL_GPL(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 unsigned long xen_store_mfn;
|
||||||
|
|
||||||
static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
|
static BLOCKING_NOTIFIER_HEAD(xenstore_chain);
|
||||||
|
@ -719,17 +722,11 @@ static int __init xenstored_local_init(void)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum xenstore_init {
|
|
||||||
UNKNOWN,
|
|
||||||
PV,
|
|
||||||
HVM,
|
|
||||||
LOCAL,
|
|
||||||
};
|
|
||||||
static int __init xenbus_init(void)
|
static int __init xenbus_init(void)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
enum xenstore_init usage = UNKNOWN;
|
|
||||||
uint64_t v = 0;
|
uint64_t v = 0;
|
||||||
|
xen_store_domain_type = XS_UNKNOWN;
|
||||||
|
|
||||||
if (!xen_domain())
|
if (!xen_domain())
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -737,29 +734,29 @@ static int __init xenbus_init(void)
|
||||||
xenbus_ring_ops_init();
|
xenbus_ring_ops_init();
|
||||||
|
|
||||||
if (xen_pv_domain())
|
if (xen_pv_domain())
|
||||||
usage = PV;
|
xen_store_domain_type = XS_PV;
|
||||||
if (xen_hvm_domain())
|
if (xen_hvm_domain())
|
||||||
usage = HVM;
|
xen_store_domain_type = XS_HVM;
|
||||||
if (xen_hvm_domain() && xen_initial_domain())
|
if (xen_hvm_domain() && xen_initial_domain())
|
||||||
usage = LOCAL;
|
xen_store_domain_type = XS_LOCAL;
|
||||||
if (xen_pv_domain() && !xen_start_info->store_evtchn)
|
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)
|
if (xen_pv_domain() && xen_start_info->store_evtchn)
|
||||||
xenstored_ready = 1;
|
xenstored_ready = 1;
|
||||||
|
|
||||||
switch (usage) {
|
switch (xen_store_domain_type) {
|
||||||
case LOCAL:
|
case XS_LOCAL:
|
||||||
err = xenstored_local_init();
|
err = xenstored_local_init();
|
||||||
if (err)
|
if (err)
|
||||||
goto out_error;
|
goto out_error;
|
||||||
xen_store_interface = mfn_to_virt(xen_store_mfn);
|
xen_store_interface = mfn_to_virt(xen_store_mfn);
|
||||||
break;
|
break;
|
||||||
case PV:
|
case XS_PV:
|
||||||
xen_store_evtchn = xen_start_info->store_evtchn;
|
xen_store_evtchn = xen_start_info->store_evtchn;
|
||||||
xen_store_mfn = xen_start_info->store_mfn;
|
xen_store_mfn = xen_start_info->store_mfn;
|
||||||
xen_store_interface = mfn_to_virt(xen_store_mfn);
|
xen_store_interface = mfn_to_virt(xen_store_mfn);
|
||||||
break;
|
break;
|
||||||
case HVM:
|
case XS_HVM:
|
||||||
err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
|
err = hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &v);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_error;
|
goto out_error;
|
||||||
|
|
|
@ -47,6 +47,13 @@ struct xen_bus_type {
|
||||||
struct bus_type bus;
|
struct bus_type bus;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum xenstore_init {
|
||||||
|
XS_UNKNOWN,
|
||||||
|
XS_PV,
|
||||||
|
XS_HVM,
|
||||||
|
XS_LOCAL,
|
||||||
|
};
|
||||||
|
|
||||||
extern struct device_attribute xenbus_dev_attrs[];
|
extern struct device_attribute xenbus_dev_attrs[];
|
||||||
|
|
||||||
extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
|
extern int xenbus_match(struct device *_dev, struct device_driver *_drv);
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "xenbus_probe.h"
|
#include "xenbus_probe.h"
|
||||||
|
|
||||||
|
|
||||||
|
static struct workqueue_struct *xenbus_frontend_wq;
|
||||||
|
|
||||||
/* device/<type>/<id> => <type>-<id> */
|
/* device/<type>/<id> => <type>-<id> */
|
||||||
static int frontend_bus_id(char bus_id[XEN_BUS_ID_SIZE], const char *nodename)
|
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);
|
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 = {
|
static const struct dev_pm_ops xenbus_pm_ops = {
|
||||||
.suspend = xenbus_dev_suspend,
|
.suspend = xenbus_dev_suspend,
|
||||||
.resume = xenbus_dev_resume,
|
.resume = xenbus_frontend_dev_resume,
|
||||||
.freeze = xenbus_dev_suspend,
|
.freeze = xenbus_dev_suspend,
|
||||||
.thaw = xenbus_dev_cancel,
|
.thaw = xenbus_dev_cancel,
|
||||||
.restore = xenbus_dev_resume,
|
.restore = xenbus_dev_resume,
|
||||||
|
@ -440,6 +473,8 @@ static int __init xenbus_probe_frontend_init(void)
|
||||||
|
|
||||||
register_xenstore_notifier(&xenstore_notifier);
|
register_xenstore_notifier(&xenstore_notifier);
|
||||||
|
|
||||||
|
xenbus_frontend_wq = create_workqueue("xenbus_frontend");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
subsys_initcall(xenbus_probe_frontend_init);
|
subsys_initcall(xenbus_probe_frontend_init);
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct xenbus_device {
|
||||||
struct device dev;
|
struct device dev;
|
||||||
enum xenbus_state state;
|
enum xenbus_state state;
|
||||||
struct completion down;
|
struct completion down;
|
||||||
|
struct work_struct work;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline struct xenbus_device *to_xenbus_device(struct device *dev)
|
static inline struct xenbus_device *to_xenbus_device(struct device *dev)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue