]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/x86/xen/enlighten.c
x86: convert to generic helpers for IPI function calls
[linux-2.6-omap-h63xx.git] / arch / x86 / xen / enlighten.c
index 27ee26aedf941d98e2cdaf5e8fa90ba1a7ee5930..8e317782fe377c1823f9578ced2a419f0d9b90bb 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/mm.h>
 #include <linux/page-flags.h>
 #include <linux/highmem.h>
+#include <linux/console.h>
 
 #include <xen/interface/xen.h>
 #include <xen/interface/physdev.h>
@@ -154,7 +155,8 @@ static void xen_cpuid(unsigned int *ax, unsigned int *bx,
        if (*ax == 1)
                maskedx = ~((1 << X86_FEATURE_APIC) |  /* disable APIC */
                            (1 << X86_FEATURE_ACPI) |  /* disable ACPI */
-                           (1 << X86_FEATURE_SEP)  |  /* disable SEP */
+                           (1 << X86_FEATURE_MCE)  |  /* disable MCE */
+                           (1 << X86_FEATURE_MCA)  |  /* disable MCA */
                            (1 << X86_FEATURE_ACC));   /* thermal monitoring */
 
        asm(XEN_EMULATE_PREFIX "cpuid"
@@ -530,26 +532,37 @@ static void xen_apic_write(unsigned long reg, u32 val)
 static void xen_flush_tlb(void)
 {
        struct mmuext_op *op;
-       struct multicall_space mcs = xen_mc_entry(sizeof(*op));
+       struct multicall_space mcs;
+
+       preempt_disable();
+
+       mcs = xen_mc_entry(sizeof(*op));
 
        op = mcs.args;
        op->cmd = MMUEXT_TLB_FLUSH_LOCAL;
        MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
 
        xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+       preempt_enable();
 }
 
 static void xen_flush_tlb_single(unsigned long addr)
 {
        struct mmuext_op *op;
-       struct multicall_space mcs = xen_mc_entry(sizeof(*op));
+       struct multicall_space mcs;
+
+       preempt_disable();
 
+       mcs = xen_mc_entry(sizeof(*op));
        op = mcs.args;
        op->cmd = MMUEXT_INVLPG_LOCAL;
        op->arg1.linear_addr = addr & PAGE_MASK;
        MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
 
        xen_mc_issue(PARAVIRT_LAZY_MMU);
+
+       preempt_enable();
 }
 
 static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
@@ -654,15 +667,17 @@ static void xen_write_cr3(unsigned long cr3)
 
 /* Early in boot, while setting up the initial pagetable, assume
    everything is pinned. */
-static __init void xen_alloc_pt_init(struct mm_struct *mm, u32 pfn)
+static __init void xen_alloc_pte_init(struct mm_struct *mm, u32 pfn)
 {
+#ifdef CONFIG_FLATMEM
        BUG_ON(mem_map);        /* should only be used early */
+#endif
        make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
 }
 
-/* Early release_pt assumes that all pts are pinned, since there's
+/* Early release_pte assumes that all pts are pinned, since there's
    only init_mm and anything attached to that is pinned. */
-static void xen_release_pt_init(u32 pfn)
+static void xen_release_pte_init(u32 pfn)
 {
        make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
 }
@@ -696,12 +711,12 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
        }
 }
 
-static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
+static void xen_alloc_pte(struct mm_struct *mm, u32 pfn)
 {
        xen_alloc_ptpage(mm, pfn, PT_PTE);
 }
 
-static void xen_alloc_pd(struct mm_struct *mm, u32 pfn)
+static void xen_alloc_pmd(struct mm_struct *mm, u32 pfn)
 {
        xen_alloc_ptpage(mm, pfn, PT_PMD);
 }
@@ -721,12 +736,12 @@ static void xen_release_ptpage(u32 pfn, unsigned level)
        }
 }
 
