Newer
Older
Jeremy Fitzhardinge
committed
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
static inline pgd_t __pgd(unsigned long val)
{
return (pgd_t) { PVOP_CALL1(unsigned long, make_pgd, val) };
}
static inline unsigned long pte_val(pte_t x)
{
return PVOP_CALL1(unsigned long, pte_val, x.pte_low);
}
static inline unsigned long pgd_val(pgd_t x)
{
return PVOP_CALL1(unsigned long, pgd_val, x.pgd);
}
static inline void set_pte(pte_t *ptep, pte_t pteval)
{
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 */
#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 */