diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-11 19:19:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-11 19:19:30 -0400 |
commit | 607eeb0b836aa24a6972a460a213c4f87902d403 (patch) | |
tree | a3435442118d31e9a9e538333df205c6489c65de | |
parent | 4c4445013f792f82855079ac377bf5d75af4581c (diff) | |
parent | 7c86617dde0015112de566a4619a9b06871580c1 (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.c | 5 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 50 | ||||
-rw-r--r-- | arch/x86/xen/spinlock.c | 2 | ||||
-rw-r--r-- | drivers/xen/Kconfig | 2 | ||||
-rw-r--r-- | drivers/xen/events.c | 3 |
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 | ||
86 | EXPORT_SYMBOL_GPL(hypercall_page); | 86 | EXPORT_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 | */ | ||
88 | DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu); | 104 | DEFINE_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 | */ | ||
89 | DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); | 111 | DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); |
90 | 112 | ||
91 | enum xen_domain_type xen_domain_type = XEN_NATIVE; | 113 | enum 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 | ||
142 | config SWIOTLB_XEN | 142 | config 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 | ||
147 | config XEN_TMEM | 147 | config 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 | ||
172 | static void xen_irq_info_evtchn_init(unsigned irq, | 174 | static 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 | ||
879 | out: | 880 | out: |
880 | mutex_unlock(&irq_mapping_update_lock); | 881 | mutex_unlock(&irq_mapping_update_lock); |