Newer
Older
Jeremy Fitzhardinge
committed
static inline void set_pte(pte_t *ptep, pte_t pteval)
{
PVOP_VCALL2(pv_mmu_ops.set_pte, ptep, pteval.pte_low);
Jeremy Fitzhardinge
committed
}
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);
Jeremy Fitzhardinge
committed
}
static inline void set_pmd(pmd_t *pmdp, pmd_t pmdval)
{
PVOP_VCALL2(pv_mmu_ops.set_pmd, pmdp, pmdval.pud.pgd.pgd);
Jeremy Fitzhardinge
committed
}
#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_MODE
Jeremy Fitzhardinge
committed
static inline void arch_enter_lazy_cpu_mode(void)
{
PVOP_VCALL0(pv_cpu_ops.lazy_mode.enter);
Jeremy Fitzhardinge
committed
}
static inline void arch_leave_lazy_cpu_mode(void)
{
PVOP_VCALL0(pv_cpu_ops.lazy_mode.leave);
Jeremy Fitzhardinge
committed
}
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();
}
Jeremy Fitzhardinge
committed
}
#define __HAVE_ARCH_ENTER_LAZY_MMU_MODE
Jeremy Fitzhardinge
committed
static inline void arch_enter_lazy_mmu_mode(void)
{
PVOP_VCALL0(pv_mmu_ops.lazy_mode.enter);
Jeremy Fitzhardinge
committed
}
static inline void arch_leave_lazy_mmu_mode(void)
{
PVOP_VCALL0(pv_mmu_ops.lazy_mode.leave);
Jeremy Fitzhardinge
committed
}
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();
}
Jeremy Fitzhardinge
committed
}
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(pv_irq_ops.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(pv_irq_ops.restore_fl),
Jeremy Fitzhardinge
committed
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(pv_irq_ops.irq_disable),
Jeremy Fitzhardinge
committed
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(pv_irq_ops.irq_enable),
Jeremy Fitzhardinge
committed
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;
}
/* Make sure as little as possible of this mess escapes. */
Jeremy Fitzhardinge
committed
#undef PARAVIRT_CALL
#undef __PVOP_CALL
#undef __PVOP_VCALL
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__ */
#define PARA_PATCH(struct, off) ((PARAVIRT_PATCH_##struct + (off)) / 4)
Jeremy Fitzhardinge
committed
#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)
Jeremy Fitzhardinge
committed
#define DISABLE_INTERRUPTS(clobbers) \
PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_disable), clobbers, \
Jeremy Fitzhardinge
committed
pushl %eax; pushl %ecx; pushl %edx; \
call *%cs:pv_irq_ops+PV_IRQ_irq_disable; \
Jeremy Fitzhardinge
committed
popl %edx; popl %ecx; popl %eax) \
Jeremy Fitzhardinge
committed
#define ENABLE_INTERRUPTS(clobbers) \
PARA_SITE(PARA_PATCH(pv_irq_ops, PV_IRQ_irq_enable), clobbers, \
Jeremy Fitzhardinge
committed
pushl %eax; pushl %ecx; pushl %edx; \
call *%cs:pv_irq_ops+PV_IRQ_irq_enable; \
Jeremy Fitzhardinge
committed
popl %edx; popl %ecx; popl %eax)
Jeremy Fitzhardinge
committed
#define ENABLE_INTERRUPTS_SYSCALL_RET \
PARA_SITE(PARA_PATCH(pv_cpu_ops, PV_CPU_irq_enable_syscall_ret),\
CLBR_NONE, \
jmp *%cs:pv_cpu_ops+PV_CPU_irq_enable_syscall_ret)
#define GET_CR0_INTO_EAX \
Jeremy Fitzhardinge
committed
push %ecx; push %edx; \
call *pv_cpu_ops+PV_CPU_read_cr0; \
Jeremy Fitzhardinge
committed
pop %edx; pop %ecx
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_PARAVIRT */
#endif /* __ASM_PARAVIRT_H */