diff options
| -rw-r--r-- | arch/x86/xen/enlighten.c | 75 | ||||
| -rw-r--r-- | arch/x86/xen/suspend.c | 2 | ||||
| -rw-r--r-- | arch/x86/xen/xen-ops.h | 2 |
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 | ||
| 1498 | void __ref xen_hvm_init_shared_info(void) | 1498 | #ifdef CONFIG_XEN_PVHVM |
| 1499 | #define HVM_SHARED_INFO_ADDR 0xFE700000UL | ||
| 1500 | static struct shared_info *xen_hvm_shared_info; | ||
| 1501 | static unsigned long xen_hvm_sip_phys; | ||
| 1502 | static int xen_major, xen_minor; | ||
| 1503 | |||
| 1504 | static 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 | } |
| 1516 | static 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 */ | ||
| 1532 | void 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. */ | ||
| 1543 | static 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 | ||
| 1530 | static void __init init_hvm_pv_info(void) | 1558 | static 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 | ||
| 1591 | static bool __init xen_hvm_platform(void) | 1612 | static 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); | |||
| 40 | void xen_vcpu_restore(void); | 40 | void xen_vcpu_restore(void); |
| 41 | 41 | ||
| 42 | void xen_callback_vector(void); | 42 | void xen_callback_vector(void); |
| 43 | void xen_hvm_init_shared_info(void); | 43 | void xen_hvm_resume_shared_info(void); |
| 44 | void xen_unplug_emulated_devices(void); | 44 | void xen_unplug_emulated_devices(void); |
| 45 | 45 | ||
| 46 | void __init xen_build_dynamic_phys_to_machine(void); | 46 | void __init xen_build_dynamic_phys_to_machine(void); |
