aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/xen/enlighten.c75
-rw-r--r--arch/x86/xen/suspend.c2
-rw-r--r--arch/x86/xen/xen-ops.h2
3 files changed, 55 insertions, 24 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 586d83812b67..a90c3bb58bed 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1495,51 +1495,72 @@ asmlinkage void __init xen_start_kernel(void)
1495#endif 1495#endif
1496} 1496}
1497 1497
1498void __ref xen_hvm_init_shared_info(void) 1498#ifdef CONFIG_XEN_PVHVM
1499#define HVM_SHARED_INFO_ADDR 0xFE700000UL
1500static struct shared_info *xen_hvm_shared_info;
1501static unsigned long xen_hvm_sip_phys;
1502static int xen_major, xen_minor;
1503
1504static void xen_hvm_connect_shared_info(unsigned long pfn)
1499{ 1505{
1500 int cpu;
1501 struct xen_add_to_physmap xatp; 1506 struct xen_add_to_physmap xatp;
1502 static struct shared_info *shared_info_page = 0;
1503 1507
1504 if (!shared_info_page)
1505 shared_info_page = (struct shared_info *)
1506 extend_brk(PAGE_SIZE, PAGE_SIZE);
1507 xatp.domid = DOMID_SELF; 1508 xatp.domid = DOMID_SELF;
1508 xatp.idx = 0; 1509 xatp.idx = 0;
1509 xatp.space = XENMAPSPACE_shared_info; 1510 xatp.space = XENMAPSPACE_shared_info;
1510 xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; 1511 xatp.gpfn = pfn;
1511 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) 1512 if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
1512 BUG(); 1513 BUG();
1513 1514
1514 HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; 1515}
1516static void __init xen_hvm_set_shared_info(struct shared_info *sip)
1517{
1518 int cpu;
1519
1520 HYPERVISOR_shared_info = sip;
1515 1521
1516 /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info 1522 /* 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 1523 * page, we use it in the event channel upcall and in some pvclock
1518 * related functions. We don't need the vcpu_info placement 1524 * 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 1525 * optimizations because we don't use any pv_mmu or pv_irq op on
1520 * HVM. 1526 * HVM. */
1521 * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is 1527 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]; 1528 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
1529}
1530
1531/* Reconnect the shared_info pfn to a (new) mfn */
1532void xen_hvm_resume_shared_info(void)
1533{
1534 xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
1535}
1536
1537/* Xen tools prior to Xen 4 do not provide a E820_Reserved area for guest usage.
1538 * On these old tools the shared info page will be placed in E820_Ram.
1539 * Xen 4 provides a E820_Reserved area at 0xFC000000, and this code expects
1540 * that nothing is mapped up to HVM_SHARED_INFO_ADDR.
1541 * Xen 4.3+ provides an explicit 1MB area at HVM_SHARED_INFO_ADDR which is used
1542 * here for the shared info page. */
1543static void __init xen_hvm_init_shared_info(void)
1544{
1545 if (xen_major < 4) {
1546 xen_hvm_shared_info = extend_brk(PAGE_SIZE, PAGE_SIZE);
1547 xen_hvm_sip_phys = __pa(xen_hvm_shared_info);
1548 } else {
1549 xen_hvm_sip_phys = HVM_SHARED_INFO_ADDR;
1550 set_fixmap(FIX_PARAVIRT_BOOTMAP, xen_hvm_sip_phys);
1551 xen_hvm_shared_info =
1552 (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
1526 } 1553 }
1554 xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT);
1555 xen_hvm_set_shared_info(xen_hvm_shared_info);
1527} 1556}
1528 1557
1529#ifdef CONFIG_XEN_PVHVM
1530static void __init init_hvm_pv_info(void) 1558static void __init init_hvm_pv_info(void)
1531{ 1559{
1532 int major, minor;
1533 uint32_t eax, ebx, ecx, edx, pages, msr, base; 1560 uint32_t eax, ebx, ecx, edx, pages, msr, base;
1534 u64 pfn; 1561 u64 pfn;
1535 1562
1536 base = xen_cpuid_base(); 1563 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); 1564 cpuid(base + 2, &pages, &msr, &ecx, &edx);
1544 1565
1545 pfn = __pa(hypercall_page); 1566 pfn = __pa(hypercall_page);
@@ -1590,12 +1611,22 @@ static void __init xen_hvm_guest_init(void)
1590 1611
1591static bool __init xen_hvm_platform(void) 1612static bool __init xen_hvm_platform(void)
1592{ 1613{
1614 uint32_t eax, ebx, ecx, edx, base;
1615
1593 if (xen_pv_domain()) 1616 if (xen_pv_domain())
1594 return false; 1617 return false;
1595 1618
1596 if (!xen_cpuid_base()) 1619 base = xen_cpuid_base();
1620 if (!base)
1597 return false; 1621 return false;
1598 1622
1623 cpuid(base + 1, &eax, &ebx, &ecx, &edx);
1624
1625 xen_major = eax >> 16;
1626 xen_minor = eax & 0xffff;
1627
1628 printk(KERN_INFO "Xen version %d.%d.\n", xen_major, xen_minor);
1629
1599 return true; 1630 return true;
1600} 1631}
1601 1632
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);