]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - include/asm-i386/paravirt.h
[PATCH] i386: PARAVIRT: rename struct paravirt_patch to paravirt_patch_site for clarity
[linux-2.6-omap-h63xx.git] / include / asm-i386 / paravirt.h
index 9f06265065f4ae564e508aa7851091bd81630f1c..b4cc2fc4031e259e67fece256da357289e83e653 100644 (file)
@@ -2,11 +2,11 @@
 #define __ASM_PARAVIRT_H
 /* Various instructions on x86 need to be replaced for
  * para-virtualization: those hooks are defined here. */
-#include <linux/linkage.h>
+
+#ifdef CONFIG_PARAVIRT
 #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
  * callers */
 #define PARAVIRT_IRQ_DISABLE 0
 #define CLBR_ANY 0x7
 
 #ifndef __ASSEMBLY__
+#include <linux/types.h>
+
 struct thread_struct;
 struct Xgt_desc_struct;
 struct tss_struct;
 struct mm_struct;
+struct desc_struct;
 struct paravirt_ops
 {
        unsigned int kernel_rpl;
+       int shared_kernel_pmd;
        int paravirt_enabled;
        const char *name;
 
@@ -48,101 +52,136 @@ struct paravirt_ops
        char *(*memory_setup)(void);
        void (*init_IRQ)(void);
 
+       void (*pagetable_setup_start)(pgd_t *pgd_base);
+       void (*pagetable_setup_done)(pgd_t *pgd_base);
+
        void (*banner)(void);
 
        unsigned long (*get_wallclock)(void);
        int (*set_wallclock)(unsigned long);
        void (*time_init)(void);
 
-       /* All the function pointers here are declared as "fastcall"
-          so that we get a specific register-based calling
-          convention.  This makes it easier to implement inline
-          assembler replacements. */
-
-       void (fastcall *cpuid)(unsigned int *eax, unsigned int *ebx,
+       void (*cpuid)(unsigned int *eax, unsigned int *ebx,
                      unsigned int *ecx, unsigned int *edx);
 
-       unsigned long (fastcall *get_debugreg)(int regno);
-       void (fastcall *set_debugreg)(int regno, unsigned long value);
+       unsigned long (*get_debugreg)(int regno);
+       void (*set_debugreg)(int regno, unsigned long value);
 
-       void (fastcall *clts)(void);
+       void (*clts)(void);
 
-       unsigned long (fastcall *read_cr0)(void);
-       void (fastcall *write_cr0)(unsigned long);
+       unsigned long (*read_cr0)(void);
+       void (*write_cr0)(unsigned long);
 
-       unsigned long (fastcall *read_cr2)(void);
-       void (fastcall *write_cr2)(unsigned long);
+       unsigned long (*read_cr2)(void);
+       void (*write_cr2)(unsigned long);
 
-       unsigned long (fastcall *read_cr3)(void);
-       void (fastcall *write_cr3)(unsigned long);
+       unsigned long (*read_cr3)(void);
+       void (*write_cr3)(unsigned long);
 
-       unsigned long (fastcall *read_cr4_safe)(void);
-       unsigned long (fastcall *read_cr4)(void);
-       void (fastcall *write_cr4)(unsigned long);
+       unsigned long (*read_cr4_safe)(void);
+       unsigned long (*read_cr4)(void);
+       void (*write_cr4)(unsigned long);
 
-       unsigned long (fastcall *save_fl)(void);
-       void (fastcall *restore_fl)(unsigned long);
-       void (fastcall *irq_disable)(void);
-       void (fastcall *irq_enable)(void);
-       void (fastcall *safe_halt)(void);
-       void (fastcall *halt)(void);
-       void (fastcall *wbinvd)(void);
+       unsigned long (*save_fl)(void);
+       void (*restore_fl)(unsigned long);
+       void (*irq_disable)(void);
+       void (*irq_enable)(void);
+       void (*safe_halt)(void);
+       void (*halt)(void);
+       void (*wbinvd)(void);
 
        /* err = 0/-EFAULT.  wrmsr returns 0/-EFAULT. */
-       u64 (fastcall *read_msr)(unsigned int msr, int *err);
-       int (fastcall *write_msr)(unsigned int msr, u64 val);
-
-       u64 (fastcall *read_tsc)(void);
-       u64 (fastcall *read_pmc)(void);
-
-       void (fastcall *load_tr_desc)(void);
-       void (fastcall *load_gdt)(const struct Xgt_desc_struct *);
-       void (fastcall *load_idt)(const struct Xgt_desc_struct *);
-       void (fastcall *store_gdt)(struct Xgt_desc_struct *);
-       void (fastcall *store_idt)(struct Xgt_desc_struct *);
-       void (fastcall *set_ldt)(const void *desc, unsigned entries);
-       unsigned long (fastcall *store_tr)(void);
-       void (fastcall *load_tls)(struct thread_struct *t, unsigned int cpu);
-       void (fastcall *write_ldt_entry)(void *dt, int entrynum,
-                                        u32 low, u32 high);
-       void (fastcall *write_gdt_entry)(void *dt, int entrynum,
-                                        u32 low, u32 high);
-       void (fastcall *write_idt_entry)(void *dt, int entrynum,
-                                        u32 low, u32 high);
-       void (fastcall *load_esp0)(struct tss_struct *tss,
-                                  struct thread_struct *thread);
-
-       void (fastcall *set_iopl_mask)(unsigned mask);
-
-       void (fastcall *io_delay)(void);
-       void (*const_udelay)(unsigned long loops);
+       u64 (*read_msr)(unsigned int msr, int *err);
+       int (*write_msr)(unsigned int msr, u64 val);
+
+       u64 (*read_tsc)(void);
+       u64 (*read_pmc)(void);
+       u64 (*get_scheduled_cycles)(void);
+       unsigned long (*get_cpu_khz)(void);
+
+       void (*load_tr_desc)(void);
+       void (*load_gdt)(const struct Xgt_desc_struct *);
+       void (*load_idt)(const struct Xgt_desc_struct *);
+       void (*store_gdt)(struct Xgt_desc_struct *);
+       void (*store_idt)(struct Xgt_desc_struct *);
+       void (*set_ldt)(const void *desc, unsigned entries);
+       unsigned long (*store_tr)(void);
+       void (*load_tls)(struct thread_struct *t, unsigned int cpu);
+       void (*write_ldt_entry)(struct desc_struct *,
+                               int entrynum, u32 low, u32 high);
+       void (*write_gdt_entry)(struct desc_struct *,
+                               int entrynum, u32 low, u32 high);
+       void (*write_idt_entry)(struct desc_struct *,
+                               int entrynum, u32 low, u32 high);
+       void (*load_esp0)(struct tss_struct *tss, struct thread_struct *t);
+
+       void (*set_iopl_mask)(unsigned mask);
+
+       void (*io_delay)(void);
+
+       void (*activate_mm)(struct mm_struct *prev,
+                           struct mm_struct *next);
+       void (*dup_mmap)(struct mm_struct *oldmm,
+                        struct mm_struct *mm);
+       void (*exit_mmap)(struct mm_struct *mm);
 
 #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);
+       void (*apic_write)(unsigned long reg, unsigned long v);
+       void (*apic_write_atomic)(unsigned long reg, unsigned long v);
+       unsigned long (*apic_read)(unsigned long reg);
+       void (*setup_boot_clock)(void);
+       void (*setup_secondary_clock)(void);
 #endif
 
-       void (fastcall *flush_tlb_user)(void);
-       void (fastcall *flush_tlb_kernel)(void);
-       void (fastcall *flush_tlb_single)(u32 addr);
+       void (*flush_tlb_user)(void);
+       void (*flush_tlb_kernel)(void);
+       void (*flush_tlb_single)(u32 addr);
+
+       void (*map_pt_hook)(int type, pte_t *va, u32 pfn);
+
+       void (*alloc_pt)(u32 pfn);
+       void (*alloc_pd)(u32 pfn);
+       void (*alloc_pd_clone)(u32 pfn, u32 clonepfn, u32 start, u32 count);
+       void (*release_pt)(u32 pfn);
+       void (*release_pd)(u32 pfn);
+
+       void (*set_pte)(pte_t *ptep, pte_t pteval);
+       void (*set_pte_at)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval);
+       void (*set_pmd)(pmd_t *pmdp, pmd_t pmdval);
+       void (*pte_update)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+       void (*pte_update_defer)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+
+       pte_t (*ptep_get_and_clear)(pte_t *ptep);
 
-       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);
+       void (*set_pte_atomic)(pte_t *ptep, pte_t pteval);
+       void (*set_pte_present)(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte);
+       void (*set_pud)(pud_t *pudp, pud_t pudval);
+       void (*pte_clear)(struct mm_struct *mm, unsigned long addr, pte_t *ptep);
+       void (*pmd_clear)(pmd_t *pmdp);
+
+       unsigned long long (*pte_val)(pte_t);
+       unsigned long long (*pmd_val)(pmd_t);
+       unsigned long long (*pgd_val)(pgd_t);
+
+       pte_t (*make_pte)(unsigned long long pte);
+       pmd_t (*make_pmd)(unsigned long long pmd);
+       pgd_t (*make_pgd)(unsigned long long pgd);
+#else
+       unsigned long (*pte_val)(pte_t);
+       unsigned long (*pgd_val)(pgd_t);
+
+       pte_t (*make_pte)(unsigned long pte);
+       pgd_t (*make_pgd)(unsigned long pgd);
 #endif
 