-static void xen_release_pt(u32 pfn)
+static void xen_release_pte(u32 pfn)
 {
        xen_release_ptpage(pfn, PT_PTE);
 }
 
-static void xen_release_pd(u32 pfn)
+static void xen_release_pmd(u32 pfn)
 {
        xen_release_ptpage(pfn, PT_PMD);
 }
@@ -770,38 +785,35 @@ static __init void xen_set_pte_init(pte_t *ptep, pte_t pte)
 static __init void xen_pagetable_setup_start(pgd_t *base)
 {
        pgd_t *xen_pgd = (pgd_t *)xen_start_info->pt_base;
+       int i;
 
        /* special set_pte for pagetable initialization */
        pv_mmu_ops.set_pte = xen_set_pte_init;
 
        init_mm.pgd = base;
        /*
-        * copy top-level of Xen-supplied pagetable into place.  For
-        * !PAE we can use this as-is, but for PAE it is a stand-in
-        * while we copy the pmd pages.
+        * copy top-level of Xen-supplied pagetable into place.  This
+        * is a stand-in while we copy the pmd pages.
         */
        memcpy(base, xen_pgd, PTRS_PER_PGD * sizeof(pgd_t));
 
-       if (PTRS_PER_PMD > 1) {
-               int i;
-               /*
-                * For PAE, need to allocate new pmds, rather than
-                * share Xen's, since Xen doesn't like pmd's being
-                * shared between address spaces.
-                */
-               for (i = 0; i < PTRS_PER_PGD; i++) {
-                       if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
-                               pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
+       /*
+        * For PAE, need to allocate new pmds, rather than
+        * share Xen's, since Xen doesn't like pmd's being
+        * shared between address spaces.
+        */
+       for (i = 0; i < PTRS_PER_PGD; i++) {
+               if (pgd_val_ma(xen_pgd[i]) & _PAGE_PRESENT) {
+                       pmd_t *pmd = (pmd_t *)alloc_bootmem_low_pages(PAGE_SIZE);
 
-                               memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
-                                      PAGE_SIZE);
+                       memcpy(pmd, (void *)pgd_page_vaddr(xen_pgd[i]),
+                              PAGE_SIZE);
 
-                               make_lowmem_page_readonly(pmd);
+                       make_lowmem_page_readonly(pmd);
 
-                               set_pgd(&base[i], __pgd(1 + __pa(pmd)));
-                       } else
-                               pgd_clear(&base[i]);
-               }
+                       set_pgd(&base[i], __pgd(1 + __pa(pmd)));
+               } else
+                       pgd_clear(&base[i]);
        }
 
        /* make sure zero_page is mapped RO so we can use it in pagetables */
@@ -848,27 +860,17 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
 {
        /* This will work as long as patching hasn't happened yet
           (which it hasn't) */
-       pv_mmu_ops.alloc_pt = xen_alloc_pt;
-       pv_mmu_ops.alloc_pd = xen_alloc_pd;
-       pv_mmu_ops.release_pt = xen_release_pt;
-       pv_mmu_ops.release_pd = xen_release_pd;
+       pv_mmu_ops.alloc_pte = xen_alloc_pte;
+       pv_mmu_ops.alloc_pmd = xen_alloc_pmd;
+       pv_mmu_ops.release_pte = xen_release_pte;
+       pv_mmu_ops.release_pmd = xen_release_pmd;
        pv_mmu_ops.set_pte = xen_set_pte;
 
        setup_shared_info();
 
        /* Actually pin the pagetable down, but we can't set PG_pinned
           yet because the page structures don't exist yet. */
-       {
-               unsigned level;
-
-#ifdef CONFIG_X86_PAE
-               level = MMUEXT_PIN_L3_TABLE;
-#else
-               level = MMUEXT_PIN_L2_TABLE;
-#endif
-
-               pin_pagetable_pfn(level, PFN_DOWN(__pa(base)));
-       }
+       pin_pagetable_pfn(MMUEXT_PIN_L3_TABLE, PFN_DOWN(__pa(base)));
 }
 
 /* This is called once we have the cpu_possible_map */
