Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d2da7af authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'stable/for-linus-3.10-rc0-tag' of...

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
parents c1be5a5b 18c0025b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
		goto error;
	i = 0;
	list_for_each_entry(msidesc, &dev->msi_list, list) {
		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i], 0,
		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
					       (type == PCI_CAP_ID_MSIX) ?
					       "pcifront-msi-x" :
					       "pcifront-msi",
@@ -244,7 +244,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
			dev_dbg(&dev->dev,
				"xen: msi already bound to pirq=%d\n", pirq);
		}
		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq, 0,
		irq = xen_bind_pirq_msi_to_irq(dev, msidesc, pirq,
					       (type == PCI_CAP_ID_MSIX) ?
					       "msi-x" : "msi",
					       DOMID_SELF);
@@ -326,7 +326,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
		}

		ret = xen_bind_pirq_msi_to_irq(dev, msidesc,
					       map_irq.pirq, map_irq.index,
					       map_irq.pirq,
					       (type == PCI_CAP_ID_MSIX) ?
					       "msi-x" : "msi",
						domid);
+56 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/pci.h>
#include <linux/gfp.h>
#include <linux/memblock.h>
#include <linux/edd.h>

#include <xen/xen.h>
#include <xen/events.h>
@@ -1306,6 +1307,55 @@ static const struct machine_ops xen_machine_ops __initconst = {
	.emergency_restart = xen_emergency_restart,
};

static void __init xen_boot_params_init_edd(void)
{
#if IS_ENABLED(CONFIG_EDD)
	struct xen_platform_op op;
	struct edd_info *edd_info;
	u32 *mbr_signature;
	unsigned nr;
	int ret;

	edd_info = boot_params.eddbuf;
	mbr_signature = boot_params.edd_mbr_sig_buffer;

	op.cmd = XENPF_firmware_info;

	op.u.firmware_info.type = XEN_FW_DISK_INFO;
	for (nr = 0; nr < EDDMAXNR; nr++) {
		struct edd_info *info = edd_info + nr;

		op.u.firmware_info.index = nr;
		info->params.length = sizeof(info->params);
		set_xen_guest_handle(op.u.firmware_info.u.disk_info.edd_params,
				     &info->params);
		ret = HYPERVISOR_dom0_op(&op);
		if (ret)
			break;

#define C(x) info->x = op.u.firmware_info.u.disk_info.x
		C(device);
		C(version);
		C(interface_support);
		C(legacy_max_cylinder);
		C(legacy_max_head);
		C(legacy_sectors_per_track);
#undef C
	}
	boot_params.eddbuf_entries = nr;

	op.u.firmware_info.type = XEN_FW_DISK_MBR_SIGNATURE;
	for (nr = 0; nr < EDD_MBR_SIG_MAX; nr++) {
		op.u.firmware_info.index = nr;
		ret = HYPERVISOR_dom0_op(&op);
		if (ret)
			break;
		mbr_signature[nr] = op.u.firmware_info.u.disk_mbr_signature.mbr_signature;
	}
	boot_params.edd_mbr_sig_buf_entries = nr;
#endif
}

/*
 * Set up the GDT and segment registers for -fstack-protector.  Until
 * we do this, we have to be careful not to call any stack-protected
@@ -1508,6 +1558,8 @@ asmlinkage void __init xen_start_kernel(void)
		/* Avoid searching for BIOS MP tables */
		x86_init.mpparse.find_smp_config = x86_init_noop;
		x86_init.mpparse.get_smp_config = x86_init_uint_noop;

		xen_boot_params_init_edd();
	}
#ifdef CONFIG_PCI
	/* PCI BIOS service won't work from a PV guest. */
@@ -1589,8 +1641,11 @@ static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
	switch (action) {
	case CPU_UP_PREPARE:
		xen_vcpu_setup(cpu);
		if (xen_have_vector_callback)
		if (xen_have_vector_callback) {
			xen_init_lock_cpu(cpu);
			if (xen_feature(XENFEAT_hvm_safe_pvclock))
				xen_setup_timer(cpu);
		}
		break;
	default:
		break;
+14 −7
Original line number Diff line number Diff line
@@ -144,6 +144,13 @@ static int xen_smp_intr_init(unsigned int cpu)
		goto fail;
	per_cpu(xen_callfuncsingle_irq, cpu) = rc;

	/*
	 * The IRQ worker on PVHVM goes through the native path and uses the
	 * IPI mechanism.
	 */
	if (xen_hvm_domain())
		return 0;

	callfunc_name = kasprintf(GFP_KERNEL, "irqwork%d", cpu);
	rc = bind_ipi_to_irqhandler(XEN_IRQ_WORK_VECTOR,
				    cpu,
@@ -167,6 +174,9 @@ static int xen_smp_intr_init(unsigned int cpu)
	if (per_cpu(xen_callfuncsingle_irq, cpu) >= 0)
		unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu),
				       NULL);
	if (xen_hvm_domain())
		return rc;

	if (per_cpu(xen_irq_work, cpu) >= 0)
		unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);

