Features:

- Populate the boot_params with EDD data.
  - Cleanups in the IRQ code.
 Bug-fixes:
  - CPU hotplug offline/online in PVHVM mode.
  - Re-upload processor PM data after ACPI S3 suspend/resume cycle.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.13 (GNU/Linux)
 
 iQEcBAABAgAGBQJRcWFDAAoJEFjIrFwIi8fJQScIAJmnsPzoqd/USahqgbOvc0Nb
 fJgzvno0Lfuvi5NipMpMDNCpCxRuikoJe6ocoF6E0+poucckRGDFSC3R2KVgLR2O
 pXkO7bzggkUYkLehW7gXmM4IlvhLxnsfEofDWxG2VJy6RfWxFk+84v/uimQSIB0D
 jI9FB3oUhfA+IT8/3Iofyv2OiPH39zNLlzidAnVXmJ8SoJFDLt3l1IymYqVdq6Lt
 AKL0IXa31f+yfj9Vli1mkBsxuEIvIo5tVQNn250B4cMlR8mcWsQBnxIeA2M+8Jhl
 d2ereTBwhjohCrFR/TWlXYrMlL+XVucI7J7agf3tF4kmDUqjg+c9hUkszSOPjEc=
 =yJWr
 -----END PGP SIGNATURE-----

Merge tag 'stable/for-linus-3.10-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen

Pull Xen updates from Konrad Rzeszutek Wilk:
 "Features:
   - Populate the boot_params with EDD data.
   - Cleanups in the IRQ code.
  Bug-fixes:
   - CPU hotplug offline/online in PVHVM mode.
   - Re-upload processor PM data after ACPI S3 suspend/resume cycle."

And Konrad gets a gold star for sending the pull request early when he
thought he'd be away for the first week of the merge window (but because
of 3.9 dragging out to -rc8 he then re-sent the reminder on the first
day of the merge window anyway)

* tag 'stable/for-linus-3.10-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen: resolve section mismatch warnings in xen-acpi-processor
  xen: Re-upload processor PM data to hypervisor after S3 resume (v2)
  xen/smp: Unifiy some of the PVs and PVHVM offline CPU path
  xen/smp/pvhvm: Don't initialize IRQ_WORKER as we are using the native one.
  xen/spinlock: Disable IRQ spinlock (PV) allocation on PVHVM
  xen/spinlock:  Check against default value of -1 for IRQ line.
  xen/time: Add default value of -1 for IRQ and check for that.
  xen/events: Check that IRQ value passed in is valid.
  xen/time: Fix kasprintf splat when allocating timer%d IRQ line.
  xen/smp/spinlock: Fix leakage of the spinlock interrupt line for every CPU online/offline
  xen/smp: Fix leakage of timer interrupt line for every CPU online/offline.
  xen kconfig: fix select INPUT_XEN_KBDDEV_FRONTEND
  xen: drop tracking of IRQ vector
  x86/xen: populate boot_params with EDD data
This commit is contained in:
Linus Torvalds 2013-04-29 08:16:51 -07:00
commit 9d2da7af90
9 changed files with 188 additions and 54 deletions

View file

