aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2013-01-29 17:59:09 -0500
committerH. Peter Anvin <hpa@linux.intel.com>2013-01-29 18:10:15 -0500
commitde65d816aa44f9ddd79861ae21d75010cc1fd003 (patch)
tree04a637a43b2e52a733d0dcb7595a47057571e7da /arch/x86/xen
parent9710f581bb4c35589ac046b0cfc0deb7f369fc85 (diff)
parent5dcd14ecd41ea2b3ae3295a9b30d98769d52165f (diff)
Merge remote-tracking branch 'origin/x86/boot' into x86/mm2
Coming patches to x86/mm2 require the changes and advanced baseline in x86/boot. Resolved Conflicts: arch/x86/kernel/setup.c mm/nobootmem.c Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Diffstat (limited to 'arch/x86/xen')
-rw-r--r--arch/x86/xen/Kconfig3
-rw-r--r--arch/x86/xen/enlighten.c109
-rw-r--r--arch/x86/xen/mmu.c17
-rw-r--r--arch/x86/xen/smp.c9
-rw-r--r--arch/x86/xen/suspend.c2
-rw-r--r--arch/x86/xen/xen-ops.h2
6 files changed, 101 insertions, 41 deletions
diff --git a/arch/x86/xen/Kconfig b/arch/x86/xen/Kconfig
index fdce49c7aff6..131dacd2748a 100644
--- a/arch/x86/xen/Kconfig
+++ b/arch/x86/xen/Kconfig
@@ -6,8 +6,9 @@ config XEN
6 bool "Xen guest support" 6 bool "Xen guest support"
7 select PARAVIRT 7 select PARAVIRT
8 select PARAVIRT_CLOCK 8 select PARAVIRT_CLOCK
9 select XEN_HAVE_PVMMU
9 depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS) 10 depends on X86_64 || (X86_32 && X86_PAE && !X86_VISWS)
10 depends on X86_CMPXCHG && X86_TSC 11 depends on X86_TSC
11 help 12 help
12 This is the Linux Xen port. Enabling this will allow the 13 This is the Linux Xen port. Enabling this will allow the
13 kernel to boot in a paravirtualized environment under the 14 kernel to boot in a paravirtualized environment under the
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 586d83812b67..138e5667409a 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -193,10 +193,11 @@ void xen_vcpu_restore(void)
193{ 193{
194 int cpu; 194 int cpu;
195 195
196 for_each_online_cpu(cpu) { 196 for_each_possible_cpu(cpu) {
197 bool other_cpu = (cpu != smp_processor_id()); 197 bool other_cpu = (cpu != smp_processor_id());
198 bool is_up = HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL);
198 199
199 if (other_cpu && 200 if (other_cpu && is_up &&
200 HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL)) 201 HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL))
201 BUG(); 202 BUG();
202 203
@@ -205,7 +206,7 @@ void xen_vcpu_restore(void)
205 if (have_vcpu_info_placement) 206 if (have_vcpu_info_placement)
206 xen_vcpu_setup(cpu); 207 xen_vcpu_setup(cpu);
207 208
208 if (other_cpu && 209 if (other_cpu && is_up &&
209 HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL)) 210 HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL))
210 BUG(); 211 BUG();
211 } 212 }
@@ -223,6 +224,21 @@ static void __init xen_banner(void)
223 version >> 16, version & 0xffff, extra.extraversion, 224 version >> 16, version & 0xffff, extra.extraversion,
224 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : ""); 225 xen_feature(XENFEAT_mmu_pt_update_preserve_ad) ? " (preserve-AD)" : "");
225} 226}
227/* Check if running on Xen version (major, minor) or later */
228bool
229xen_running_on_version_or_later(unsigned int major, unsigned int minor)
230{
231 unsigned int version;
232
233 if (!xen_domain())
234 return false;
235
236 version = HYPERVISOR_xen_version(XENVER_version, NULL);
237 if ((((version >> 16) == major) && ((version & 0xffff) >= minor)) ||
238 ((version >> 16) > major))
239 return true;
240 return false;
241}
226 242
227#define CPUID_THERM_POWER_LEAF 6 243#define CPUID_THERM_POWER_LEAF 6
228#define APERFMPERF_PRESENT 0 244#define APERFMPERF_PRESENT 0
@@ -287,8 +303,7 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
287 303
288static bool __init xen_check_mwait(void) 304static bool __init xen_check_mwait(void)
289{ 305{
290#if defined(CONFIG_ACPI) && !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR) && \ 306#ifdef CONFIG_ACPI
291 !defined(CONFIG_ACPI_PROCESSOR_AGGREGATOR_MODULE)
292 struct xen_platform_op op = { 307 struct xen_platform_op op = {
293 .cmd = XENPF_set_processor_pminfo, 308 .cmd = XENPF_set_processor_pminfo,
294 .u.set_pminfo.id = -1, 309 .u.set_pminfo.id = -1,
@@ -309,6 +324,13 @@ static bool __init xen_check_mwait(void)
309 if (!xen_initial_domain()) 324 if (!xen_initial_domain())
310 return false; 325 return false;
311 326
327 /*
328 * When running under platform earlier than Xen4.2, do not expose
329 * mwait, to avoid the risk of loading native acpi pad driver
330 */
331 if (!xen_running_on_version_or_later(4, 2))
332 return false;
333
312 ax = 1; 334 ax = 1;
313 cx = 0; 335 cx = 0;
314 336
@@ -1495,51 +1517,72 @@ asmlinkage void __init xen_start_kernel(void)
1495#endif 1517#endif
1496} 1518}
1497 1519
1498void __ref xen_hvm_init_shared_info(void) 1520#ifdef CONFIG_XEN_PVHVM
1521#define HVM_SHARED_INFO_ADDR 0xFE700000UL
1522static struct shared_info *xen_hvm_shared_info;
1523static unsigned long xen_hvm_sip_phys;
1524static int xen_major, xen_minor;
1525
1526static void xen_hvm_connect_shared_info(unsigned long pfn)
1499{ 1527{
1500 int cpu;
1501 struct xen_add_to_physmap xatp; 1528 struct xen_add_to_physmap xatp;
1502 static struct shared_info *shared_info_page = 0;
1503 1529
1504 if (!shared_info_page)
1505 shared_info_page = (struct shared_info *)
1506 extend_brk(PAGE_SIZE, PAGE_SIZE);
1507 xatp.domid = DOMID_SELF; 1530 xatp.domid = DOMID_SELF;
1508 xatp.idx = 0; 1531 xatp.idx = 0;
1509 xatp.space = XENMAPSPACE_shared_info; 1532 xatp.space = XENMAPSPACE_shared_info;
1510 xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; 1533 xatp.gpfn = pfn;
1511 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) 1534 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
1512 BUG(); 1535 BUG();
1513 1536
1514 HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; 1537}
1538static void __init xen_hvm_set_shared_info(struct shared_info *sip)
1539{
1540 int cpu;
1541
1542 HYPERVISOR_shared_info = sip;
1515 1543
1516 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info 1544 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info
1517 * page, we use it in the event channel upcall and in some pvclock 1545 * page, we use it in the event channel upcall and in some pvclock
1518 * related functions. We don't need the vcpu_info placement 1546 * related functions. We don't need the vcpu_info placement
1519 * optimizations because we don't use any pv_mmu or pv_irq op on 1547 * optimizations because we don't use any pv_mmu or pv_irq op on
1520 * HVM. 1548 * HVM. */
1521 * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is 1549 for_each_online_cpu(cpu)
1522 * online but xen_hvm_init_shared_info is run at resume time too and
1523 * in that case multiple vcpus might be online. */
1524 for_each_online_cpu(cpu) {
1525 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 1550 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
1551}
1552
1553/* Reconnect the shared_info pfn to a (new) mfn */
1554void xen_hvm_resume_shared_info(void)
1555{
1556 xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
1557}
1558
1559/* Xen tools prior to Xen 4 do not provide a E820_Reserved area for guest usage.
1560 * On these old tools the shared info page will be placed in E820_Ram.
1561 * Xen 4 provides a E820_Reserved area at 0xFC000000, and this code expects
1562 * that nothing is mapped up to HVM_SHARED_INFO_ADDR.
1563 * Xen 4.3+ provides an explicit 1MB area at HVM_SHARED_INFO_ADDR which is used
1564 * here for the shared info page. */
1565static void __init xen_hvm_init_shared_info(void)
1566{
1567 if (xen_major < 4) {
1568 xen_hvm_shared_info = extend_brk(PAGE_SIZE, PAGE_SIZE);
1569 xen_hvm_sip_phys = __pa(xen_hvm_shared_info);
1570 } else {
1571 xen_hvm_sip_phys = HVM_SHARED_INFO_ADDR;
1572 set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_hvm_sip_phys);
1573 xen_hvm_shared_info =
1574 (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
1526 } 1575 }
1576 xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
1577 xen_hvm_set_shared_info(xen_hvm_shared_info);
1527} 1578}
1528 1579
1529#ifdef CONFIG_XEN_PVHVM
1530static void __init init_hvm_pv_info(void) 1580static void __init init_hvm_pv_info(void)
1531{ 1581{
1532 int major, minor; 1582 uint32_t ecx, edx, pages, msr, base;
1533 uint32_t eax, ebx, ecx, edx, pages, msr, base;
1534 u64 pfn; 1583 u64 pfn;
1535 1584
1536 base = xen_cpuid_base(); 1585 base = xen_cpuid_base();
1537 cpuid(base + 1, &eax, &ebx, &ecx, &edx);
1538
1539 major = eax >> 16;
1540 minor = eax & 0xffff;
1541 printk(KERN_INFO "Xen version %d.%d.\n", major, minor);
1542
1543 cpuid(base + 2, &pages, &msr, &ecx, &edx); 1586 cpuid(base + 2, &pages, &msr, &ecx, &edx);
1544 1587
1545 pfn = __pa(hypercall_page); 1588 pfn = __pa(hypercall_page);
@@ -1590,12 +1633,22 @@ static void __init xen_hvm_guest_init(void)
1590 1633
1591static bool __init xen_hvm_platform(void) 1634static bool __init xen_hvm_platform(void)
1592{ 1635{
1636 uint32_t eax, ebx, ecx, edx, base;
1637
1593 if (xen_pv_domain()) 1638 if (xen_pv_domain())
1594 return false; 1639 return false;
1595 1640
1596 if (!xen_cpuid_base()) 1641 base = xen_cpuid_base();
1642 if (!base)
1597 return false; 1643 return false;
1598 1644
1645 cpuid(base + 1, &eax, &ebx, &ecx, &edx);
1646
1647 xen_major = eax >> 16;
1648 xen_minor = eax & 0xffff;
1649
1650 printk(KERN_INFO "Xen version %d.%d.\n", xen_major, xen_minor);
1651
1599 return true; 1652 return true;
1600} 1653}
1601 1654
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index bbb883f58bc4..f5e86eee4e0e 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -2469,8 +2469,10 @@ static int remap_area_mfn_pte_fn(pte_t *ptep, pgtable_t token,
2469 2469
2470int xen_remap_domain_mfn_range(struct vm_area_struct *vma, 2470int xen_remap_domain_mfn_range(struct vm_area_struct *vma,
2471 unsigned long addr, 2471 unsigned long addr,
2472 unsigned long mfn, int nr, 2472 xen_pfn_t mfn, int nr,
2473 pgprot_t prot, unsigned domid) 2473 pgprot_t prot, unsigned domid,
2474 struct page **pages)
2475
2474{ 2476{
2475 struct remap_data rmd; 2477 struct remap_data rmd;
2476 struct mmu_update mmu_update[REMAP_BATCH_SIZE]; 2478 struct mmu_update mmu_update[REMAP_BATCH_SIZE];
@@ -2514,3 +2516,14 @@ out:
2514 return err; 2516 return err;
2515} 2517}
2516EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range); 2518EXPORT_SYMBOL_GPL(xen_remap_domain_mfn_range);
2519
2520/* Returns: 0 success */
2521int xen_unmap_domain_mfn_range(struct vm_area_struct *vma,
2522 int numpgs, struct page **pages)
2523{
2524 if (!pages || !xen_feature(XENFEAT_auto_translated_physmap))
2525 return 0;
2526
2527 return -EINVAL;
2528}
2529EXPORT_SYMBOL_GPL(xen_unmap_domain_mfn_range);
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 353c50f18702..34bc4cee8887 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -254,7 +254,7 @@ static void __init xen_smp_prepare_cpus(unsigned int max_cpus)
254 } 254 }
255 xen_init_lock_cpu(0); 255 xen_init_lock_cpu(0);
256 256
257 smp_store_cpu_info(0); 257 smp_store_boot_cpu_info();
258 cpu_data(0).x86_max_cores = 1; 258 cpu_data(0).x86_max_cores = 1;
259 259
260 for_each_possible_cpu(i) { 260 for_each_possible_cpu(i) {
@@ -432,13 +432,6 @@ static void __cpuinit xen_play_dead(void) /* used only with HOTPLUG_CPU */
432 play_dead_common(); 432 play_dead_common();
433 HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL); 433 HYPERVISOR_vcpu_op(VCPUOP_down, smp_processor_id(), NULL);
434 cpu_bringup(); 434 cpu_bringup();
435 /*
436 * Balance out the preempt calls - as we are running in cpu_idle
437 * loop which has been called at bootup from cpu_bringup_and_idle.
438 * The cpucpu_bringup_and_idle called cpu_bringup which made a
439 * preempt_disable() So this preempt_enable will balance it out.
440 */
441 preempt_enable();
442} 435}
443 436
444#else /* !CONFIG_HOTPLUG_CPU */ 437#else /* !CONFIG_HOTPLUG_CPU */
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c
index 45329c8c226e..ae8a00c39de4 100644
--- a/arch/x86/xen/suspend.c
+++ b/arch/x86/xen/suspend.c
@@ -30,7 +30,7 @@ void xen_arch_hvm_post_suspend(int suspend_cancelled)
30{ 30{
31#ifdef CONFIG_XEN_PVHVM 31#ifdef CONFIG_XEN_PVHVM
32 int cpu; 32 int cpu;
33 xen_hvm_init_shared_info(); 33 xen_hvm_resume_shared_info();
34 xen_callback_vector(); 34 xen_callback_vector();
35 xen_unplug_emulated_devices(); 35 xen_unplug_emulated_devices();
36 if (xen_feature(XENFEAT_hvm_safe_pvclock)) { 36 if (xen_feature(XENFEAT_hvm_safe_pvclock)) {
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index a95b41744ad0..d2e73d19d366 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -40,7 +40,7 @@ void xen_enable_syscall(void);
40void xen_vcpu_restore(void); 40void xen_vcpu_restore(void);
41 41
42void xen_callback_vector(void); 42void xen_callback_vector(void);
43void xen_hvm_init_shared_info(void); 43void xen_hvm_resume_shared_info(void);
44void xen_unplug_emulated_devices(void); 44void xen_unplug_emulated_devices(void);
45 45
46void __init xen_build_dynamic_phys_to_machine(void); 46void __init xen_build_dynamic_phys_to_machine(void);