📄 paravirt.h
字号:
PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr);}static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm, unsigned long va){ PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va);}static inline void paravirt_alloc_pt(struct mm_struct *mm, unsigned pfn){ PVOP_VCALL2(pv_mmu_ops.alloc_pt, mm, pfn);}static inline void paravirt_release_pt(unsigned pfn){ PVOP_VCALL1(pv_mmu_ops.release_pt, pfn);}static inline void paravirt_alloc_pd(unsigned pfn){ PVOP_VCALL1(pv_mmu_ops.alloc_pd, pfn);}static inline void paravirt_alloc_pd_clone(unsigned pfn, unsigned clonepfn, unsigned start, unsigned count){ PVOP_VCALL4(pv_mmu_ops.alloc_pd_clone, pfn, clonepfn, start, count);}static inline void paravirt_release_pd(unsigned pfn){ PVOP_VCALL1(pv_mmu_ops.release_pd, pfn);}#ifdef CONFIG_HIGHPTEstatic inline void *kmap_atomic_pte(struct page *page, enum km_type type){ unsigned long ret; ret = PVOP_CALL2(unsigned long, pv_mmu_ops.kmap_atomic_pte, page, type); return (void *)ret;}#endifstatic inline void pte_update(struct mm_struct *mm, unsigned long addr, pte_t *ptep){ PVOP_VCALL3(pv_mmu_ops.pte_update, mm, addr, ptep);}static inline void pte_update_defer(struct mm_struct *mm, unsigned long addr, pte_t *ptep){ PVOP_VCALL3(pv_mmu_ops.pte_update_defer, mm, addr, ptep);}#ifdef CONFIG_X86_PAEstatic inline pte_t __pte(unsigned long long val){ unsigned long long ret = PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pte, val, val >> 32); return (pte_t) { ret, ret >> 32 };}static inline pmd_t __pmd(unsigned long long val){ return (pmd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pmd, val, val >> 32) };}static inline pgd_t __pgd(unsigned long long val){ return (pgd_t) { PVOP_CALL2(unsigned long long, pv_mmu_ops.make_pgd, val, val >> 32) };}static inline unsigned long long pte_val(pte_t x){ return PVOP_CALL2(unsigned long long, pv_mmu_ops.pte_val, x.pte_low, x.pte_high);}static inline unsigned long long pmd_val(pmd_t x){ return PVOP_CALL2(unsigned long long, pv_mmu_ops.pmd_val, x.pmd, x.pmd >> 32);}static inline unsigned long long pgd_val(pgd_t x){ return PVOP_CALL2(unsigned long long, pv_mmu_ops.pgd_val, x.pgd, x.pgd >> 32);}static inline void set_pte(pte_t *ptep, pte_t pteval){ PVOP_VCALL3(pv_mmu_ops.set_pte, ptep, pteval.pte_low, pteval.pte_high);}static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval){ /* 5 arg words */ pv_mmu_ops.set_pte_at(mm, addr, ptep, pteval);}static inline void set_pte_atomic(pte_t *ptep, pte_t pteval){ PVOP_VCALL3(pv_mmu_ops.set_pte_atomic, ptep, pteval.pte_low, pteval.pte_high);}static inline void set_pte_present(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte){ /* 5 arg words */ pv_mmu_ops.set_pte_present(mm, addr, ptep, pte);}static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval){ PVOP_VCALL3(pv_mmu_ops.set_pmd, pmdp, pmdval.pmd, pmdval.pmd >> 32);}static inline void set_pud(pud_t *pudp, pud_t pudval){ PVOP_VCALL3(pv_mmu_ops.set_pud, pudp, pudval.pgd.pgd, pudval.pgd.pgd >> 32);}static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep){ PVOP_VCALL3(pv_mmu_ops.pte_clear, mm, addr, ptep);}static inline void pmd_clear(pmd_t *pmdp){ PVOP_VCALL1(pv_mmu_ops.pmd_clear, pmdp);}#else /* !CONFIG_X86_PAE */static inline pte_t __pte(unsigned long val){ return (pte_t) { PVOP_CALL1(unsigned long, pv_mmu_ops.make_pte, val) };}static inline pgd_t __pgd(unsigned long val){ return (pgd_t) { PVOP_CALL1(unsigned long, pv_mmu_ops.make_pgd, val) };}static inline unsigned long pte_val(pte_t x){ return PVOP_CALL1(unsigned long, pv_mmu_ops.pte_val, x.pte_low);}static inline unsigned long pgd_val(pgd_t x){ return PVOP_CALL1(unsigned long, pv_mmu_ops.pgd_val, x.pgd);}static inline void set_pte(pte_t *ptep, pte_t pteval){ PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, pteval.pte_low);}static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval){ PVOP_VCALL4(pv_mmu_ops.set_pte_at, mm, addr, ptep, pteval.pte_low);}static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval){ PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd);}#endif /* CONFIG_X86_PAE *//* Lazy mode for batching updates / context switch */enum paravirt_lazy_mode { PARAVIRT_LAZY_NONE, PARAVIRT_LAZY_MMU, PARAVIRT_LAZY_CPU,};enum paravirt_lazy_mode paravirt_get_lazy_mode(void);void paravirt_enter_lazy_cpu(void);void paravirt_leave_lazy_cpu(void);void paravirt_enter_lazy_mmu(void);void paravirt_leave_lazy_mmu(void);void paravirt_leave_lazy(enum paravirt_lazy_mode mode);#define __HAVE_ARCH_ENTER_LAZY_CPU_MODEstatic inline void arch_enter_lazy_cpu_mode(void){ PVOP_VCALL0(pv_cpu_ops.lazy_mode.enter);}static inline void arch_leave_lazy_cpu_mode(void){ PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave);}static inline void arch_flush_lazy_cpu_mode(void){ if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_CPU)) { arch_leave_lazy_cpu_mode(); arch_enter_lazy_cpu_mode(); }}#define __HAVE_ARCH_ENTER_LAZY_MMU_MODEstatic inline void arch_enter_lazy_mmu_mode(void){ PVOP_VCALL0(pv_mmu_ops.lazy_mode.enter);}static inline void arch_leave_lazy_mmu_mode(void){ PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);}static inline void arch_flush_lazy_mmu_mode(void){ if (unlikely(paravirt_get_lazy_mode() == PARAVIRT_LAZY_MMU)) { arch_leave_lazy_mmu_mode(); arch_enter_lazy_mmu_mode(); }}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_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[];static inline unsigned long __raw_local_save_flags(void){ unsigned long f; asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" PARAVIRT_CALL "popl %%edx; popl %%ecx") : "=a"(f) : paravirt_type(pv_irq_ops.save_fl), paravirt_clobber(CLBR_EAX) : "memory", "cc"); return f;}static inline void raw_local_irq_restore(unsigned long f){ asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" PARAVIRT_CALL "popl %%edx; popl %%ecx") : "=a"(f) : "0"(f), paravirt_type(pv_irq_ops.restore_fl), paravirt_clobber(CLBR_EAX) : "memory", "cc");}static inline void raw_local_irq_disable(void){ asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" PARAVIRT_CALL "popl %%edx; popl %%ecx") : : paravirt_type(pv_irq_ops.irq_disable), paravirt_clobber(CLBR_EAX) : "memory", "eax", "cc");}static inline void raw_local_irq_enable(void){ asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;" PARAVIRT_CALL "popl %%edx; popl %%ecx") : : paravirt_type(pv_irq_ops.irq_enable), paravirt_clobber(CLBR_EAX) : "memory", "eax", "cc");}static inline unsigned long __raw_local_irq_save(void){ unsigned long f; f = __raw_local_save_flags(); raw_local_irq_disable(); return f;}#define CLI_STRING \ _paravirt_alt("pushl %%ecx; pushl %%edx;" \ "call *%[paravirt_cli_opptr];" \ "popl %%edx; popl %%ecx", \ "%c[paravirt_cli_type]", "%c[paravirt_clobber]")#define STI_STRING \ _paravirt_alt("pushl %%ecx; pushl %%edx;" \ "call *%[paravirt_sti_opptr];" \ "popl %%edx; popl %%ecx", \ "%c[paravirt_sti_type]", "%c[paravirt_clobber]")#define CLI_STI_CLOBBERS , "%eax"#define CLI_STI_INPUT_ARGS \ , \ [paravirt_cli_type] "i" (PARAVIRT_PATCH(pv_irq_ops.irq_disable)), \ [paravirt_cli_opptr] "m" (pv_irq_ops.irq_disable), \ [paravirt_sti_type] "i" (PARAVIRT_PATCH(pv_irq_ops.irq_enable)), \ [paravirt_sti_opptr] "m" (pv_irq_ops.irq_enable), \ paravirt_clobber(CLBR_EAX)/* Make sure as little as possible of this mess escapes. */#undef PARAVIRT_CALL#undef __PVOP_CALL#undef __PVOP_VCALL#undef PVOP_VCALL0#undef PVOP_CALL0#undef PVOP_VCALL1#undef PVOP_CALL1#undef PVOP_VCALL2#undef PVOP_CALL2#undef PVOP_VCALL3#undef PVOP_CALL3#undef PVOP_VCALL4#undef PVOP_CALL4#else /* __ASSEMBLY__ */#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)#define PARA_SITE(ptype, clobbers, ops) \771:; \ ops; \772:; \ .pushsection .parainstructions,"a"; \ .long 771b; \ .byte ptype; \ .byte 772b-771b; \ .short clobbers; \ .popsection#define INTERRUPT_RETURN \ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_iret), CLBR_NONE, \ jmp *%cs:pv_cpu_ops+PV_CPU_iret)#define DISABLE_INTERRUPTS(clobbers) \ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \ pushl %eax; pushl %ecx; pushl %edx; \ call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \ popl %edx; popl %ecx; popl %eax) \#define ENABLE_INTERRUPTS(clobbers) \ PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \ pushl %eax; pushl %ecx; pushl %edx; \ call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \ popl %edx; popl %ecx; popl %eax)#define ENABLE_INTERRUPTS_SYSEXIT \ PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_sysexit), CLBR_NONE,\ jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_sysexit)#define GET_CR0_INTO_EAX \ push %ecx; push %edx; \ call *pv_cpu_ops+PV_CPU_read_cr0; \ pop %edx; pop %ecx#endif /* __ASSEMBLY__ */#endif /* CONFIG_PARAVIRT */#endif /* __ASM_PARAVIRT_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -