📄 paravirt.h
字号:
__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 + -