x86/xen: move paravirt lazy code
[linux-2.6-microblaze.git] / arch / x86 / xen / enlighten_pv.c
index 49352fa..54b8382 100644 (file)
@@ -101,6 +101,16 @@ struct tls_descs {
        struct desc_struct desc[3];
 };
 
+DEFINE_PER_CPU(enum xen_lazy_mode, xen_lazy_mode) = XEN_LAZY_NONE;
+
+enum xen_lazy_mode xen_get_lazy_mode(void)
+{
+       if (in_interrupt())
+               return XEN_LAZY_NONE;
+
+       return this_cpu_read(xen_lazy_mode);
+}
+
 /*
  * Updating the 3 TLS descriptors in the GDT on every task switch is
  * surprisingly expensive so we avoid updating them if they haven't
@@ -362,10 +372,25 @@ static noinstr unsigned long xen_get_debugreg(int reg)
        return HYPERVISOR_get_debugreg(reg);
 }
 
+static void xen_start_context_switch(struct task_struct *prev)
+{
+       BUG_ON(preemptible());
+
+       if (this_cpu_read(xen_lazy_mode) == XEN_LAZY_MMU) {
+               arch_leave_lazy_mmu_mode();
+               set_ti_thread_flag(task_thread_info(prev), TIF_LAZY_MMU_UPDATES);
+       }
+       enter_lazy(XEN_LAZY_CPU);
+}
+
 static void xen_end_context_switch(struct task_struct *next)
 {
+       BUG_ON(preemptible());
+
        xen_mc_flush();
-       paravirt_end_context_switch(next);
+       leave_lazy(XEN_LAZY_CPU);
+       if (test_and_clear_ti_thread_flag(task_thread_info(next), TIF_LAZY_MMU_UPDATES))
+               arch_enter_lazy_mmu_mode();
 }
 
 static unsigned long xen_store_tr(void)
@@ -472,7 +497,7 @@ static void xen_set_ldt(const void *addr, unsigned entries)
 
        MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
 
-       xen_mc_issue(PARAVIRT_LAZY_CPU);
+       xen_mc_issue(XEN_LAZY_CPU);
 }
 
 static void xen_load_gdt(const struct desc_ptr *dtr)
@@ -568,7 +593,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
         * exception between the new %fs descriptor being loaded and
         * %fs being effectively cleared at __switch_to().
         */
-       if (paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)
+       if (xen_get_lazy_mode() == XEN_LAZY_CPU)
                loadsegment(fs, 0);
 
        xen_mc_batch();
@@ -577,7 +602,7 @@ static void xen_load_tls(struct thread_struct *t, unsigned int cpu)
        load_TLS_descriptor(t, cpu, 1);
        load_TLS_descriptor(t, cpu, 2);
 
-       xen_mc_issue(PARAVIRT_LAZY_CPU);
+       xen_mc_issue(XEN_LAZY_CPU);
 }
 
 static void xen_load_gs_index(unsigned int idx)
@@ -909,7 +934,7 @@ static void xen_load_sp0(unsigned long sp0)
 
        mcs = xen_mc_entry(0);
        MULTI_stack_switch(mcs.mc, __KERNEL_DS, sp0);
-       xen_mc_issue(PARAVIRT_LAZY_CPU);
+       xen_mc_issue(XEN_LAZY_CPU);
        this_cpu_write(cpu_tss_rw.x86_tss.sp0, sp0);
 }
 
@@ -973,7 +998,7 @@ static void xen_write_cr0(unsigned long cr0)
 
        MULTI_fpu_taskswitch(mcs.mc, (cr0 & X86_CR0_TS) != 0);
 
-       xen_mc_issue(PARAVIRT_LAZY_CPU);
+       xen_mc_issue(XEN_LAZY_CPU);
 }
 
 static void xen_write_cr4(unsigned long cr4)
@@ -1156,7 +1181,7 @@ static const typeof(pv_ops) xen_cpu_ops __initconst = {
 #endif
                .io_delay = xen_io_delay,
 
-               .start_context_switch = paravirt_start_context_switch,
+               .start_context_switch = xen_start_context_switch,
                .end_context_switch = xen_end_context_switch,
        },
 };