aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/enlighten.c
diff options
context:
space:
mode:
authorKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-09-12 11:14:33 -0400
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2012-09-12 11:14:33 -0400
commit25a765b7f05cb8460fa01b54568894b20e184862 (patch)
tree0b56db57b4d9f912393ab303c269e0fe6cdf8635 /arch/x86/xen/enlighten.c
parent9d2be9287107695708e6aae5105a8a518a6cb4d0 (diff)
parent64282278989d5b0398dcb3ba7904cb00c621dc35 (diff)
Merge branch 'x86/platform' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into stable/for-linus-3.7
* 'x86/platform' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (9690 commits) x86: Document x86_init.paging.pagetable_init() x86: xen: Cleanup and remove x86_init.paging.pagetable_setup_done() x86: Move paging_init() call to x86_init.paging.pagetable_init() x86: Rename pagetable_setup_start() to pagetable_init() x86: Remove base argument from x86_init.paging.pagetable_setup_start Linux 3.6-rc5 HID: tpkbd: work even if the new Lenovo Keyboard driver is not configured Remove user-triggerable BUG from mpol_to_str xen/pciback: Fix proper FLR steps. uml: fix compile error in deliver_alarm() dj: memory scribble in logi_dj Fix order of arguments to compat_put_time[spec|val] xen: Use correct masking in xen_swiotlb_alloc_coherent. xen: fix logical error in tlb flushing xen/p2m: Fix one-off error in checking the P2M tree directory. powerpc: Don't use __put_user() in patch_instruction powerpc: Make sure IPI handlers see data written by IPI senders powerpc: Restore correct DSCR in context switch powerpc: Fix DSCR inheritance in copy_thread() powerpc: Keep thread.dscr and thread.dscr_inherit in sync ...
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r--arch/x86/xen/enlighten.c112
1 files changed, 68 insertions, 44 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index cb1b1914dbd3..2766746de274 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -38,6 +38,7 @@
38#include <xen/interface/physdev.h> 38#include <xen/interface/physdev.h>
39#include <xen/interface/vcpu.h> 39#include <xen/interface/vcpu.h>
40#include <xen/interface/memory.h> 40#include <xen/interface/memory.h>
41#include <xen/interface/xen-mca.h>
41#include <xen/features.h> 42#include <xen/features.h>
42#include <xen/page.h> 43#include <xen/page.h>
43#include <xen/hvm.h> 44#include <xen/hvm.h>
@@ -109,7 +110,7 @@ EXPORT_SYMBOL_GPL(xen_have_vector_callback);
109 * Point at some empty memory to start with. We map the real shared_info 110 * Point at some empty memory to start with. We map the real shared_info
110 * page as soon as fixmap is up and running. 111 * page as soon as fixmap is up and running.
111 */ 112 */
112struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info; 113struct shared_info *HYPERVISOR_shared_info = &xen_dummy_shared_info;
113 114
114/* 115/*
115 * Flag to determine whether vcpu info placement is available on all 116 * Flag to determine whether vcpu info placement is available on all
@@ -126,6 +127,19 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
126 */ 127 */
127static int have_vcpu_info_placement = 1; 128static int have_vcpu_info_placement = 1;
128 129
130struct tls_descs {
131 struct desc_struct desc[3];
132};
133
134/*
135 * Updating the 3 TLS descriptors in the GDT on every task switch is
136 * surprisingly expensive so we avoid updating them if they haven't
137 * changed. Since Xen writes different descriptors than the one
138 * passed in the update_descriptor hypercall we keep shadow copies to
139 * compare against.
140 */
141static DEFINE_PER_CPU(struct tls_descs, shadow_tls_desc);
142
129static void clamp_max_cpus(void) 143static void clamp_max_cpus(void)
130{ 144{
131#ifdef CONFIG_SMP 145#ifdef CONFIG_SMP
@@ -343,9 +357,7 @@ static void __init xen_init_cpuid_mask(void)
343 unsigned int xsave_mask; 357 unsigned int xsave_mask;
344 358
345 cpuid_leaf1_edx_mask = 359 cpuid_leaf1_edx_mask =
346 ~((1 << X86_FEATURE_MCE) | /* disable MCE */ 360 ~((1 << X86_FEATURE_MTRR) | /* disable MTRR */
347 (1 << X86_FEATURE_MCA) | /* disable MCA */
348 (1 << X86_FEATURE_MTRR) | /* disable MTRR */
349 (1 << X86_FEATURE_ACC)); /* thermal monitoring */ 361 (1 << X86_FEATURE_ACC)); /* thermal monitoring */
350 362
351 if (!xen_initial_domain()) 363 if (!xen_initial_domain())
@@ -542,12 +554,28 @@ static void __init xen_load_gdt_boot(const struct desc_ptr *dtr)
542 BUG(); 554 BUG();
543} 555}
544 556
557static inline bool desc_equal(const struct desc_struct *d1,
558 const struct desc_struct *d2)
559{
560 return d1->a == d2->a && d1->b == d2->b;
561}
562
545static void load_TLS_descriptor(struct thread_struct *t, 563static void load_TLS_descriptor(struct thread_struct *t,
546 unsigned int cpu, unsigned int i) 564 unsigned int cpu, unsigned int i)
547{ 565{
548 struct desc_struct *gdt = get_cpu_gdt_table(cpu); 566 struct desc_struct *shadow = &per_cpu(shadow_tls_desc, cpu).desc[i];
549 xmaddr_t maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]); 567 struct desc_struct *gdt;
550 struct multicall_space mc = __xen_mc_entry(0); 568 xmaddr_t maddr;
569 struct multicall_space mc;
570
571 if (desc_equal(shadow, &t->tls_array[i]))
572 return;
573
574 *shadow = t->tls_array[i];
575
576 gdt = get_cpu_gdt_table(cpu);
577 maddr = arbitrary_virt_to_machine(&gdt[GDT_ENTRY_TLS_MIN+i]);
578 mc = __xen_mc_entry(0);
551 579
552 MULTI_update_descriptor(mc.mc, maddr.maddr, t->tls_array[i]); 580 MULTI_update_descriptor(mc.mc, maddr.maddr, t->tls_array[i]);
553} 581}
@@ -629,8 +657,8 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
629 /* 657 /*
630 * Look for known traps using IST, and substitute them 658 * Look for known traps using IST, and substitute them
631 * appropriately. The debugger ones are the only ones we care 659 * appropriately. The debugger ones are the only ones we care
632 * about. Xen will handle faults like double_fault and 660 * about. Xen will handle faults like double_fault,
633 * machine_check, so we should never see them. Warn if 661 * so we should never see them. Warn if
634 * there's an unexpected IST-using fault handler. 662 * there's an unexpected IST-using fault handler.
635 */ 663 */
636 if (addr == (unsigned long)debug) 664 if (addr == (unsigned long)debug)
@@ -645,7 +673,11 @@ static int cvt_gate_to_trap(int vector, const gate_desc *val,
645 return 0; 673 return 0;
646#ifdef CONFIG_X86_MCE 674#ifdef CONFIG_X86_MCE
647 } else if (addr == (unsigned long)machine_check) { 675 } else if (addr == (unsigned long)machine_check) {
648 return 0; 676 /*
677 * when xen hypervisor inject vMCE to guest,
678 * use native mce handler to handle it
679 */
680 ;
649#endif 681#endif
650 } else { 682 } else {
651 /* Some other trap using IST? */ 683 /* Some other trap using IST? */
@@ -1126,9 +1158,7 @@ static const struct pv_cpu_ops xen_cpu_ops __initconst = {
1126 .wbinvd = native_wbinvd, 1158 .wbinvd = native_wbinvd,
1127 1159
1128 .read_msr = native_read_msr_safe, 1160 .read_msr = native_read_msr_safe,
1129 .rdmsr_regs = native_rdmsr_safe_regs,
1130 .write_msr = xen_write_msr_safe, 1161 .write_msr = xen_write_msr_safe,
1131 .wrmsr_regs = native_wrmsr_safe_regs,
1132 1162
1133 .read_tsc = native_read_tsc, 1163 .read_tsc = native_read_tsc,
1134 .read_pmc = native_read_pmc, 1164 .read_pmc = native_read_pmc,
@@ -1441,32 +1471,6 @@ asmlinkage void __init xen_start_kernel(void)
1441#endif 1471#endif
1442} 1472}
1443 1473
1444static int init_hvm_pv_info(int *major, int *minor)
1445{
1446 uint32_t eax, ebx, ecx, edx, pages, msr, base;
1447 u64 pfn;
1448
1449 base = xen_cpuid_base();
1450 cpuid(base + 1, &eax, &ebx, &ecx, &edx);
1451
1452 *major = eax >> 16;
1453 *minor = eax & 0xffff;
1454 printk(KERN_INFO "Xen version %d.%d.\n", *major, *minor);
1455
1456 cpuid(base + 2, &pages, &msr, &ecx, &edx);
1457
1458 pfn = __pa(hypercall_page);
1459 wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
1460
1461 xen_setup_features();
1462
1463 pv_info.name = "Xen HVM";
1464
1465 xen_domain_type = XEN_HVM_DOMAIN;
1466
1467 return 0;
1468}
1469
1470void __ref xen_hvm_init_shared_info(void) 1474void __ref xen_hvm_init_shared_info(void)
1471{ 1475{
1472 int cpu; 1476 int cpu;
@@ -1499,6 +1503,31 @@ void __ref xen_hvm_init_shared_info(void)
1499} 1503}
1500 1504
1501#ifdef CONFIG_XEN_PVHVM 1505#ifdef CONFIG_XEN_PVHVM
1506static void __init init_hvm_pv_info(void)
1507{
1508 int major, minor;
1509 uint32_t eax, ebx, ecx, edx, pages, msr, base;
1510 u64 pfn;
1511
1512 base = xen_cpuid_base();
1513 cpuid(base + 1, &eax, &ebx, &ecx, &edx);
1514
1515 major = eax >> 16;
1516 minor = eax & 0xffff;
1517 printk(KERN_INFO "Xen version %d.%d.\n", major, minor);
1518
1519 cpuid(base + 2, &pages, &msr, &ecx, &edx);
1520
1521 pfn = __pa(hypercall_page);
1522 wrmsr_safe(msr, (u32)pfn, (u32)(pfn >> 32));
1523
1524 xen_setup_features();
1525
1526 pv_info.name = "Xen HVM";
1527
1528 xen_domain_type = XEN_HVM_DOMAIN;
1529}
1530
1502static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self, 1531static int __cpuinit xen_hvm_cpu_notify(struct notifier_block *self,
1503 unsigned long action, void *hcpu) 1532 unsigned long action, void *hcpu)
1504{ 1533{
@@ -1521,12 +1550,7 @@ static struct notifier_block xen_hvm_cpu_notifier __cpuinitdata = {
1521 1550
1522static void __init xen_hvm_guest_init(void) 1551static void __init xen_hvm_guest_init(void)
1523{ 1552{
1524 int r; 1553 init_hvm_pv_info();
1525 int major, minor;
1526
1527 r = init_hvm_pv_info(&major, &minor);
1528 if (r < 0)
1529 return;
1530 1554
1531 xen_hvm_init_shared_info(); 1555 xen_hvm_init_shared_info();
1532 1556