+       void (*set_lazy_mode)(int mode);
+
        /* These two are jmp to, not actually called. */
-       void (fastcall *irq_enable_sysexit)(void);
-       void (fastcall *iret)(void);
+       void (*irq_enable_sysexit)(void);
+       void (*iret)(void);
+
+       void (*startup_ipi_hook)(int phys_apicid, unsigned long start_eip, unsigned long start_esp);
 };
 
 /* Mark a paravirt probe function. */
@@ -171,9 +210,9 @@ static inline int set_wallclock(unsigned long nowtime)
        return paravirt_ops.set_wallclock(nowtime);
 }
 
-static inline void do_time_init(void)
+static inline void (*choose_time_init(void))(void)
 {
-       return paravirt_ops.time_init();
+       return paravirt_ops.time_init;
 }
 
 /* The paravirtualized CPUID instruction. */
@@ -204,6 +243,8 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
 #define read_cr4_safe(x) paravirt_ops.read_cr4_safe()
 #define write_cr4(x) paravirt_ops.write_cr4(x)
 
+#define raw_ptep_get_and_clear(xp)     (paravirt_ops.ptep_get_and_clear(xp))
+
 static inline void raw_safe_halt(void)
 {
        paravirt_ops.safe_halt();
@@ -217,6 +258,7 @@ static inline void halt(void)
 
 #define get_kernel_rpl()  (paravirt_ops.kernel_rpl)
 
+/* These should all do BUG_ON(_err), but our headers are too tangled. */
 #define rdmsr(msr,val1,val2) do {                              \
        int _err;                                               \
        u64 _l = paravirt_ops.read_msr(msr,&_err);              \
@@ -261,6 +303,9 @@ static inline void halt(void)
 
 #define rdtscll(val) (val = paravirt_ops.read_tsc())
 
+#define get_scheduled_cycles(val) (val = paravirt_ops.get_scheduled_cycles())
+#define calculate_cpu_khz() (paravirt_ops.get_cpu_khz())
+
 #define write_tsc(val1,val2) wrmsr(0x10, val1, val2)
 
 #define rdpmc(counter,low,high) do {                           \
@@ -285,6 +330,17 @@ static inline void halt(void)
        (paravirt_ops.write_idt_entry((dt), (entry), (low), (high)))
 #define set_iopl_mask(mask) (paravirt_ops.set_iopl_mask(mask))
 
+#define __pte(x)       paravirt_ops.make_pte(x)
+#define __pgd(x)       paravirt_ops.make_pgd(x)
+
+#define pte_val(x)     paravirt_ops.pte_val(x)
+#define pgd_val(x)     paravirt_ops.pgd_val(x)
+
+#ifdef CONFIG_X86_PAE
+#define __pmd(x)       paravirt_ops.make_pmd(x)
+#define pmd_val(x)     paravirt_ops.pmd_val(x)
+#endif
+
 /* The paravirtualized I/O functions */
 static inline void slow_down_io(void) {
        paravirt_ops.io_delay();
@@ -313,19 +369,76 @@ static inline unsigned long apic_read(unsigned long reg)
 {
        return paravirt_ops.apic_read(reg);
 }
+
+static inline void setup_boot_clock(void)
+{
+       paravirt_ops.setup_boot_clock();
+}
+
+static inline void setup_secondary_clock(void)
+{
+       paravirt_ops.setup_secondary_clock();
+}
 #endif
 
+static inline void paravirt_pagetable_setup_start(pgd_t *base)
+{
+       if (paravirt_ops.pagetable_setup_start)
+               (*paravirt_ops.pagetable_setup_start)(base);
+}
+
+static inline void paravirt_pagetable_setup_done(pgd_t *base)
+{
+       if (paravirt_ops.pagetable_setup_done)
+               (*paravirt_ops.pagetable_setup_done)(base);
+}
+
+#ifdef CONFIG_SMP
+static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
+                                   unsigned long start_esp)
+{
+       return paravirt_ops.startup_ipi_hook(phys_apicid, start_eip, start_esp);
+}
+#endif
+
+static inline void paravirt_activate_mm(struct mm_struct *prev,
+                                       struct mm_struct *next)
+{
+       paravirt_ops.activate_mm(prev, next);
+}
+
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+                                struct mm_struct *mm)
+{
+       paravirt_ops.dup_mmap(oldmm, mm);
+}
+
+static inline void arch_exit_mmap(struct mm_struct *mm)
+{
+       paravirt_ops.exit_mmap(mm);
+}
 
 #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_map_pt_hook(type, va, pfn) paravirt_ops.map_pt_hook(type, va, pfn)
+
+#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)
+static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
+                             pte_t *ptep, pte_t pteval)
 {
        paravirt_ops.set_pte_at(mm, addr, ptep, pteval);
 }
@@ -372,14 +485,36 @@ static inline void pmd_clear(pmd_t *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 PARAVIRT_LAZY_FLUSH 3
+
+#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 arch_flush_lazy_cpu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH)
+
+#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)
+#define arch_flush_lazy_mmu_mode() paravirt_ops.set_lazy_mode(PARAVIRT_LAZY_FLUSH)
+
+void _paravirt_nop(void);
+#define paravirt_nop   ((void *)_paravirt_nop)
+
 /* These all sit in the .parainstructions section to tell us what to patch. */
-struct paravirt_patch {
+struct paravirt_patch_site {
        u8 *instr;              /* original instructions */
        u8 instrtype;           /* type of this instruction */
        u8 len;                 /* length of original instruction */
        u16 clobbers;           /* what registers you may clobber */
 };
 
+extern struct paravirt_patch_site __parainstructions[],
+       __parainstructions_end[];
+
 #define paravirt_alt(insn_string, typenum, clobber)    \
        "771:\n\t" insn_string "\n" "772:\n"            \
        ".pushsection .parainstructions,\"a\"\n"        \