@@ -889,7 +891,6 @@ void __init xen_setup_vcpu_info_placement(void)
                pv_irq_ops.irq_disable = xen_irq_disable_direct;
                pv_irq_ops.irq_enable = xen_irq_enable_direct;
                pv_mmu_ops.read_cr2 = xen_read_cr2_direct;
-               pv_cpu_ops.iret = xen_iret_direct;
        }
 }
 
@@ -993,8 +994,8 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
        .read_tsc = native_read_tsc,
        .read_pmc = native_read_pmc,
 
-       .iret = (void *)&hypercall_page[__HYPERVISOR_iret],
-       .irq_enable_syscall_ret = NULL,  /* never called */
+       .iret = xen_iret,
+       .irq_enable_syscall_ret = xen_sysexit,
 
        .load_tr_desc = paravirt_nop,
        .set_ldt = xen_set_ldt,
@@ -1059,11 +1060,11 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
        .pte_update = paravirt_nop,
        .pte_update_defer = paravirt_nop,
 
-       .alloc_pt = xen_alloc_pt_init,
-       .release_pt = xen_release_pt_init,
-       .alloc_pd = xen_alloc_pt_init,
-       .alloc_pd_clone = paravirt_nop,
-       .release_pd = xen_release_pt_init,
+       .alloc_pte = xen_alloc_pte_init,
+       .release_pte = xen_release_pte_init,
+       .alloc_pmd = xen_alloc_pte_init,
+       .alloc_pmd_clone = paravirt_nop,
+       .release_pmd = xen_release_pte_init,
 
 #ifdef CONFIG_HIGHPTE
        .kmap_atomic_pte = xen_kmap_atomic_pte,
@@ -1079,7 +1080,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
        .make_pte = xen_make_pte,
        .make_pgd = xen_make_pgd,
 
-#ifdef CONFIG_X86_PAE
        .set_pte_atomic = xen_set_pte_atomic,
        .set_pte_present = xen_set_pte_at,
        .set_pud = xen_set_pud,
@@ -1088,7 +1088,6 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = {
 
        .make_pmd = xen_make_pmd,
        .pmd_val = xen_pmd_val,
-#endif /* PAE */
 
        .activate_mm = xen_activate_mm,
        .dup_mmap = xen_dup_mmap,
@@ -1109,7 +1108,9 @@ static const struct smp_ops xen_smp_ops __initdata = {
 
        .smp_send_stop = xen_smp_send_stop,
        .smp_send_reschedule = xen_smp_send_reschedule,
-       .smp_call_function_mask = xen_smp_call_function_mask,
+
+       .send_call_func_ipi = xen_smp_send_call_function_ipi,
+       .send_call_func_single_ipi = xen_smp_send_call_function_single_ipi,
 };
 #endif /* CONFIG_SMP */
 
@@ -1214,6 +1215,11 @@ asmlinkage void __init xen_start_kernel(void)
        if (xen_feature(XENFEAT_supervisor_mode_kernel))
                pv_info.kernel_rpl = 0;
 
+       /* Prevent unwanted bits from being set in PTEs. */
+       __supported_pte_mask &= ~_PAGE_GLOBAL;
+       if (!is_initial_xendomain())
+               __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
+
        /* set the limit of our address space */
        xen_reserve_top();
 
@@ -1228,6 +1234,9 @@ asmlinkage void __init xen_start_kernel(void)
                ? __pa(xen_start_info->mod_start) : 0;
        boot_params.hdr.ramdisk_size = xen_start_info->mod_len;
 
+       if (!is_initial_xendomain())
+               add_preferred_console("hvc", 0, NULL);
+
        /* Start the world */
        start_kernel();
 }