Newer
Older
Jeremy Fitzhardinge
committed
{
PVOP_VCALL2(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(set_pte_at, mm, addr, ptep, pteval.pte_low);
}
static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
PVOP_VCALL2(set_pmd, pmdp, pmdval.pud.pgd.pgd);
}
static inline pte_t raw_ptep_get_and_clear(pte_t *p)
{
return (pte_t) { PVOP_CALL1(unsigned long, ptep_get_and_clear, p) };
}
#endif /* CONFIG_X86_PAE */
/* 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
Jeremy Fitzhardinge
committed
static inline void arch_enter_lazy_cpu_mode(void)
{
PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_CPU);
}
static inline void arch_leave_lazy_cpu_mode(void)
{
PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_NONE);
}
static inline void arch_flush_lazy_cpu_mode(void)
{
PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_FLUSH);
}
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
Jeremy Fitzhardinge
committed
static inline void arch_enter_lazy_mmu_mode(void)
{
PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_MMU);
}
static inline void arch_leave_lazy_mmu_mode(void)
{
PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_NONE);
}
static inline void arch_flush_lazy_mmu_mode(void)
{
PVOP_VCALL1(set_lazy_mode, PARAVIRT_LAZY_FLUSH);
}
Jeremy Fitzhardinge
committed
void _paravirt_nop(void);
#define paravirt_nop ((void *)_paravirt_nop)
/* These all sit in the .parainstructions section to tell us what to patch. */
Jeremy Fitzhardinge
committed
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 */
};
Jeremy Fitzhardinge
committed
extern struct paravirt_patch_site __parainstructions[],
__parainstructions_end[];
static inline unsigned long __raw_local_save_flags(void)
{
unsigned long f;
Jeremy Fitzhardinge
committed
asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;"
PARAVIRT_CALL
"popl %%edx; popl %%ecx")
: "=a"(f)
: paravirt_type(save_fl),
Jeremy Fitzhardinge
committed
paravirt_clobber(CLBR_EAX)
Jeremy Fitzhardinge
committed
: "memory", "cc");
return f;
}
static inline void raw_local_irq_restore(unsigned long f)
{
Jeremy Fitzhardinge
committed
asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;"
PARAVIRT_CALL
"popl %%edx; popl %%ecx")
: "=a"(f)
: "0"(f),
paravirt_type(restore_fl),
paravirt_clobber(CLBR_EAX)
: "memory", "cc");
}
static inline void raw_local_irq_disable(void)
{
Jeremy Fitzhardinge
committed
asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;"
PARAVIRT_CALL
"popl %%edx; popl %%ecx")
:
: paravirt_type(irq_disable),
paravirt_clobber(CLBR_EAX)
: "memory", "eax", "cc");
}
static inline void raw_local_irq_enable(void)
{
Jeremy Fitzhardinge
committed
asm volatile(paravirt_alt("pushl %%ecx; pushl %%edx;"
PARAVIRT_CALL
"popl %%edx; popl %%ecx")
:
: paravirt_type(irq_enable),
paravirt_clobber(CLBR_EAX)
: "memory", "eax", "cc");
}
static inline unsigned long __raw_local_irq_save(void)
{
unsigned long f;
Jeremy Fitzhardinge
committed
f = __raw_local_save_flags();
raw_local_irq_disable();
return f;
}
Jeremy Fitzhardinge
committed
#define CLI_STRING \
_paravirt_alt("pushl %%ecx; pushl %%edx;" \
"call *paravirt_ops+%c[paravirt_cli_type]*4;" \
"popl %%edx; popl %%ecx", \
"%c[paravirt_cli_type]", "%c[paravirt_clobber]")
#define STI_STRING \
_paravirt_alt("pushl %%ecx; pushl %%edx;" \
"call *paravirt_ops+%c[paravirt_sti_type]*4;" \
"popl %%edx; popl %%ecx", \
"%c[paravirt_sti_type]", "%c[paravirt_clobber]")
#define CLI_STI_CLOBBERS , "%eax"
Jeremy Fitzhardinge
committed
#define CLI_STI_INPUT_ARGS \
, \
Jeremy Fitzhardinge
committed
[paravirt_cli_type] "i" (PARAVIRT_PATCH(irq_disable)), \
[paravirt_sti_type] "i" (PARAVIRT_PATCH(irq_enable)), \
paravirt_clobber(CLBR_EAX)
/* Make sure as little as possible of this mess escapes. */
Jeremy Fitzhardinge
committed
#undef PARAVIRT_CALL
Jeremy Fitzhardinge
committed
#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__ */
Jeremy Fitzhardinge
committed
#define PARA_PATCH(off) ((off) / 4)
#define PARA_SITE(ptype, clobbers, ops) \
771:; \
ops; \
772:; \
.pushsection .parainstructions,"a"; \
.long 771b; \
.byte ptype; \
.byte 772b-771b; \
.short clobbers; \
.popsection
Jeremy Fitzhardinge
committed
#define INTERRUPT_RETURN \
Jeremy Fitzhardinge
committed
PARA_SITE(PARA_PATCH(PARAVIRT_iret), CLBR_NONE, \
Jeremy Fitzhardinge
committed
jmp *%cs:paravirt_ops+PARAVIRT_iret)
#define DISABLE_INTERRUPTS(clobbers) \
PARA_SITE(PARA_PATCH(PARAVIRT_irq_disable), clobbers, \
Jeremy Fitzhardinge
committed
pushl %eax; pushl %ecx; pushl %edx; \
Jeremy Fitzhardinge
committed
call *%cs:paravirt_ops+PARAVIRT_irq_disable; \
Jeremy Fitzhardinge
committed
popl %edx; popl %ecx; popl %eax) \
Jeremy Fitzhardinge
committed
#define ENABLE_INTERRUPTS(clobbers) \
PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable), clobbers, \
Jeremy Fitzhardinge
committed
pushl %eax; pushl %ecx; pushl %edx; \
Jeremy Fitzhardinge
committed
call *%cs:paravirt_ops+PARAVIRT_irq_enable; \
Jeremy Fitzhardinge
committed
popl %edx; popl %ecx; popl %eax)
Jeremy Fitzhardinge
committed
#define ENABLE_INTERRUPTS_SYSEXIT \
Jeremy Fitzhardinge
committed
PARA_SITE(PARA_PATCH(PARAVIRT_irq_enable_sysexit), CLBR_NONE, \
Jeremy Fitzhardinge
committed
jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit)
#define GET_CR0_INTO_EAX \
Jeremy Fitzhardinge
committed
push %ecx; push %edx; \
call *paravirt_ops+PARAVIRT_read_cr0; \
pop %edx; pop %ecx
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_PARAVIRT */
#endif /* __ASM_PARAVIRT_H */