diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-15 15:12:55 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-15 15:12:55 -0500 |
commit | f741656d646f7a5b56ba86765205b954237e7956 (patch) | |
tree | 8ff5072258e72929ea1ef311d33a765e0aeb35e8 | |
parent | ac89758697195a8155f3861a34f0b41c6e562fcb (diff) | |
parent | e9daff24a266307943457086533041bd971d0ef9 (diff) |
Merge tag 'stable/for-linus-3.8-rc7-tag-two' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
Pull xen fixes from Konrad Rzeszutek Wilk:
"Two fixes:
- A simple bug-fix for redundant NULL check.
- CVE-2013-0228/XSA-42: x86/xen: don't assume %ds is usable in
xen_iret for 32-bit PVOPS
and two reverts:
- Revert the PVonHVM kexec. The patch introduces a regression with
older hypervisor stacks, such as Xen 4.1."
* tag 'stable/for-linus-3.8-rc7-tag-two' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
Revert "xen PVonHVM: use E820_Reserved area for shared_info"
Revert "xen/PVonHVM: fix compile warning in init_hvm_pv_info"
xen: remove redundant NULL check before unregister_and_remove_pcpu().
x86/xen: don't assume %ds is usable in xen_iret for 32-bit PVOPS.
-rw-r--r-- | arch/x86/xen/enlighten.c | 77 | ||||
-rw-r--r-- | arch/x86/xen/suspend.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/xen-asm_32.S | 14 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 2 | ||||
-rw-r--r-- | drivers/xen/pcpu.c | 3 |
5 files changed, 33 insertions, 65 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 138e5667409a..e0140923062f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1517,72 +1517,51 @@ asmlinkage void __init xen_start_kernel(void) | |||
1517 | #endif | 1517 | #endif |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | #ifdef CONFIG_XEN_PVHVM | 1520 | void __ref xen_hvm_init_shared_info(void) |
1521 | #define HVM_SHARED_INFO_ADDR 0xFE700000UL | ||
1522 | static struct shared_info *xen_hvm_shared_info; | ||
1523 | static unsigned long xen_hvm_sip_phys; | ||
1524 | static int xen_major, xen_minor; | ||
1525 | |||
1526 | static void xen_hvm_connect_shared_info(unsigned long pfn) | ||
1527 | { | 1521 | { |
1522 | int cpu; | ||
1528 | struct xen_add_to_physmap xatp; | 1523 | struct xen_add_to_physmap xatp; |
1524 | static struct shared_info *shared_info_page = 0; | ||
1529 | 1525 | ||
1526 | if (!shared_info_page) | ||
1527 | shared_info_page = (struct shared_info *) | ||
1528 | extend_brk(PAGE_SIZE, PAGE_SIZE); | ||
1530 | xatp.domid = DOMID_SELF; | 1529 | xatp.domid = DOMID_SELF; |
1531 | xatp.idx = 0; | 1530 | xatp.idx = 0; |
1532 | xatp.space = XENMAPSPACE_shared_info; | 1531 | xatp.space = XENMAPSPACE_shared_info; |
1533 | xatp.gpfn = pfn; | 1532 | xatp.gpfn = __pa(shared_info_page) >> PAGE_SHIFT; |
1534 | if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) | 1533 | if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp)) |
1535 | BUG(); | 1534 | BUG(); |
1536 | 1535 | ||
1537 | } | 1536 | HYPERVISOR_shared_info = (struct shared_info *)shared_info_page; |
1538 | static void __init xen_hvm_set_shared_info(struct shared_info *sip) | ||
1539 | { | ||
1540 | int cpu; | ||
1541 | |||
1542 | HYPERVISOR_shared_info = sip; | ||
1543 | 1537 | ||
1544 | /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info | 1538 | /* xen_vcpu is a pointer to the vcpu_info struct in the shared_info |
1545 | * page, we use it in the event channel upcall and in some pvclock | 1539 | * page, we use it in the event channel upcall and in some pvclock |
1546 | * related functions. We don't need the vcpu_info placement | 1540 | * related functions. We don't need the vcpu_info placement |
1547 | * optimizations because we don't use any pv_mmu or pv_irq op on | 1541 | * optimizations because we don't use any pv_mmu or pv_irq op on |
1548 | * HVM. */ | 1542 | * HVM. |
1549 | for_each_online_cpu(cpu) | 1543 | * When xen_hvm_init_shared_info is run at boot time only vcpu 0 is |
1544 | * online but xen_hvm_init_shared_info is run at resume time too and | ||
1545 | * in that case multiple vcpus might be online. */ | ||
1546 | for_each_online_cpu(cpu) { | ||
1550 | per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; | 1547 | per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; |
1551 | } | ||
1552 | |||
1553 | /* Reconnect the shared_info pfn to a (new) mfn */ | ||
1554 | void 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. */ | ||
1565 | static 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); | ||
1575 | } | 1548 | } |
1576 | xen_hvm_connect_shared_info(xen_hvm_sip_phys >> PAGE_SHIFT); | ||
1577 | xen_hvm_set_shared_info(xen_hvm_shared_info); | ||
1578 | } | 1549 | } |
1579 | 1550 | ||
1551 | #ifdef CONFIG_XEN_PVHVM | ||
1580 | static void __init init_hvm_pv_info(void) | 1552 | static void __init init_hvm_pv_info(void) |
1581 | { | 1553 | { |
1582 | uint32_t ecx, edx, pages, msr, base; | 1554 | int major, minor; |
1555 | uint32_t eax, ebx, ecx, edx, pages, msr, base; | ||
1583 | u64 pfn; | 1556 | u64 pfn; |
1584 | 1557 | ||
1585 | base = xen_cpuid_base(); | 1558 | base = xen_cpuid_base(); |
1559 | cpuid(base + 1, &eax, &ebx, &ecx, &edx); | ||
1560 | |||
1561 | major = eax >> 16; | ||
1562 | minor = eax & 0xffff; | ||
1563 | printk(KERN_INFO "Xen version %d.%d.\n", major, minor); | ||
1564 | |||
1586 | cpuid(base + 2, &pages, &msr, &ecx, &edx); | 1565 | cpuid(base + 2, &pages, &msr, &ecx, &edx); |
1587 | 1566 | ||
1588 | pfn = __pa(hypercall_page); | 1567 | pfn = __pa(hypercall_page); |
@@ -1633,22 +1612,12 @@ static void __init xen_hvm_guest_init(void) | |||
1633 | 1612 | ||
1634 | static bool __init xen_hvm_platform(void) | 1613 | static bool __init xen_hvm_platform(void) |
1635 | { | 1614 | { |
1636 | uint32_t eax, ebx, ecx, edx, base; | ||
1637 | |||
1638 | if (xen_pv_domain()) | 1615 | if (xen_pv_domain()) |
1639 | return false; | 1616 | return false; |
1640 | 1617 | ||
1641 | base = xen_cpuid_base(); | 1618 | if (!xen_cpuid_base()) |
1642 | if (!base) | ||
1643 | return false; | 1619 | return false; |
1644 | 1620 | ||
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 | |||
1652 | return true; | 1621 | return true; |
1653 | } | 1622 | } |
1654 | 1623 | ||
diff --git a/arch/x86/xen/suspend.c b/arch/x86/xen/suspend.c index ae8a00c39de4..45329c8c226e 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_resume_shared_info(); | 33 | xen_hvm_init_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-asm_32.S b/arch/x86/xen/xen-asm_32.S index f9643fc50de5..33ca6e42a4ca 100644 --- a/arch/x86/xen/xen-asm_32.S +++ b/arch/x86/xen/xen-asm_32.S | |||
@@ -89,11 +89,11 @@ ENTRY(xen_iret) | |||
89 | */ | 89 | */ |
90 | #ifdef CONFIG_SMP | 90 | #ifdef CONFIG_SMP |
91 | GET_THREAD_INFO(%eax) | 91 | GET_THREAD_INFO(%eax) |
92 | movl TI_cpu(%eax), %eax | 92 | movl %ss:TI_cpu(%eax), %eax |
93 | movl __per_cpu_offset(,%eax,4), %eax | 93 | movl %ss:__per_cpu_offset(,%eax,4), %eax |
94 | mov xen_vcpu(%eax), %eax | 94 | mov %ss:xen_vcpu(%eax), %eax |
95 | #else | 95 | #else |
96 | movl xen_vcpu, %eax | 96 | movl %ss:xen_vcpu, %eax |
97 | #endif | 97 | #endif |
98 | 98 | ||
99 | /* check IF state we're restoring */ | 99 | /* check IF state we're restoring */ |
@@ -106,11 +106,11 @@ ENTRY(xen_iret) | |||
106 | * resuming the code, so we don't have to be worried about | 106 | * resuming the code, so we don't have to be worried about |
107 | * being preempted to another CPU. | 107 | * being preempted to another CPU. |
108 | */ | 108 | */ |
109 | setz XEN_vcpu_info_mask(%eax) | 109 | setz %ss:XEN_vcpu_info_mask(%eax) |
110 | xen_iret_start_crit: | 110 | xen_iret_start_crit: |
111 | 111 | ||
112 | /* check for unmasked and pending */ | 112 | /* check for unmasked and pending */ |
113 | cmpw $0x0001, XEN_vcpu_info_pending(%eax) | 113 | cmpw $0x0001, %ss:XEN_vcpu_info_pending(%eax) |
114 | 114 | ||
115 | /* | 115 | /* |
116 | * If there's something pending, mask events again so we can | 116 | * If there's something pending, mask events again so we can |
@@ -118,7 +118,7 @@ xen_iret_start_crit: | |||
118 | * touch XEN_vcpu_info_mask. | 118 | * touch XEN_vcpu_info_mask. |
119 | */ | 119 | */ |
120 | jne 1f | 120 | jne 1f |
121 | movb $1, XEN_vcpu_info_mask(%eax) | 121 | movb $1, %ss:XEN_vcpu_info_mask(%eax) |
122 | 122 | ||
123 | 1: popl %eax | 123 | 1: popl %eax |
124 | 124 | ||
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index d2e73d19d366..a95b41744ad0 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_resume_shared_info(void); | 43 | void xen_hvm_init_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); |
diff --git a/drivers/xen/pcpu.c b/drivers/xen/pcpu.c index 067fcfa1723e..5a27a4599a4a 100644 --- a/drivers/xen/pcpu.c +++ b/drivers/xen/pcpu.c | |||
@@ -278,8 +278,7 @@ static int sync_pcpu(uint32_t cpu, uint32_t *max_cpu) | |||
278 | * Only those at cpu present map has its sys interface. | 278 | * Only those at cpu present map has its sys interface. |
279 | */ | 279 | */ |
280 | if (info->flags & XEN_PCPU_FLAGS_INVALID) { | 280 | if (info->flags & XEN_PCPU_FLAGS_INVALID) { |
281 | if (pcpu) | 281 | unregister_and_remove_pcpu(pcpu); |
282 | unregister_and_remove_pcpu(pcpu); | ||
283 | return 0; | 282 | return 0; |
284 | } | 283 | } |
285 | 284 | ||