aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-05-11 19:19:30 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-05-11 19:19:30 -0400
commit607eeb0b836aa24a6972a460a213c4f87902d403 (patch)
treea3435442118d31e9a9e538333df205c6489c65de
parent4c4445013f792f82855079ac377bf5d75af4581c (diff)
parent7c86617dde0015112de566a4619a9b06871580c1 (diff)
Merge tag 'stable/for-linus-3.10-rc0-tag-two' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
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.
-rw-r--r--arch/x86/pci/xen.c5
-rw-r--r--arch/x86/xen/enlighten.c50
-rw-r--r--arch/x86/xen/spinlock.c2
-rw-r--r--drivers/xen/Kconfig2
-rw-r--r--drivers/xen/events.c3
5 files changed, 55 insertions, 7 deletions
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 4a9be6ddf054..48e8461057ba 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -295,11 +295,10 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
295 int pos; 295 int pos;
296 u32 table_offset, bir; 296 u32 table_offset, bir;
297 297
298 pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); 298 pos = dev->msix_cap;
299
300 pci_read_config_dword(dev, pos + PCI_MSIX_TABLE, 299 pci_read_config_dword(dev, pos + PCI_MSIX_TABLE,
301 &table_offset); 300 &table_offset);
302 bir = (u8)(table_offset & PCI_MSIX_FLAGS_BIRMASK); 301 bir = (u8)(table_offset & PCI_MSIX_TABLE_BIR);
303 302
304 map_irq.table_base = pci_resource_start(dev, bir); 303 map_irq.table_base = pci_resource_start(dev, bir);
305 map_irq.entry_nr = msidesc->msi_attrib.entry_nr; 304 map_irq.entry_nr = msidesc->msi_attrib.entry_nr;
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 53d4f680c9b5..a492be2635ac 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -85,7 +85,29 @@
85 85
86EXPORT_SYMBOL_GPL(hypercall_page); 86EXPORT_SYMBOL_GPL(hypercall_page);
87 87
88/*
89 * Pointer to the xen_vcpu_info structure or
90 * &HYPERVISOR_shared_info->vcpu_info[cpu]. See xen_hvm_init_shared_info
91 * and xen_vcpu_setup for details. By default it points to share_info->vcpu_info
92 * but if the hypervisor supports VCPUOP_register_vcpu_info then it can point
93 * to xen_vcpu_info. The pointer is used in __xen_evtchn_do_upcall to
94 * acknowledge pending events.
95 * Also more subtly it is used by the patched version of irq enable/disable
96 * e.g. xen_irq_enable_direct and xen_iret in PV mode.
97 *
98 * The desire to be able to do those mask/unmask operations as a single
99 * instruction by using the per-cpu offset held in %gs is the real reason
100 * vcpu info is in a per-cpu pointer and the original reason for this
101 * hypercall.
102 *
103 */
88DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); 104DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
105
106/*
107 * Per CPU pages used if hypervisor supports VCPUOP_register_vcpu_info
108 * hypercall. This can be used both in PV and PVHVM mode. The structure
109 * overrides the default per_cpu(xen_vcpu, cpu) value.
110 */
89DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); 111DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
90 112
91enum xen_domain_type xen_domain_type = XEN_NATIVE; 113enum xen_domain_type xen_domain_type = XEN_NATIVE;
@@ -157,6 +179,21 @@ static void xen_vcpu_setup(int cpu)
157 179
158 BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info); 180 BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
159 181
182 /*
183 * This path is called twice on PVHVM - first during bootup via
184 * smp_init -> xen_hvm_cpu_notify, and then if the VCPU is being
185 * hotplugged: cpu_up -> xen_hvm_cpu_notify.
186 * As we can only do the VCPUOP_register_vcpu_info once lets
187 * not over-write its result.
188 *
189 * For PV it is called during restore (xen_vcpu_restore) and bootup
190 * (xen_setup_vcpu_info_placement). The hotplug mechanism does not
191 * use this function.
192 */
193 if (xen_hvm_domain()) {
194 if (per_cpu(xen_vcpu, cpu) == &per_cpu(xen_vcpu_info, cpu))
195 return;
196 }
160 if (cpu < MAX_VIRT_CPUS) 197 if (cpu < MAX_VIRT_CPUS)
161 per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 198 per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
162 199
@@ -172,7 +209,12 @@ static void xen_vcpu_setup(int cpu)
172 209
173 /* Check to see if the hypervisor will put the vcpu_info 210 /* Check to see if the hypervisor will put the vcpu_info
174 structure where we want it, which allows direct access via 211 structure where we want it, which allows direct access via
175 a percpu-variable. */ 212 a percpu-variable.
213 N.B. This hypercall can _only_ be called once per CPU. Subsequent
214 calls will error out with -EINVAL. This is due to the fact that
215 hypervisor has no unregister variant and this hypercall does not
216 allow to over-write info.mfn and info.offset.
217 */
176 err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); 218 err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info);
177 219
178 if (err) { 220 if (err) {
@@ -387,6 +429,9 @@ static void __init xen_init_cpuid_mask(void)
387 cpuid_leaf1_edx_mask &= 429 cpuid_leaf1_edx_mask &=
388 ~((1 << X86_FEATURE_APIC) | /* disable local APIC */ 430 ~((1 << X86_FEATURE_APIC) | /* disable local APIC */
389 (1 << X86_FEATURE_ACPI)); /* disable ACPI */ 431 (1 << X86_FEATURE_ACPI)); /* disable ACPI */
432
433 cpuid_leaf1_ecx_mask &= ~(1 << (X86_FEATURE_X2APIC % 32));
434
390 ax = 1; 435 ax = 1;
391 cx = 0; 436 cx = 0;
392 xen_cpuid(&ax, &bx, &cx, &dx); 437 xen_cpuid(&ax, &bx, &cx, &dx);
@@ -1603,6 +1648,9 @@ void __ref xen_hvm_init_shared_info(void)
1603 * online but xen_hvm_init_shared_info is run at resume time too and 1648 * online but xen_hvm_init_shared_info is run at resume time too and
1604 * in that case multiple vcpus might be online. */ 1649 * in that case multiple vcpus might be online. */
1605 for_each_online_cpu(cpu) { 1650 for_each_online_cpu(cpu) {
1651 /* Leave it to be NULL. */
1652 if (cpu >= MAX_VIRT_CPUS)
1653 continue;
1606 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 1654 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
1607 } 1655 }
1608} 1656}
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 8b54603ce816..3002ec1bb71a 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -364,7 +364,7 @@ void __cpuinit xen_init_lock_cpu(int cpu)
364 int irq; 364 int irq;
365 const char *name; 365 const char *name;
366 366
367 WARN(per_cpu(lock_kicker_irq, cpu) > 0, "spinlock on CPU%d exists on IRQ%d!\n", 367 WARN(per_cpu(lock_kicker_irq, cpu) >= 0, "spinlock on CPU%d exists on IRQ%d!\n",
368 cpu, per_cpu(lock_kicker_irq, cpu)); 368 cpu, per_cpu(lock_kicker_irq, cpu));
369 369
370 /* 370 /*
diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig
index dd4d9cb86243..f03bf501527f 100644
--- a/drivers/xen/Kconfig
+++ b/drivers/xen/Kconfig
@@ -141,7 +141,7 @@ config XEN_GRANT_DEV_ALLOC
141 141
142config SWIOTLB_XEN 142config SWIOTLB_XEN
143 def_bool y 143 def_bool y
144 depends on PCI 144 depends on PCI && X86
145 select SWIOTLB 145 select SWIOTLB
146 146
147config XEN_TMEM 147config XEN_TMEM
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index d8cc8127f19c..6a6bbe4ede92 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -167,6 +167,8 @@ static void xen_irq_info_common_init(struct irq_info *info,
167 info->cpu = cpu; 167 info->cpu = cpu;
168 168
169 evtchn_to_irq[evtchn] = irq; 169 evtchn_to_irq[evtchn] = irq;
170
171 irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN);
170} 172}
171 173
172static void xen_irq_info_evtchn_init(unsigned irq, 174static void xen_irq_info_evtchn_init(unsigned irq,
@@ -874,7 +876,6 @@ int bind_evtchn_to_irq(unsigned int evtchn)
874 struct irq_info *info = info_for_irq(irq); 876 struct irq_info *info = info_for_irq(irq);
875 WARN_ON(info == NULL || info->type != IRQT_EVTCHN); 877 WARN_ON(info == NULL || info->type != IRQT_EVTCHN);
876 } 878 }
877 irq_clear_status_flags(irq, IRQ_NOREQUEST|IRQ_NOAUTOEN);
878 879
879out: 880out:
880 mutex_unlock(&irq_mapping_update_lock); 881 mutex_unlock(&irq_mapping_update_lock);