Skip to content

Commit

Permalink
Merge tag 'stable/for-linus-3.10-rc3-tag' of git://git.kernel.org/pub…
Browse files Browse the repository at this point in the history
…/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.
  • Loading branch information
torvalds committed May 30, 2013
2 parents 5489e94 + 8d0b880 commit 3655b22
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 27 deletions.
10 changes: 4 additions & 6 deletions arch/x86/xen/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 0 additions & 1 deletion arch/x86/xen/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
2 changes: 2 additions & 0 deletions drivers/xen/tmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions drivers/xen/xen-pciback/pci_stub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions drivers/xen/xenbus/xenbus_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions drivers/xen/xenbus/xenbus_comms.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
27 changes: 12 additions & 15 deletions drivers/xen/xenbus/xenbus_probe.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -719,47 +722,41 @@ 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;

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;
Expand Down
7 changes: 7 additions & 0 deletions drivers/xen/xenbus/xenbus_probe.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
37 changes: 36 additions & 1 deletion drivers/xen/xenbus/xenbus_probe_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions include/xen/xenbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 3655b22

Please sign in to comment.