@@ -418,7 +428,7 @@ static int xen_cpu_disable(void)

static void xen_cpu_die(unsigned int cpu)
{
	while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) {
	while (xen_pv_domain() && HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) {
		current->state = TASK_UNINTERRUPTIBLE;
		schedule_timeout(HZ/10);
	}
@@ -426,6 +436,7 @@ static void xen_cpu_die(unsigned int cpu)
	unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
	unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
	unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
	if (!xen_hvm_domain())
		unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
	xen_uninit_lock_cpu(cpu);
	xen_teardown_timer(cpu);
@@ -657,11 +668,7 @@ static int __cpuinit xen_hvm_cpu_up(unsigned int cpu, struct task_struct *tidle)

static void xen_hvm_cpu_die(unsigned int cpu)
{
	unbind_from_irqhandler(per_cpu(xen_resched_irq, cpu), NULL);
	unbind_from_irqhandler(per_cpu(xen_callfunc_irq, cpu), NULL);
	unbind_from_irqhandler(per_cpu(xen_debug_irq, cpu), NULL);
	unbind_from_irqhandler(per_cpu(xen_callfuncsingle_irq, cpu), NULL);
	unbind_from_irqhandler(per_cpu(xen_irq_work, cpu), NULL);
	xen_cpu_die(cpu);
	native_cpu_die(cpu);
}

+25 −0
Original line number Diff line number Diff line
@@ -364,6 +364,16 @@ void __cpuinit xen_init_lock_cpu(int cpu)
	int irq;
	const char *name;

	WARN(per_cpu(lock_kicker_irq, cpu) > 0, "spinlock on CPU%d exists on IRQ%d!\n",
	     cpu, per_cpu(lock_kicker_irq, cpu));

	/*
	 * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
	 * (xen: disable PV spinlocks on HVM)
	 */
	if (xen_hvm_domain())
		return;

	name = kasprintf(GFP_KERNEL, "spinlock%d", cpu);
	irq = bind_ipi_to_irqhandler(XEN_SPIN_UNLOCK_VECTOR,
				     cpu,
@@ -382,11 +392,26 @@ void __cpuinit xen_init_lock_cpu(int cpu)

void xen_uninit_lock_cpu(int cpu)
{
	/*
	 * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
	 * (xen: disable PV spinlocks on HVM)
	 */
	if (xen_hvm_domain())
		return;

	unbind_from_irqhandler(per_cpu(lock_kicker_irq, cpu), NULL);
	per_cpu(lock_kicker_irq, cpu) = -1;
}

void __init xen_init_spinlocks(void)
{
	/*
	 * See git commit f10cd522c5fbfec9ae3cc01967868c9c2401ed23
	 * (xen: disable PV spinlocks on HVM)
	 */
	if (xen_hvm_domain())
		return;

	BUILD_BUG_ON(sizeof(struct xen_spinlock) > sizeof(arch_spinlock_t));

	pv_lock_ops.spin_is_locked = xen_spin_is_locked;
+10 −3
Original line number Diff line number Diff line
@@ -377,7 +377,7 @@ static const struct clock_event_device xen_vcpuop_clockevent = {

static const struct clock_event_device *xen_clockevent =
	&xen_timerop_clockevent;
static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events);
static DEFINE_PER_CPU(struct clock_event_device, xen_clock_events) = { .irq = -1 };

static irqreturn_t xen_timer_interrupt(int irq, void *dev_id)
{
@@ -401,6 +401,9 @@ void xen_setup_timer(int cpu)
	struct clock_event_device *evt;
	int irq;

	evt = &per_cpu(xen_clock_events, cpu);
	WARN(evt->irq >= 0, "IRQ%d for CPU%d is already allocated\n", evt->irq, cpu);

	printk(KERN_INFO "installing Xen timer for CPU %d\n", cpu);

	name = kasprintf(GFP_KERNEL, "timer%d", cpu);
@@ -413,7 +416,6 @@ void xen_setup_timer(int cpu)
				      IRQF_FORCE_RESUME,
				      name, NULL);

	evt = &per_cpu(xen_clock_events, cpu);
	memcpy(evt, xen_clockevent, sizeof(*evt));

	evt->cpumask = cpumask_of(cpu);
@@ -426,6 +428,7 @@ void xen_teardown_timer(int cpu)
	BUG_ON(cpu == 0);
	evt = &per_cpu(xen_clock_events, cpu);
	unbind_from_irqhandler(evt->irq, NULL);
	evt->irq = -1;
}

void xen_setup_cpu_clockevents(void)
@@ -497,7 +500,11 @@ static void xen_hvm_setup_cpu_clockevents(void)
{
	int cpu = smp_processor_id();
	xen_setup_runstate_info(cpu);
	xen_setup_timer(cpu);
	/*
	 * xen_setup_timer(cpu) - snprintf is bad in atomic context. Hence
	 * doing it xen_hvm_cpu_notify (which gets called by smp_init during
	 * early bootup and also during CPU hotplug events).
	 */
	xen_setup_cpu_clockevents();
}

Loading