@ -85,8 +85,7 @@ enum xen_irq_type {
* event channel - irq->event channel mapping
* cpu - cpu this event channel is bound to
* index - type-specific information:
* PIRQ - vector, with MSB being "needs EIO", or physical IRQ of the HVM
* guest, or GSI (real passthrough IRQ) of the device.
* PIRQ - physical IRQ, GSI, flags, and owner domain
* VIRQ - virq number
* IPI - IPI vector
* EVTCHN -
@ -105,7 +104,6 @@ struct irq_info {
struct {
unsigned short pirq;
unsigned short gsi;
unsigned char vector;
unsigned char flags;
uint16_t domid;
} pirq;
@ -211,7 +209,6 @@ static void xen_irq_info_pirq_init(unsigned irq,
unsigned short evtchn,
unsigned short pirq,
unsigned short gsi,
unsigned short vector,
uint16_t domid,
unsigned char flags)
{
@ -221,7 +218,6 @@ static void xen_irq_info_pirq_init(unsigned irq,
info->u.pirq.pirq = pirq;
info->u.pirq.gsi = gsi;
info->u.pirq.vector = vector;
info->u.pirq.domid = domid;
info->u.pirq.flags = flags;
}
@ -519,6 +515,9 @@ static void xen_free_irq(unsigned irq)
{
struct irq_info *info = irq_get_handler_data(irq);
if (WARN_ON(!info))
return;
list_del(&info->list);
irq_set_handler_data(irq, NULL);
@ -714,7 +713,7 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
goto out;
}
xen_irq_info_pirq_init(irq, 0, pirq, gsi, irq_op.vector, DOMID_SELF,
xen_irq_info_pirq_init(irq, 0, pirq, gsi, DOMID_SELF,
shareable ? PIRQ_SHAREABLE : 0);
pirq_query_unmask(irq);
@ -762,8 +761,7 @@ int xen_allocate_pirq_msi(struct pci_dev *dev, struct msi_desc *msidesc)
}
int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
int pirq, int vector, const char *name,
domid_t domid)
int pirq, const char *name, domid_t domid)
{
int irq, ret;
@ -776,7 +774,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq,
name);
xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, domid, 0);
xen_irq_info_pirq_init(irq, 0, pirq, 0, domid, 0);
ret = irq_set_msi_desc(irq, msidesc);
if (ret < 0)
goto error_irq;
@ -1008,6 +1006,9 @@ static void unbind_from_irq(unsigned int irq)
int evtchn = evtchn_from_irq(irq);
struct irq_info *info = irq_get_handler_data(irq);
if (WARN_ON(!info))
return;
mutex_lock(&irq_mapping_update_lock);
if (info->refcnt > 0) {
@ -1135,6 +1136,10 @@ int bind_ipi_to_irqhandler(enum ipi_vector ipi,
void unbind_from_irqhandler(unsigned int irq, void *dev_id)
{
struct irq_info *info = irq_get_handler_data(irq);
if (WARN_ON(!info))
return;
free_irq(irq, dev_id);
unbind_from_irq(irq);
}
@ -1457,6 +1462,9 @@ void rebind_evtchn_irq(int evtchn, int irq)
{
struct irq_info *info = info_for_irq(irq);
if (WARN_ON(!info))
return;
/* Make sure the irq is masked, since the new event channel
will also be masked. */
disable_irq(irq);
@ -1730,7 +1738,12 @@ void xen_poll_irq(int irq)
int xen_test_irq_shared(int irq)
{
struct irq_info *info = info_for_irq(irq);
struct physdev_irq_status_query irq_status = { .irq = info->u.pirq.pirq };
struct physdev_irq_status_query irq_status;
if (WARN_ON(!info))
return -ENOENT;
irq_status.irq = info->u.pirq.pirq;
if (HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status))
return 0;

View file

@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/syscore_ops.h>
#include <acpi/acpi_bus.h>
#include <acpi/acpi_drivers.h>
#include <acpi/processor.h>
@ -51,9 +52,9 @@ static DEFINE_MUTEX(acpi_ids_mutex);
/* Which ACPI ID we have processed from 'struct acpi_processor'. */
static unsigned long *acpi_ids_done;
/* Which ACPI ID exist in the SSDT/DSDT processor definitions. */
static unsigned long __initdata *acpi_id_present;
static unsigned long *acpi_id_present;
/* And if there is an _CST definition (or a PBLK) for the ACPI IDs */
static unsigned long __initdata *acpi_id_cst_present;
static unsigned long *acpi_id_cst_present;
static int push_cxx_to_hypervisor(struct acpi_processor *_pr)
{
@ -329,7 +330,7 @@ static unsigned int __init get_max_acpi_id(void)
* for_each_[present|online]_cpu macros which are banded to the virtual
* CPU amount.
*/
static acpi_status __init
static acpi_status
read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv)
{
u32 acpi_id;
@ -384,12 +385,16 @@ read_acpi_id(acpi_handle handle, u32 lvl, void *context, void **rv)
return AE_OK;
}
static int __init check_acpi_ids(struct acpi_processor *pr_backup)
static int check_acpi_ids(struct acpi_processor *pr_backup)
{
if (!pr_backup)
return -ENODEV;
if (acpi_id_present && acpi_id_cst_present)
/* OK, done this once .. skip to uploading */
goto upload;
/* All online CPUs have been processed at this stage. Now verify
* whether in fact "online CPUs" == physical CPUs.
*/
@ -408,6 +413,7 @@ static int __init check_acpi_ids(struct acpi_processor *pr_backup)
read_acpi_id, NULL, NULL, NULL);
acpi_get_devices("ACPI0007", read_acpi_id, NULL, NULL);
upload:
if (!bitmap_equal(acpi_id_present, acpi_ids_done, nr_acpi_bits)) {
unsigned int i;
for_each_set_bit(i, acpi_id_present, nr_acpi_bits) {
@ -417,10 +423,7 @@ static int __init check_acpi_ids(struct acpi_processor *pr_backup)
(void)upload_pm_data(pr_backup);
}
}
kfree(acpi_id_present);
acpi_id_present = NULL;
kfree(acpi_id_cst_present);
acpi_id_cst_present = NULL;
return 0;
}
static int __init check_prereq(void)
@ -467,9 +470,46 @@ static void free_acpi_perf_data(void)
free_percpu(acpi_perf_data);
}
static int __init xen_acpi_processor_init(void)
static int xen_upload_processor_pm_data(void)
{
struct acpi_processor *pr_backup = NULL;
unsigned int i;
int rc = 0;
pr_info(DRV_NAME "Uploading Xen processor PM info\n");
for_each_possible_cpu(i) {
struct acpi_processor *_pr;
_pr = per_cpu(processors, i /* APIC ID */);
if (!_pr)
continue;
if (!pr_backup) {
pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
if (pr_backup)
memcpy(pr_backup, _pr, sizeof(struct acpi_processor));
}
(void)upload_pm_data(_pr);
}
rc = check_acpi_ids(pr_backup);
kfree(pr_backup);
return rc;
}
static void xen_acpi_processor_resume(void)
{
bitmap_zero(acpi_ids_done, nr_acpi_bits);
xen_upload_processor_pm_data();
}
static struct syscore_ops xap_syscore_ops = {
.resume = xen_acpi_processor_resume,
};
static int __init xen_acpi_processor_init(void)
{
unsigned int i;
int rc = check_prereq();
@ -514,27 +554,12 @@ static int __init xen_acpi_processor_init(void)
goto err_out;
}
for_each_possible_cpu(i) {
struct acpi_processor *_pr;
_pr = per_cpu(processors, i /* APIC ID */);
if (!_pr)
continue;
if (!pr_backup) {
pr_backup = kzalloc(sizeof(struct acpi_processor), GFP_KERNEL);
if (pr_backup)
memcpy(pr_backup, _pr, sizeof(struct acpi_processor));
}
(void)upload_pm_data(_pr);
}
rc = check_acpi_ids(pr_backup);
kfree(pr_backup);
pr_backup = NULL;
rc = xen_upload_processor_pm_data();
if (rc)
goto err_unregister;
register_syscore_ops(&xap_syscore_ops);
return 0;
err_unregister:
for_each_possible_cpu(i) {
@ -552,7 +577,10 @@ static void __exit xen_acpi_processor_exit(void)
{
int i;
unregister_syscore_ops(&xap_syscore_ops);
kfree(acpi_ids_done);
kfree(acpi_id_present);
kfree(acpi_id_cst_present);
for_each_possible_cpu(i) {
struct acpi_processor_performance *perf;
perf = per_cpu_ptr(acpi_perf_data, i);