]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge tag 'stable/for-linus-3.10-rc0-tag-two' of git://git.kernel.org/pub/scm/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 May 2013 23:19:30 +0000 (16:19 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 11 May 2013 23:19:30 +0000 (16:19 -0700)
Pull Xen bug-fixes from Konrad Rzeszutek Wilk:
 - More fixes in the vCPU PVHVM hotplug path.
 - Add more documentation.
 - Fix various ARM related issues in the Xen generic drivers.
 - Updates in the xen-pciback driver per Bjorn's updates.
 - Mask the x2APIC feature for PV guests.

* tag 'stable/for-linus-3.10-rc0-tag-two' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
  xen/pci: Used cached MSI-X capability offset
  xen/pci: Use PCI_MSIX_TABLE_BIR, not PCI_MSIX_FLAGS_BIRMASK
  xen: clear IRQ_NOAUTOEN and IRQ_NOREQUEST
  xen: mask x2APIC feature in PV
  xen: SWIOTLB is only used on x86
  xen/spinlock: Fix check from greater than to be also be greater or equal to.
  xen/smp/pvhvm: Don't point per_cpu(xen_vpcu, 33 and larger) to shared_info
  xen/vcpu: Document the xen_vcpu_info and xen_vcpu
  xen/vcpu/pvhvm: Fix vcpu hotplugging hanging.

arch/x86/pci/xen.c
arch/x86/xen/enlighten.c
arch/x86/xen/spinlock.c
drivers/xen/Kconfig
drivers/xen/events.c

index 4a9be6ddf05437e66ab8c94862a9b3e8a30e4373..48e8461057ba9346442aa5c72d6772b190dcf4c9 100644 (file)
@@ -295,11 +295,10 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
                        int pos;
                        u32 table_offset, bir;
 
-                       pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);
-
+                       pos = dev->msix_cap;
                        pci_read_config_dword(dev, pos + PCI_MSIX_TABLE,
                                              &table_offset);
-                       bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK);
+                       bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR);
 
                        map_irq.table_base = pci_resource_start(dev, bir);
                        map_irq.entry_nr = msidesc->msi_attrib.entry_nr;
index 53d4f680c9b59f498d41148325cd5a96ef1723e3..a492be2635ac048a527d856b796431ccac72d9fd 100644 (file)
 
 EXPORT_SYMBOL_GPL(hypercall_page);
 
+/*
+ * Pointer to the xen_vcpu_info structure or
+ * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info
+ * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info
+ * but if the hypervisor supports VCPUOP_register_vcpu_info then it can point
+ * to xen_vcpu_info. The pointer is used in __xen_evtchn_do_upcall to
+ * acknowledge pending events.
+ * Also more subtly it is used by the patched version of irq enable/disable
+ * e.g. xen_irq_enable_direct and xen_iret in PV mode.
+ *
+ * The desire to be able to do those mask/unmask operations as a single
+ * instruction by using the per-cpu offset held in %gs is the real reason
+ * vcpu info is in a per-cpu pointer and the original reason for this
+ * hypercall.
+ *
+ */
 DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
+
+/*
+ * Per CPU pages used if hypervisor supports VCPUOP_register_vcpu_info
+ * hypercall. This can be used both in PV and PVHVM mode. The structure
+ * overrides the default per_cpu(xen_vcpu, cpu) value.
+ */
 DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
 
 enum xen_domain_type xen_domain_type = XEN_NATIVE;
@@ -157,6 +179,21 @@ static void xen_vcpu_setup(int cpu)
 
        BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
 
+       /*
+        * This path is called twice on PVHVM - first during bootup via
+        * smp_init -> xen_hvm_cpu_notify, and then if the VCPU is being
+        * hotplugged: cpu_up -> xen_hvm_cpu_notify.
+        * As we can only do the VCPUOP_register_vcpu_info once lets
+        * not over-write its result.
+        *
+        * For PV it is called during restore (xen_vcpu_restore) and bootup
+        * (xen_setup_vcpu_info_placement). The hotplug mechanism does not
+        * use this function.
+        */
+       if (xen_hvm_domain()) {
+               if (per_cpu(xen_vcpu, cpu) == &per_cpu(xen_vcpu_info, cpu))
+                       return;
+       }
        if (cpu < MAX_VIRT_CPUS)
                per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
 
@@ -172,7 +209,12 @@ static void xen_vcpu_setup(int cpu)
 
        /* Check to see if the hypervisor will put the vcpu_info
           structure where we want it, which allows direct access via
-          a percpu-variable. */
+          a percpu-variable.
+          N.B. This hypercall can _only_ be called once per CPU. Subsequent
+          calls will error out with -EINVAL. This is due to the fact that
+          hypervisor has no unregister variant and this hypercall does not
+          allow to over-write info.mfn and info.offset.
+        */
        err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
 
        if (err) {
@@ -387,6 +429,9 @@ static void __init xen_init_cpuid_mask(void)
                cpuid_leaf1_edx_mask &=
                        ~((1 << X86_FEATURE_APIC) |  /* disable local APIC */
                          (1 << X86_FEATURE_ACPI));  /* disable ACPI */
+
+       cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_X2APIC % 32));
+
        ax = 1;
        cx = 0;
        xen_cpuid(&ax, &bx, &cx, &dx);
@@ -1603,6 +1648,9 @@ void __ref xen_hvm_init_shared_info(void)
         * online but xen_hvm_init_shared_info is run at resume time too and
         * in that case multiple vcpus might be online. */
        for_each_online_cpu(cpu) {
+               /* Leave it to be NULL. */
+               if (cpu >= MAX_VIRT_CPUS)
+                       continue;
                per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
        }
 }
index 8b54603ce81613fee6783a6d3869b0021878feb4..3002ec1bb71a27d193ce4b1e041f8b3a3c5b49fa 100644 (file)
@@ -364,7 +364,7 @@ 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",
+       WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n",
             cpu, per_cpu(lock_kicker_irq, cpu));
 
        /*
index dd4d9cb862432b4ce6715aba3164a53ffaaa87a5..f03bf501527f64785a3fbbec39963f979d70ad8a 100644 (file)
@@ -141,7 +141,7 @@ config XEN_GRANT_DEV_ALLOC
 
 config SWIOTLB_XEN
        def_bool y
-       depends on PCI
+       depends on PCI && X86
        select SWIOTLB
 
 config XEN_TMEM
index d8cc8127f19c18f9b6a4ea9f937015363b912bd8..6a6bbe4ede92c67afe4c88efd105839f14b3a240 100644 (file)
@@ -167,6 +167,8 @@ static void xen_irq_info_common_init(struct irq_info *info,
        info->cpu = cpu;
 
        evtchn_to_irq[evtchn] = irq;
+
+       irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN);
 }
 
 static void xen_irq_info_evtchn_init(unsigned irq,
@@ -874,7 +876,6 @@ int bind_evtchn_to_irq(unsigned int evtchn)
                struct irq_info *info = info_for_irq(irq);
                WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
        }
-       irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN);
 
 out:
        mutex_unlock(&irq_mapping_update_lock);