⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paravirt.h

📁 linux 内核源代码
💻 H
📖 第 1 页 / 共 3 页
字号:
			__ret = (rettype)((((u64)__edx) << 32) | __eax); \		} else {						\			asm volatile(pre				\				     paravirt_alt(PARAVIRT_CALL)	\				     post				\				     : "=a" (__eax), "=d" (__edx),	\				       "=c" (__ecx)			\				     : paravirt_type(op),		\				       paravirt_clobber(CLBR_ANY),	\				       ##__VA_ARGS__			\				     : "memory", "cc");			\			__ret = (rettype)__eax;				\		}							\		__ret;							\	})#define __PVOP_VCALL(op, pre, post, ...)				\	({								\		unsigned long __eax, __edx, __ecx;			\		asm volatile(pre					\			     paravirt_alt(PARAVIRT_CALL)		\			     post					\			     : "=a" (__eax), "=d" (__edx), "=c" (__ecx) \			     : paravirt_type(op),			\			       paravirt_clobber(CLBR_ANY),		\			       ##__VA_ARGS__				\			     : "memory", "cc");				\	})#define PVOP_CALL0(rettype, op)						\	__PVOP_CALL(rettype, op, "", "")#define PVOP_VCALL0(op)							\	__PVOP_VCALL(op, "", "")#define PVOP_CALL1(rettype, op, arg1)					\	__PVOP_CALL(rettype, op, "", "", "0" ((u32)(arg1)))#define PVOP_VCALL1(op, arg1)						\	__PVOP_VCALL(op, "", "", "0" ((u32)(arg1)))#define PVOP_CALL2(rettype, op, arg1, arg2)				\	__PVOP_CALL(rettype, op, "", "", "0" ((u32)(arg1)), "1" ((u32)(arg2)))#define PVOP_VCALL2(op, arg1, arg2)					\	__PVOP_VCALL(op, "", "", "0" ((u32)(arg1)), "1" ((u32)(arg2)))#define PVOP_CALL3(rettype, op, arg1, arg2, arg3)			\	__PVOP_CALL(rettype, op, "", "", "0" ((u32)(arg1)),		\		    "1"((u32)(arg2)), "2"((u32)(arg3)))#define PVOP_VCALL3(op, arg1, arg2, arg3)				\	__PVOP_VCALL(op, "", "", "0" ((u32)(arg1)), "1"((u32)(arg2)),	\		     "2"((u32)(arg3)))#define PVOP_CALL4(rettype, op, arg1, arg2, arg3, arg4)			\	__PVOP_CALL(rettype, op,					\		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\		    "0" ((u32)(arg1)), "1" ((u32)(arg2)),		\		    "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))#define PVOP_VCALL4(op, arg1, arg2, arg3, arg4)				\	__PVOP_VCALL(op,						\		    "push %[_arg4];", "lea 4(%%esp),%%esp;",		\		    "0" ((u32)(arg1)), "1" ((u32)(arg2)),		\		    "2" ((u32)(arg3)), [_arg4] "mr" ((u32)(arg4)))static inline int paravirt_enabled(void){	return pv_info.paravirt_enabled;}static inline void load_esp0(struct tss_struct *tss,			     struct thread_struct *thread){	PVOP_VCALL2(pv_cpu_ops.load_esp0, tss, thread);}#define ARCH_SETUP			pv_init_ops.arch_setup();static inline unsigned long get_wallclock(void){	return PVOP_CALL0(unsigned long, pv_time_ops.get_wallclock);}static inline int set_wallclock(unsigned long nowtime){	return PVOP_CALL1(int, pv_time_ops.set_wallclock, nowtime);}static inline void (*choose_time_init(void))(void){	return pv_time_ops.time_init;}/* The paravirtualized CPUID instruction. */static inline void __cpuid(unsigned int *eax, unsigned int *ebx,			   unsigned int *ecx, unsigned int *edx){	PVOP_VCALL4(pv_cpu_ops.cpuid, eax, ebx, ecx, edx);}/* * These special macros can be used to get or set a debugging register */static inline unsigned long paravirt_get_debugreg(int reg){	return PVOP_CALL1(unsigned long, pv_cpu_ops.get_debugreg, reg);}#define get_debugreg(var, reg) var = paravirt_get_debugreg(reg)static inline void set_debugreg(unsigned long val, int reg){	PVOP_VCALL2(pv_cpu_ops.set_debugreg, reg, val);}static inline void clts(void){	PVOP_VCALL0(pv_cpu_ops.clts);}static inline unsigned long read_cr0(void){	return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr0);}static inline void write_cr0(unsigned long x){	PVOP_VCALL1(pv_cpu_ops.write_cr0, x);}static inline unsigned long read_cr2(void){	return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr2);}static inline void write_cr2(unsigned long x){	PVOP_VCALL1(pv_mmu_ops.write_cr2, x);}static inline unsigned long read_cr3(void){	return PVOP_CALL0(unsigned long, pv_mmu_ops.read_cr3);}static inline void write_cr3(unsigned long x){	PVOP_VCALL1(pv_mmu_ops.write_cr3, x);}static inline unsigned long read_cr4(void){	return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4);}static inline unsigned long read_cr4_safe(void){	return PVOP_CALL0(unsigned long, pv_cpu_ops.read_cr4_safe);}static inline void write_cr4(unsigned long x){	PVOP_VCALL1(pv_cpu_ops.write_cr4, x);}static inline void raw_safe_halt(void){	PVOP_VCALL0(pv_irq_ops.safe_halt);}static inline void halt(void){	PVOP_VCALL0(pv_irq_ops.safe_halt);}static inline void wbinvd(void){	PVOP_VCALL0(pv_cpu_ops.wbinvd);}#define get_kernel_rpl()  (pv_info.kernel_rpl)static inline u64 paravirt_read_msr(unsigned msr, int *err){	return PVOP_CALL2(u64, pv_cpu_ops.read_msr, msr, err);}static inline int paravirt_write_msr(unsigned msr, unsigned low, unsigned high){	return PVOP_CALL3(int, pv_cpu_ops.write_msr, msr, low, high);}/* These should all do BUG_ON(_err), but our headers are too tangled. */#define rdmsr(msr,val1,val2) do {		\	int _err;				\	u64 _l = paravirt_read_msr(msr, &_err);	\	val1 = (u32)_l;				\	val2 = _l >> 32;			\} while(0)#define wrmsr(msr,val1,val2) do {		\	paravirt_write_msr(msr, val1, val2);	\} while(0)#define rdmsrl(msr,val) do {			\	int _err;				\	val = paravirt_read_msr(msr, &_err);	\} while(0)#define wrmsrl(msr,val)		wrmsr(msr, (u32)((u64)(val)), ((u64)(val))>>32)#define wrmsr_safe(msr,a,b)	paravirt_write_msr(msr, a, b)/* rdmsr with exception handling */#define rdmsr_safe(msr,a,b) ({			\	int _err;				\	u64 _l = paravirt_read_msr(msr, &_err);	\	(*a) = (u32)_l;				\	(*b) = _l >> 32;			\	_err; })static inline u64 paravirt_read_tsc(void){	return PVOP_CALL0(u64, pv_cpu_ops.read_tsc);}#define rdtscl(low) do {			\	u64 _l = paravirt_read_tsc();		\	low = (int)_l;				\} while(0)#define rdtscll(val) (val = paravirt_read_tsc())static inline unsigned long long paravirt_sched_clock(void){	return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);}#define calculate_cpu_khz() (pv_time_ops.get_cpu_khz())#define write_tsc(val1,val2) wrmsr(0x10, val1, val2)static inline unsigned long long paravirt_read_pmc(int counter){	return PVOP_CALL1(u64, pv_cpu_ops.read_pmc, counter);}#define rdpmc(counter,low,high) do {		\	u64 _l = paravirt_read_pmc(counter);	\	low = (u32)_l;				\	high = _l >> 32;			\} while(0)static inline void load_TR_desc(void){	PVOP_VCALL0(pv_cpu_ops.load_tr_desc);}static inline void load_gdt(const struct Xgt_desc_struct *dtr){	PVOP_VCALL1(pv_cpu_ops.load_gdt, dtr);}static inline void load_idt(const struct Xgt_desc_struct *dtr){	PVOP_VCALL1(pv_cpu_ops.load_idt, dtr);}static inline void set_ldt(const void *addr, unsigned entries){	PVOP_VCALL2(pv_cpu_ops.set_ldt, addr, entries);}static inline void store_gdt(struct Xgt_desc_struct *dtr){	PVOP_VCALL1(pv_cpu_ops.store_gdt, dtr);}static inline void store_idt(struct Xgt_desc_struct *dtr){	PVOP_VCALL1(pv_cpu_ops.store_idt, dtr);}static inline unsigned long paravirt_store_tr(void){	return PVOP_CALL0(unsigned long, pv_cpu_ops.store_tr);}#define store_tr(tr)	((tr) = paravirt_store_tr())static inline void load_TLS(struct thread_struct *t, unsigned cpu){	PVOP_VCALL2(pv_cpu_ops.load_tls, t, cpu);}static inline void write_ldt_entry(void *dt, int entry, u32 low, u32 high){	PVOP_VCALL4(pv_cpu_ops.write_ldt_entry, dt, entry, low, high);}static inline void write_gdt_entry(void *dt, int entry, u32 low, u32 high){	PVOP_VCALL4(pv_cpu_ops.write_gdt_entry, dt, entry, low, high);}static inline void write_idt_entry(void *dt, int entry, u32 low, u32 high){	PVOP_VCALL4(pv_cpu_ops.write_idt_entry, dt, entry, low, high);}static inline void set_iopl_mask(unsigned mask){	PVOP_VCALL1(pv_cpu_ops.set_iopl_mask, mask);}/* The paravirtualized I/O functions */static inline void slow_down_io(void) {	pv_cpu_ops.io_delay();#ifdef REALLY_SLOW_IO	pv_cpu_ops.io_delay();	pv_cpu_ops.io_delay();	pv_cpu_ops.io_delay();#endif}#ifdef CONFIG_X86_LOCAL_APIC/* * Basic functions accessing APICs. */static inline void apic_write(unsigned long reg, unsigned long v){	PVOP_VCALL2(pv_apic_ops.apic_write, reg, v);}static inline void apic_write_atomic(unsigned long reg, unsigned long v){	PVOP_VCALL2(pv_apic_ops.apic_write_atomic, reg, v);}static inline unsigned long apic_read(unsigned long reg){	return PVOP_CALL1(unsigned long, pv_apic_ops.apic_read, reg);}static inline void setup_boot_clock(void){	PVOP_VCALL0(pv_apic_ops.setup_boot_clock);}static inline void setup_secondary_clock(void){	PVOP_VCALL0(pv_apic_ops.setup_secondary_clock);}#endifstatic inline void paravirt_post_allocator_init(void){	if (pv_init_ops.post_allocator_init)		(*pv_init_ops.post_allocator_init)();}static inline void paravirt_pagetable_setup_start(pgd_t *base){	(*pv_mmu_ops.pagetable_setup_start)(base);}static inline void paravirt_pagetable_setup_done(pgd_t *base){	(*pv_mmu_ops.pagetable_setup_done)(base);}#ifdef CONFIG_SMPstatic inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,				    unsigned long start_esp){	PVOP_VCALL3(pv_apic_ops.startup_ipi_hook,		    phys_apicid, start_eip, start_esp);}#endifstatic inline void paravirt_activate_mm(struct mm_struct *prev,					struct mm_struct *next){	PVOP_VCALL2(pv_mmu_ops.activate_mm, prev, next);}static inline void arch_dup_mmap(struct mm_struct *oldmm,				 struct mm_struct *mm){	PVOP_VCALL2(pv_mmu_ops.dup_mmap, oldmm, mm);}static inline void arch_exit_mmap(struct mm_struct *mm){	PVOP_VCALL1(pv_mmu_ops.exit_mmap, mm);}static inline void __flush_tlb(void){	PVOP_VCALL0(pv_mmu_ops.flush_tlb_user);}static inline void __flush_tlb_global(void){	PVOP_VCALL0(pv_mmu_ops.flush_tlb_kernel);}static inline void __flush_tlb_single(unsigned long addr){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -