1#include <asm/paravirt.h> 2#include <asm/asm-offsets.h> 3#include <linux/stringify.h> 4 5DEF_NATIVE(pv_irq_ops, irq_disable, "cli"); 6DEF_NATIVE(pv_irq_ops, irq_enable, "sti"); 7DEF_NATIVE(pv_irq_ops, restore_fl, "pushq %rdi; popfq"); 8DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax"); 9DEF_NATIVE(pv_cpu_ops, iret, "iretq"); 10DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax"); 11DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax"); 12DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3"); 13DEF_NATIVE(pv_mmu_ops, flush_tlb_single, "invlpg (%rdi)"); 14DEF_NATIVE(pv_cpu_ops, clts, "clts"); 15DEF_NATIVE(pv_cpu_ops, wbinvd, "wbinvd"); 16 17DEF_NATIVE(pv_cpu_ops, irq_enable_sysexit, "swapgs; sti; sysexit"); 18DEF_NATIVE(pv_cpu_ops, usergs_sysret64, "swapgs; sysretq"); 19DEF_NATIVE(pv_cpu_ops, usergs_sysret32, "swapgs; sysretl"); 20DEF_NATIVE(pv_cpu_ops, swapgs, "swapgs"); 21 22unsigned native_patch(u8 type, u16 clobbers, void *ibuf, 23 unsigned long addr, unsigned len) 24{ 25 const unsigned char *start, *end; 26 unsigned ret; 27 28#define PATCH_SITE(ops, x) \ 29 case PARAVIRT_PATCH(ops.x): \ 30 start = start_##ops##_##x; \ 31 end = end_##ops##_##x; \ 32 goto patch_site 33 switch(type) { 34 PATCH_SITE(pv_irq_ops, restore_fl); 35 PATCH_SITE(pv_irq_ops, save_fl); 36 PATCH_SITE(pv_irq_ops, irq_enable); 37 PATCH_SITE(pv_irq_ops, irq_disable); 38 PATCH_SITE(pv_cpu_ops, iret); 39 PATCH_SITE(pv_cpu_ops, irq_enable_sysexit); 40 PATCH_SITE(pv_cpu_ops, usergs_sysret32); 41 PATCH_SITE(pv_cpu_ops, usergs_sysret64); 42 PATCH_SITE(pv_cpu_ops, swapgs); 43 PATCH_SITE(pv_mmu_ops, read_cr2); 44 PATCH_SITE(pv_mmu_ops, read_cr3); 45 PATCH_SITE(pv_mmu_ops, write_cr3); 46 PATCH_SITE(pv_cpu_ops, clts); 47 PATCH_SITE(pv_mmu_ops, flush_tlb_single); 48 PATCH_SITE(pv_cpu_ops, wbinvd); 49 50 patch_site: 51 ret = paravirt_patch_insns(ibuf, len, start, end); 52 break; 53 54 default: 55 ret = paravirt_patch_default(type, clobbers, ibuf, addr, len); 56 break; 57 } 58#undef PATCH_SITE 59 return ret; 60} 61

