aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/enlighten.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-07-27 14:35:37 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-07-27 14:35:37 -0400
commit08fd8c17686c6b09fa410a26d516548dd80ff147 (patch)
tree0d8c17e70a94518a301e85fc7b23fbc09311068c /arch/x86/xen/enlighten.c
parente831101a73fbc8339ef1d1909dad3ef64f089e70 (diff)
parentd34c30cc1fa80f509500ff192ea6bc7d30671061 (diff)
Merge tag 'for-linus-4.8-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen updates from David Vrabel: "Features and fixes for 4.8-rc0: - ACPI support for guests on ARM platforms. - Generic steal time support for arm and x86. - Support cases where kernel cpu is not Xen VCPU number (e.g., if in-guest kexec is used). - Use the system workqueue instead of a custom workqueue in various places" * tag 'for-linus-4.8-rc0-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: (47 commits) xen: add static initialization of steal_clock op to xen_time_ops xen/pvhvm: run xen_vcpu_setup() for the boot CPU xen/evtchn: use xen_vcpu_id mapping xen/events: fifo: use xen_vcpu_id mapping xen/events: use xen_vcpu_id mapping in events_base x86/xen: use xen_vcpu_id mapping when pointing vcpu_info to shared_info x86/xen: use xen_vcpu_id mapping for HYPERVISOR_vcpu_op xen: introduce xen_vcpu_id mapping x86/acpi: store ACPI ids from MADT for future usage x86/xen: update cpuid.h from Xen-4.7 xen/evtchn: add IOCTL_EVTCHN_RESTRICT xen-blkback: really don't leak mode property xen-blkback: constify instance of "struct attribute_group" xen-blkfront: prefer xenbus_scanf() over xenbus_gather() xen-blkback: prefer xenbus_scanf() over xenbus_gather() xen: support runqueue steal time on xen arm/xen: add support for vm_assist hypercall xen: update xen headers xen-pciback: drop superfluous variables xen-pciback: short-circuit read path used for merging write values ...
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r--arch/x86/xen/enlighten.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 0f87db2cc6a8..69b4b6d29738 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -59,6 +59,7 @@
59#include <asm/xen/pci.h> 59#include <asm/xen/pci.h>
60#include <asm/xen/hypercall.h> 60#include <asm/xen/hypercall.h>
61#include <asm/xen/hypervisor.h> 61#include <asm/xen/hypervisor.h>
62#include <asm/xen/cpuid.h>
62#include <asm/fixmap.h> 63#include <asm/fixmap.h>
63#include <asm/processor.h> 64#include <asm/processor.h>
64#include <asm/proto.h> 65#include <asm/proto.h>
@@ -118,6 +119,10 @@ DEFINE_PER_CPU(struct vcpu_info *, xen_vcpu);
118 */ 119 */
119DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info); 120DEFINE_PER_CPU(struct vcpu_info, xen_vcpu_info);
120 121
122/* Linux <-> Xen vCPU id mapping */
123DEFINE_PER_CPU(int, xen_vcpu_id) = -1;
124EXPORT_PER_CPU_SYMBOL(xen_vcpu_id);
125
121enum xen_domain_type xen_domain_type = XEN_NATIVE; 126enum xen_domain_type xen_domain_type = XEN_NATIVE;
122EXPORT_SYMBOL_GPL(xen_domain_type); 127EXPORT_SYMBOL_GPL(xen_domain_type);
123 128
@@ -179,7 +184,7 @@ static void clamp_max_cpus(void)
179#endif 184#endif
180} 185}
181 186
182static void xen_vcpu_setup(int cpu) 187void xen_vcpu_setup(int cpu)
183{ 188{
184 struct vcpu_register_vcpu_info info; 189 struct vcpu_register_vcpu_info info;
185 int err; 190 int err;
@@ -202,8 +207,9 @@ static void xen_vcpu_setup(int cpu)
202 if (per_cpu(xen_vcpu, cpu) == &per_cpu(xen_vcpu_info, cpu)) 207 if (per_cpu(xen_vcpu, cpu) == &per_cpu(xen_vcpu_info, cpu))
203 return; 208 return;
204 } 209 }
205 if (cpu < MAX_VIRT_CPUS) 210 if (xen_vcpu_nr(cpu) < MAX_VIRT_CPUS)
206 per_cpu(xen_vcpu,cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 211 per_cpu(xen_vcpu, cpu) =
212 &HYPERVISOR_shared_info->vcpu_info[xen_vcpu_nr(cpu)];
207 213
208 if (!have_vcpu_info_placement) { 214 if (!have_vcpu_info_placement) {
209 if (cpu >= MAX_VIRT_CPUS) 215 if (cpu >= MAX_VIRT_CPUS)
@@ -223,7 +229,8 @@ static void xen_vcpu_setup(int cpu)
223 hypervisor has no unregister variant and this hypercall does not 229 hypervisor has no unregister variant and this hypercall does not
224 allow to over-write info.mfn and info.offset. 230 allow to over-write info.mfn and info.offset.
225 */ 231 */
226 err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, cpu, &info); 232 err = HYPERVISOR_vcpu_op(VCPUOP_register_vcpu_info, xen_vcpu_nr(cpu),
233 &info);
227 234
228 if (err) { 235 if (err) {
229 printk(KERN_DEBUG "register_vcpu_info failed: err=%d\n", err); 236 printk(KERN_DEBUG "register_vcpu_info failed: err=%d\n", err);
@@ -247,10 +254,11 @@ void xen_vcpu_restore(void)
247 254
248 for_each_possible_cpu(cpu) { 255 for_each_possible_cpu(cpu) {
249 bool other_cpu = (cpu != smp_processor_id()); 256 bool other_cpu = (cpu != smp_processor_id());
250 bool is_up = HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL); 257 bool is_up = HYPERVISOR_vcpu_op(VCPUOP_is_up, xen_vcpu_nr(cpu),
258 NULL);
251 259
252 if (other_cpu && is_up && 260 if (other_cpu && is_up &&
253 HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) 261 HYPERVISOR_vcpu_op(VCPUOP_down, xen_vcpu_nr(cpu), NULL))
254 BUG(); 262 BUG();
255 263
256 xen_setup_runstate_info(cpu); 264 xen_setup_runstate_info(cpu);
@@ -259,7 +267,7 @@ void xen_vcpu_restore(void)
259 xen_vcpu_setup(cpu); 267 xen_vcpu_setup(cpu);
260 268
261 if (other_cpu && is_up && 269 if (other_cpu && is_up &&
262 HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) 270 HYPERVISOR_vcpu_op(VCPUOP_up, xen_vcpu_nr(cpu), NULL))
263 BUG(); 271 BUG();
264 } 272 }
265} 273}
@@ -588,7 +596,7 @@ static void xen_load_gdt(const struct desc_ptr *dtr)
588{ 596{
589 unsigned long va = dtr->address; 597 unsigned long va = dtr->address;
590 unsigned int size = dtr->size + 1; 598 unsigned int size = dtr->size + 1;
591 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; 599 unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE);
592 unsigned long frames[pages]; 600 unsigned long frames[pages];
593 int f; 601 int f;
594 602
@@ -637,7 +645,7 @@ static void __init xen_load_gdt_boot(const struct desc_ptr *dtr)
637{ 645{
638 unsigned long va = dtr->address; 646 unsigned long va = dtr->address;
639 unsigned int size = dtr->size + 1; 647 unsigned int size = dtr->size + 1;
640 unsigned pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; 648 unsigned pages = DIV_ROUND_UP(size, PAGE_SIZE);
641 unsigned long frames[pages]; 649 unsigned long frames[pages];
642 int f; 650 int f;
643 651
@@ -1135,8 +1143,11 @@ void xen_setup_vcpu_info_placement(void)
1135{ 1143{
1136 int cpu; 1144 int cpu;
1137 1145
1138 for_each_possible_cpu(cpu) 1146 for_each_possible_cpu(cpu) {
1147 /* Set up direct vCPU id mapping for PV guests. */
1148 per_cpu(xen_vcpu_id, cpu) = cpu;
1139 xen_vcpu_setup(cpu); 1149 xen_vcpu_setup(cpu);
1150 }
1140 1151
1141 /* xen_vcpu_setup managed to place the vcpu_info within the 1152 /* xen_vcpu_setup managed to place the vcpu_info within the
1142 * percpu area for all cpus, so make use of it. Note that for 1153 * percpu area for all cpus, so make use of it. Note that for
@@ -1727,6 +1738,9 @@ asmlinkage __visible void __init xen_start_kernel(void)
1727#endif 1738#endif
1728 xen_raw_console_write("about to get started...\n"); 1739 xen_raw_console_write("about to get started...\n");
1729 1740
1741 /* Let's presume PV guests always boot on vCPU with id 0. */
1742 per_cpu(xen_vcpu_id, 0) = 0;
1743
1730 xen_setup_runstate_info(0); 1744 xen_setup_runstate_info(0);
1731 1745
1732 xen_efi_init(); 1746 xen_efi_init();
@@ -1768,9 +1782,10 @@ void __ref xen_hvm_init_shared_info(void)
1768 * in that case multiple vcpus might be online. */ 1782 * in that case multiple vcpus might be online. */
1769 for_each_online_cpu(cpu) { 1783 for_each_online_cpu(cpu) {
1770 /* Leave it to be NULL. */ 1784 /* Leave it to be NULL. */
1771 if (cpu >= MAX_VIRT_CPUS) 1785 if (xen_vcpu_nr(cpu) >= MAX_VIRT_CPUS)
1772 continue; 1786 continue;
1773 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 1787 per_cpu(xen_vcpu, cpu) =
1788 &HYPERVISOR_shared_info->vcpu_info[xen_vcpu_nr(cpu)];
1774 } 1789 }
1775} 1790}
1776 1791
@@ -1795,6 +1810,12 @@ static void __init init_hvm_pv_info(void)
1795 1810
1796 xen_setup_features(); 1811 xen_setup_features();
1797 1812
1813 cpuid(base + 4, &eax, &ebx, &ecx, &edx);
1814 if (eax & XEN_HVM_CPUID_VCPU_ID_PRESENT)
1815 this_cpu_write(xen_vcpu_id, ebx);
1816 else
1817 this_cpu_write(xen_vcpu_id, smp_processor_id());
1818
1798 pv_info.name = "Xen HVM"; 1819 pv_info.name = "Xen HVM";
1799 1820
1800 xen_domain_type = XEN_HVM_DOMAIN; 1821 xen_domain_type = XEN_HVM_DOMAIN;
@@ -1806,6 +1827,10 @@ static int xen_hvm_cpu_notify(struct notifier_block *self, unsigned long action,
1806 int cpu = (long)hcpu; 1827 int cpu = (long)hcpu;
1807 switch (action) { 1828 switch (action) {
1808 case CPU_UP_PREPARE: 1829 case CPU_UP_PREPARE:
1830 if (cpu_acpi_id(cpu) != U32_MAX)
1831 per_cpu(xen_vcpu_id, cpu) = cpu_acpi_id(cpu);
1832 else
1833 per_cpu(xen_vcpu_id, cpu) = cpu;
1809 xen_vcpu_setup(cpu); 1834 xen_vcpu_setup(cpu);
1810 if (xen_have_vector_callback) { 1835 if (xen_have_vector_callback) {
1811 if (xen_feature(XENFEAT_hvm_safe_pvclock)) 1836 if (xen_feature(XENFEAT_hvm_safe_pvclock))