]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - include/asm-i386/paravirt.h
[PATCH] i386: paravirt CPU hypercall batching mode
[net-next-2.6.git] / include / asm-i386 / paravirt.h
index dd707d8c8270fdea82bc40bbbd5cc6d7bbdc5ef4..38e5164bd0e70451de85dd66e92f6208c7dffb14 100644 (file)
@@ -4,6 +4,7 @@
  * para-virtualization: those hooks are defined here. */
 #include <linux/linkage.h>
 #include <linux/stringify.h>
+#include <asm/page.h>
 
 #ifdef CONFIG_PARAVIRT
 /* These are the most performance critical ops, so we want to be able to patch
@@ -27,6 +28,7 @@
 struct thread_struct;
 struct Xgt_desc_struct;
 struct tss_struct;
+struct mm_struct;
 struct paravirt_ops
 {
        unsigned int kernel_rpl;
@@ -115,6 +117,37 @@ struct paravirt_ops
        void (fastcall *io_delay)(void);
        void (*const_udelay)(unsigned long loops);
 
+#ifdef CONFIG_X86_LOCAL_APIC
+       void (fastcall *apic_write)(unsigned long reg, unsigned long v);
+       void (fastcall *apic_write_atomic)(unsigned long reg, unsigned long v);
+       unsigned long (fastcall *apic_read)(unsigned long reg);
+#endif
+
+       void (fastcall *flush_tlb_user)(void);
+       void (fastcall *flush_tlb_kernel)(void);
+       void (fastcall *flush_tlb_single)(u32 addr);
+
+       void (fastcall *alloc_pt)(u32 pfn);
+       void (fastcall *alloc_pd)(u32 pfn);
+       void (fastcall *alloc_pd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count);
+       void (fastcall *release_pt)(u32 pfn);
+       void (fastcall *release_pd)(u32 pfn);
+
+       void (fastcall *set_pte)(pte_t *ptep, pte_t pteval);
+       void (fastcall *set_pte_at)(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval);
+       void (fastcall *set_pmd)(pmd_t *pmdp, pmd_t pmdval);
+       void (fastcall *pte_update)(struct mm_struct *mm, u32 addr, pte_t *ptep);
+       void (fastcall *pte_update_defer)(struct mm_struct *mm, u32 addr, pte_t *ptep);
+#ifdef CONFIG_X86_PAE
+       void (fastcall *set_pte_atomic)(pte_t *ptep, pte_t pteval);
+       void (fastcall *set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
+       void (fastcall *set_pud)(pud_t *pudp, pud_t pudval);
+       void (fastcall *pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+       void (fastcall *pmd_clear)(pmd_t *pmdp);
+#endif
+
+       void (fastcall *set_lazy_mode)(int mode);
+
        /* These two are jmp to, not actually called. */
        void (fastcall *irq_enable_sysexit)(void);
        void (fastcall *iret)(void);
@@ -270,6 +303,104 @@ static inline void slow_down_io(void) {
 #endif
 }
 
+#ifdef CONFIG_X86_LOCAL_APIC
+/*
+ * Basic functions accessing APICs.
+ */
+static inline void apic_write(unsigned long reg, unsigned long v)
+{
+       paravirt_ops.apic_write(reg,v);
+}
+
+static inline void apic_write_atomic(unsigned long reg, unsigned long v)
+{
+       paravirt_ops.apic_write_atomic(reg,v);
+}
+
+static inline unsigned long apic_read(unsigned long reg)
+{
+       return paravirt_ops.apic_read(reg);
+}
+#endif
+
+
+#define __flush_tlb() paravirt_ops.flush_tlb_user()
+#define __flush_tlb_global() paravirt_ops.flush_tlb_kernel()
+#define __flush_tlb_single(addr) paravirt_ops.flush_tlb_single(addr)
+
+#define paravirt_alloc_pt(pfn) paravirt_ops.alloc_pt(pfn)
+#define paravirt_release_pt(pfn) paravirt_ops.release_pt(pfn)
+
+#define paravirt_alloc_pd(pfn) paravirt_ops.alloc_pd(pfn)
+#define paravirt_alloc_pd_clone(pfn, clonepfn, start, count) \
+       paravirt_ops.alloc_pd_clone(pfn, clonepfn, start, count)
+#define paravirt_release_pd(pfn) paravirt_ops.release_pd(pfn)
+
+static inline void set_pte(pte_t *ptep, pte_t pteval)
+{
+       paravirt_ops.set_pte(ptep, pteval);
+}
+
+static inline void set_pte_at(struct mm_struct *mm, u32 addr, pte_t *ptep, pte_t pteval)
+{
+       paravirt_ops.set_pte_at(mm, addr, ptep, pteval);
+}
+
+static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval)
+{
+       paravirt_ops.set_pmd(pmdp, pmdval);
+}
+
+static inline void pte_update(struct mm_struct *mm, u32 addr, pte_t *ptep)
+{
+       paravirt_ops.pte_update(mm, addr, ptep);
+}
+
+static inline void pte_update_defer(struct mm_struct *mm, u32 addr, pte_t *ptep)
+{
+       paravirt_ops.pte_update_defer(mm, addr, ptep);
+}
+
+#ifdef CONFIG_X86_PAE
+static inline void set_pte_atomic(pte_t *ptep, pte_t pteval)
+{
+       paravirt_ops.set_pte_atomic(ptep, pteval);
+}
+
+static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte)
+{
+       paravirt_ops.set_pte_present(mm, addr, ptep, pte);
+}
+
+static inline void set_pud(pud_t *pudp, pud_t pudval)
+{
+       paravirt_ops.set_pud(pudp, pudval);
+}
+
+static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+{
+       paravirt_ops.pte_clear(mm, addr, ptep);
+}
+
+static inline void pmd_clear(pmd_t *pmdp)
+{
+       paravirt_ops.pmd_clear(pmdp);
+}
+#endif
+
+/* Lazy mode for batching updates / context switch */
+#define PARAVIRT_LAZY_NONE 0
+#define PARAVIRT_LAZY_MMU  1
+#define PARAVIRT_LAZY_CPU  2
+
+#define  __HAVE_ARCH_ENTER_LAZY_CPU_MODE
+#define arch_enter_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_CPU)
+#define arch_leave_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE)
+
+#define  __HAVE_ARCH_ENTER_LAZY_MMU_MODE
+#define arch_enter_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_MMU)
+#define arch_leave_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_NONE)
+
 /* These all sit in the .parainstructions section to tell us what to patch. */
 struct paravirt_patch {
        u8 *instr;              /* original instructions */