Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 paravirt updates from Ingo Molnar:
"A handful of paravirt patching code enhancements to make it more
robust against patching failures, and related cleanups and not so
related cleanups - by Thomas Gleixner and myself"

* 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/paravirt: Rename paravirt_patch_site::instrtype to paravirt_patch_site::type
x86/paravirt: Standardize 'insn_buff' variable names
x86/paravirt: Match paravirt patchlet field definition ordering to initialization ordering
x86/paravirt: Replace the paravirt patch asm magic
x86/paravirt: Unify the 32/64 bit paravirt patching code
x86/paravirt: Detect over-sized patching bugs in paravirt_patch_call()
x86/paravirt: Detect over-sized patching bugs in paravirt_patch_insns()
x86/paravirt: Remove bogus extern declarations

+213 -237
+4 -4
arch/x86/events/intel/ds.c
··· 337 337 struct debug_store *ds = hwev->ds; 338 338 size_t bsiz = x86_pmu.pebs_buffer_size; 339 339 int max, node = cpu_to_node(cpu); 340 - void *buffer, *ibuffer, *cea; 340 + void *buffer, *insn_buff, *cea; 341 341 342 342 if (!x86_pmu.pebs) 343 343 return 0; ··· 351 351 * buffer then. 352 352 */ 353 353 if (x86_pmu.intel_cap.pebs_format < 2) { 354 - ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node); 355 - if (!ibuffer) { 354 + insn_buff = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node); 355 + if (!insn_buff) { 356 356 dsfree_pages(buffer, bsiz); 357 357 return -ENOMEM; 358 358 } 359 - per_cpu(insn_buffer, cpu) = ibuffer; 359 + per_cpu(insn_buffer, cpu) = insn_buff; 360 360 } 361 361 hwev->ds_pebs_vaddr = buffer; 362 362 /* Update the cpu entry area mapping */
+7 -14
arch/x86/include/asm/paravirt_types.h
··· 88 88 * the number of bytes of code generated, as we nop pad the 89 89 * rest in generic code. 90 90 */ 91 - unsigned (*patch)(u8 type, void *insnbuf, 91 + unsigned (*patch)(u8 type, void *insn_buff, 92 92 unsigned long addr, unsigned len); 93 93 } __no_randomize_layout; 94 94 ··· 370 370 /* Simple instruction patching code. */ 371 371 #define NATIVE_LABEL(a,x,b) "\n\t.globl " a #x "_" #b "\n" a #x "_" #b ":\n\t" 372 372 373 - #define DEF_NATIVE(ops, name, code) \ 374 - __visible extern const char start_##ops##_##name[], end_##ops##_##name[]; \ 375 - asm(NATIVE_LABEL("start_", ops, name) code NATIVE_LABEL("end_", ops, name)) 373 + unsigned paravirt_patch_ident_64(void *insn_buff, unsigned len); 374 + unsigned paravirt_patch_default(u8 type, void *insn_buff, unsigned long addr, unsigned len); 375 + unsigned paravirt_patch_insns(void *insn_buff, unsigned len, const char *start, const char *end); 376 376 377 - unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len); 378 - unsigned paravirt_patch_default(u8 type, void *insnbuf, 379 - unsigned long addr, unsigned len); 380 - 381 - unsigned paravirt_patch_insns(void *insnbuf, unsigned len, 382 - const char *start, const char *end); 383 - 384 - unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len); 377 + unsigned native_patch(u8 type, void *insn_buff, unsigned long addr, unsigned len); 385 378 386 379 int paravirt_disable_iospace(void); 387 380 ··· 672 679 673 680 /* These all sit in the .parainstructions section to tell us what to patch. */ 674 681 struct paravirt_patch_site { 675 - u8 *instr; /* original instructions */ 676 - u8 instrtype; /* type of this instruction */ 682 + u8 *instr; /* original instructions */ 683 + u8 type; /* type of this instruction */ 677 684 u8 len; /* length of original instruction */ 678 685 }; 679 686
+2 -2
arch/x86/kernel/Makefile
··· 30 30 31 31 OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y 32 32 OBJECT_FILES_NON_STANDARD_test_nx.o := y 33 - OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y 33 + OBJECT_FILES_NON_STANDARD_paravirt_patch.o := y 34 34 35 35 ifdef CONFIG_FRAME_POINTER 36 36 OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y ··· 112 112 obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o 113 113 114 114 obj-$(CONFIG_KVM_GUEST) += kvm.o kvmclock.o 115 - obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o 115 + obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch.o 116 116 obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o 117 117 obj-$(CONFIG_PARAVIRT_CLOCK) += pvclock.o 118 118 obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o
+26 -27
arch/x86/kernel/alternative.c
··· 278 278 } 279 279 280 280 static void __init_or_module 281 - recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insnbuf) 281 + recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insn_buff) 282 282 { 283 283 u8 *next_rip, *tgt_rip; 284 284 s32 n_dspl, o_dspl; ··· 287 287 if (a->replacementlen != 5) 288 288 return; 289 289 290 - o_dspl = *(s32 *)(insnbuf + 1); 290 + o_dspl = *(s32 *)(insn_buff + 1); 291 291 292 292 /* next_rip of the replacement JMP */ 293 293 next_rip = repl_insn + a->replacementlen; ··· 313 313 two_byte_jmp: 314 314 n_dspl -= 2; 315 315 316 - insnbuf[0] = 0xeb; 317 - insnbuf[1] = (s8)n_dspl; 318 - add_nops(insnbuf + 2, 3); 316 + insn_buff[0] = 0xeb; 317 + insn_buff[1] = (s8)n_dspl; 318 + add_nops(insn_buff + 2, 3); 319 319 320 320 repl_len = 2; 321 321 goto done; ··· 323 323 five_byte_jmp: 324 324 n_dspl -= 5; 325 325 326 - insnbuf[0] = 0xe9; 327 - *(s32 *)&insnbuf[1] = n_dspl; 326 + insn_buff[0] = 0xe9; 327 + *(s32 *)&insn_buff[1] = n_dspl; 328 328 329 329 repl_len = 5; 330 330 ··· 371 371 { 372 372 struct alt_instr *a; 373 373 u8 *instr, *replacement; 374 - u8 insnbuf[MAX_PATCH_LEN]; 374 + u8 insn_buff[MAX_PATCH_LEN]; 375 375 376 376 DPRINTK("alt table %px, -> %px", start, end); 377 377 /* ··· 384 384 * order. 385 385 */ 386 386 for (a = start; a < end; a++) { 387 - int insnbuf_sz = 0; 387 + int insn_buff_sz = 0; 388 388 389 389 instr = (u8 *)&a->instr_offset + a->instr_offset; 390 390 replacement = (u8 *)&a->repl_offset + a->repl_offset; 391 - BUG_ON(a->instrlen > sizeof(insnbuf)); 391 + BUG_ON(a->instrlen > sizeof(insn_buff)); 392 392 BUG_ON(a->cpuid >= (NCAPINTS + NBUGINTS) * 32); 393 393 if (!boot_cpu_has(a->cpuid)) { 394 394 if (a->padlen > 1) ··· 406 406 DUMP_BYTES(instr, a->instrlen, "%px: old_insn: ", instr); 407 407 DUMP_BYTES(replacement, a->replacementlen, "%px: rpl_insn: ", replacement); 408 408 409 - memcpy(insnbuf, replacement, a->replacementlen); 410 - insnbuf_sz = a->replacementlen; 409 + memcpy(insn_buff, replacement, a->replacementlen); 410 + insn_buff_sz = a->replacementlen; 411 411 412 412 /* 413 413 * 0xe8 is a relative jump; fix the offset. ··· 415 415 * Instruction length is checked before the opcode to avoid 416 416 * accessing uninitialized bytes for zero-length replacements. 417 417 */ 418 - if (a->replacementlen == 5 && *insnbuf == 0xe8) { 419 - *(s32 *)(insnbuf + 1) += replacement - instr; 418 + if (a->replacementlen == 5 && *insn_buff == 0xe8) { 419 + *(s32 *)(insn_buff + 1) += replacement - instr; 420 420 DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx", 421 - *(s32 *)(insnbuf + 1), 422 - (unsigned long)instr + *(s32 *)(insnbuf + 1) + 5); 421 + *(s32 *)(insn_buff + 1), 422 + (unsigned long)instr + *(s32 *)(insn_buff + 1) + 5); 423 423 } 424 424 425 425 if (a->replacementlen && is_jmp(replacement[0])) 426 - recompute_jump(a, instr, replacement, insnbuf); 426 + recompute_jump(a, instr, replacement, insn_buff); 427 427 428 428 if (a->instrlen > a->replacementlen) { 429 - add_nops(insnbuf + a->replacementlen, 429 + add_nops(insn_buff + a->replacementlen, 430 430 a->instrlen - a->replacementlen); 431 - insnbuf_sz += a->instrlen - a->replacementlen; 431 + insn_buff_sz += a->instrlen - a->replacementlen; 432 432 } 433 - DUMP_BYTES(insnbuf, insnbuf_sz, "%px: final_insn: ", instr); 433 + DUMP_BYTES(insn_buff, insn_buff_sz, "%px: final_insn: ", instr); 434 434 435 - text_poke_early(instr, insnbuf, insnbuf_sz); 435 + text_poke_early(instr, insn_buff, insn_buff_sz); 436 436 } 437 437 } 438 438 ··· 594 594 struct paravirt_patch_site *end) 595 595 { 596 596 struct paravirt_patch_site *p; 597 - char insnbuf[MAX_PATCH_LEN]; 597 + char insn_buff[MAX_PATCH_LEN]; 598 598 599 599 for (p = start; p < end; p++) { 600 600 unsigned int used; 601 601 602 602 BUG_ON(p->len > MAX_PATCH_LEN); 603 603 /* prep the buffer with the original instructions */ 604 - memcpy(insnbuf, p->instr, p->len); 605 - used = pv_ops.init.patch(p->instrtype, insnbuf, 606 - (unsigned long)p->instr, p->len); 604 + memcpy(insn_buff, p->instr, p->len); 605 + used = pv_ops.init.patch(p->type, insn_buff, (unsigned long)p->instr, p->len); 607 606 608 607 BUG_ON(used > p->len); 609 608 610 609 /* Pad the rest with nops */ 611 - add_nops(insnbuf + used, p->len - used); 612 - text_poke_early(p->instr, insnbuf, p->len); 610 + add_nops(insn_buff + used, p->len - used); 611 + text_poke_early(p->instr, insn_buff, p->len); 613 612 } 614 613 } 615 614 extern struct paravirt_patch_site __start_parainstructions[],
+8 -8
arch/x86/kernel/kprobes/opt.c
··· 422 422 void arch_optimize_kprobes(struct list_head *oplist) 423 423 { 424 424 struct optimized_kprobe *op, *tmp; 425 - u8 insn_buf[RELATIVEJUMP_SIZE]; 425 + u8 insn_buff[RELATIVEJUMP_SIZE]; 426 426 427 427 list_for_each_entry_safe(op, tmp, oplist, list) { 428 428 s32 rel = (s32)((long)op->optinsn.insn - ··· 434 434 memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE, 435 435 RELATIVE_ADDR_SIZE); 436 436 437 - insn_buf[0] = RELATIVEJUMP_OPCODE; 438 - *(s32 *)(&insn_buf[1]) = rel; 437 + insn_buff[0] = RELATIVEJUMP_OPCODE; 438 + *(s32 *)(&insn_buff[1]) = rel; 439 439 440 - text_poke_bp(op->kp.addr, insn_buf, RELATIVEJUMP_SIZE, 440 + text_poke_bp(op->kp.addr, insn_buff, RELATIVEJUMP_SIZE, 441 441 op->optinsn.insn); 442 442 443 443 list_del_init(&op->list); ··· 447 447 /* Replace a relative jump with a breakpoint (int3). */ 448 448 void arch_unoptimize_kprobe(struct optimized_kprobe *op) 449 449 { 450 - u8 insn_buf[RELATIVEJUMP_SIZE]; 450 + u8 insn_buff[RELATIVEJUMP_SIZE]; 451 451 452 452 /* Set int3 to first byte for kprobes */ 453 - insn_buf[0] = BREAKPOINT_INSTRUCTION; 454 - memcpy(insn_buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE); 455 - text_poke_bp(op->kp.addr, insn_buf, RELATIVEJUMP_SIZE, 453 + insn_buff[0] = BREAKPOINT_INSTRUCTION; 454 + memcpy(insn_buff + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE); 455 + text_poke_bp(op->kp.addr, insn_buff, RELATIVEJUMP_SIZE, 456 456 op->optinsn.insn); 457 457 } 458 458
+22 -22
arch/x86/kernel/paravirt.c
··· 58 58 u32 delta; 59 59 } __attribute__((packed)); 60 60 61 - static unsigned paravirt_patch_call(void *insnbuf, const void *target, 61 + static unsigned paravirt_patch_call(void *insn_buff, const void *target, 62 62 unsigned long addr, unsigned len) 63 63 { 64 - struct branch *b = insnbuf; 65 - unsigned long delta = (unsigned long)target - (addr+5); 64 + const int call_len = 5; 65 + struct branch *b = insn_buff; 66 + unsigned long delta = (unsigned long)target - (addr+call_len); 66 67 67 - if (len < 5) { 68 - #ifdef CONFIG_RETPOLINE 69 - WARN_ONCE(1, "Failing to patch indirect CALL in %ps\n", (void *)addr); 70 - #endif 71 - return len; /* call too long for patch site */ 68 + if (len < call_len) { 69 + pr_warn("paravirt: Failed to patch indirect CALL at %ps\n", (void *)addr); 70 + /* Kernel might not be viable if patching fails, bail out: */ 71 + BUG_ON(1); 72 72 } 73 73 74 74 b->opcode = 0xe8; /* call */ 75 75 b->delta = delta; 76 - BUILD_BUG_ON(sizeof(*b) != 5); 76 + BUILD_BUG_ON(sizeof(*b) != call_len); 77 77 78 - return 5; 78 + return call_len; 79 79 } 80 80 81 81 #ifdef CONFIG_PARAVIRT_XXL ··· 85 85 return x; 86 86 } 87 87 88 - static unsigned paravirt_patch_jmp(void *insnbuf, const void *target, 88 + static unsigned paravirt_patch_jmp(void *insn_buff, const void *target, 89 89 unsigned long addr, unsigned len) 90 90 { 91 - struct branch *b = insnbuf; 91 + struct branch *b = insn_buff; 92 92 unsigned long delta = (unsigned long)target - (addr+5); 93 93 94 94 if (len < 5) { ··· 113 113 static_branch_disable(&virt_spin_lock_key); 114 114 } 115 115 116 - unsigned paravirt_patch_default(u8 type, void *insnbuf, 116 + unsigned paravirt_patch_default(u8 type, void *insn_buff, 117 117 unsigned long addr, unsigned len) 118 118 { 119 119 /* ··· 125 125 126 126 if (opfunc == NULL) 127 127 /* If there's no function, patch it with a ud2a (BUG) */ 128 - ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a)); 128 + ret = paravirt_patch_insns(insn_buff, len, ud2a, ud2a+sizeof(ud2a)); 129 129 else if (opfunc == _paravirt_nop) 130 130 ret = 0; 131 131 132 132 #ifdef CONFIG_PARAVIRT_XXL 133 133 /* identity functions just return their single argument */ 134 134 else if (opfunc == _paravirt_ident_64) 135 - ret = paravirt_patch_ident_64(insnbuf, len); 135 + ret = paravirt_patch_ident_64(insn_buff, len); 136 136 137 137 else if (type == PARAVIRT_PATCH(cpu.iret) || 138 138 type == PARAVIRT_PATCH(cpu.usergs_sysret64)) 139 139 /* If operation requires a jmp, then jmp */ 140 - ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len); 140 + ret = paravirt_patch_jmp(insn_buff, opfunc, addr, len); 141 141 #endif 142 142 else 143 143 /* Otherwise call the function. */ 144 - ret = paravirt_patch_call(insnbuf, opfunc, addr, len); 144 + ret = paravirt_patch_call(insn_buff, opfunc, addr, len); 145 145 146 146 return ret; 147 147 } 148 148 149 - unsigned paravirt_patch_insns(void *insnbuf, unsigned len, 149 + unsigned paravirt_patch_insns(void *insn_buff, unsigned len, 150 150 const char *start, const char *end) 151 151 { 152 152 unsigned insn_len = end - start; 153 153 154 - if (insn_len > len || start == NULL) 155 - insn_len = len; 156 - else 157 - memcpy(insnbuf, start, insn_len); 154 + /* Alternative instruction is too large for the patch site and we cannot continue: */ 155 + BUG_ON(insn_len > len || start == NULL); 156 + 157 + memcpy(insn_buff, start, insn_len); 158 158 159 159 return insn_len; 160 160 }
+126
arch/x86/kernel/paravirt_patch.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include <linux/stringify.h> 3 + 4 + #include <asm/paravirt.h> 5 + #include <asm/asm-offsets.h> 6 + 7 + #define PSTART(d, m) \ 8 + patch_data_##d.m 9 + 10 + #define PEND(d, m) \ 11 + (PSTART(d, m) + sizeof(patch_data_##d.m)) 12 + 13 + #define PATCH(d, m, insn_buff, len) \ 14 + paravirt_patch_insns(insn_buff, len, PSTART(d, m), PEND(d, m)) 15 + 16 + #define PATCH_CASE(ops, m, data, insn_buff, len) \ 17 + case PARAVIRT_PATCH(ops.m): \ 18 + return PATCH(data, ops##_##m, insn_buff, len) 19 + 20 + #ifdef CONFIG_PARAVIRT_XXL 21 + struct patch_xxl { 22 + const unsigned char irq_irq_disable[1]; 23 + const unsigned char irq_irq_enable[1]; 24 + const unsigned char irq_save_fl[2]; 25 + const unsigned char mmu_read_cr2[3]; 26 + const unsigned char mmu_read_cr3[3]; 27 + const unsigned char mmu_write_cr3[3]; 28 + const unsigned char irq_restore_fl[2]; 29 + # ifdef CONFIG_X86_64 30 + const unsigned char cpu_wbinvd[2]; 31 + const unsigned char cpu_usergs_sysret64[6]; 32 + const unsigned char cpu_swapgs[3]; 33 + const unsigned char mov64[3]; 34 + # else 35 + const unsigned char cpu_iret[1]; 36 + # endif 37 + }; 38 + 39 + static const struct patch_xxl patch_data_xxl = { 40 + .irq_irq_disable = { 0xfa }, // cli 41 + .irq_irq_enable = { 0xfb }, // sti 42 + .irq_save_fl = { 0x9c, 0x58 }, // pushf; pop %[re]ax 43 + .mmu_read_cr2 = { 0x0f, 0x20, 0xd0 }, // mov %cr2, %[re]ax 44 + .mmu_read_cr3 = { 0x0f, 0x20, 0xd8 }, // mov %cr3, %[re]ax 45 + # ifdef CONFIG_X86_64 46 + .mmu_write_cr3 = { 0x0f, 0x22, 0xdf }, // mov %rdi, %cr3 47 + .irq_restore_fl = { 0x57, 0x9d }, // push %rdi; popfq 48 + .cpu_wbinvd = { 0x0f, 0x09 }, // wbinvd 49 + .cpu_usergs_sysret64 = { 0x0f, 0x01, 0xf8, 50 + 0x48, 0x0f, 0x07 }, // swapgs; sysretq 51 + .cpu_swapgs = { 0x0f, 0x01, 0xf8 }, // swapgs 52 + .mov64 = { 0x48, 0x89, 0xf8 }, // mov %rdi, %rax 53 + # else 54 + .mmu_write_cr3 = { 0x0f, 0x22, 0xd8 }, // mov %eax, %cr3 55 + .irq_restore_fl = { 0x50, 0x9d }, // push %eax; popf 56 + .cpu_iret = { 0xcf }, // iret 57 + # endif 58 + }; 59 + 60 + unsigned int paravirt_patch_ident_64(void *insn_buff, unsigned int len) 61 + { 62 + #ifdef CONFIG_X86_64 63 + return PATCH(xxl, mov64, insn_buff, len); 64 + #endif 65 + return 0; 66 + } 67 + # endif /* CONFIG_PARAVIRT_XXL */ 68 + 69 + #ifdef CONFIG_PARAVIRT_SPINLOCKS 70 + struct patch_lock { 71 + unsigned char queued_spin_unlock[3]; 72 + unsigned char vcpu_is_preempted[2]; 73 + }; 74 + 75 + static const struct patch_lock patch_data_lock = { 76 + .vcpu_is_preempted = { 0x31, 0xc0 }, // xor %eax, %eax 77 + 78 + # ifdef CONFIG_X86_64 79 + .queued_spin_unlock = { 0xc6, 0x07, 0x00 }, // movb $0, (%rdi) 80 + # else 81 + .queued_spin_unlock = { 0xc6, 0x00, 0x00 }, // movb $0, (%eax) 82 + # endif 83 + }; 84 + #endif /* CONFIG_PARAVIRT_SPINLOCKS */ 85 + 86 + unsigned int native_patch(u8 type, void *insn_buff, unsigned long addr, 87 + unsigned int len) 88 + { 89 + switch (type) { 90 + 91 + #ifdef CONFIG_PARAVIRT_XXL 92 + PATCH_CASE(irq, restore_fl, xxl, insn_buff, len); 93 + PATCH_CASE(irq, save_fl, xxl, insn_buff, len); 94 + PATCH_CASE(irq, irq_enable, xxl, insn_buff, len); 95 + PATCH_CASE(irq, irq_disable, xxl, insn_buff, len); 96 + 97 + PATCH_CASE(mmu, read_cr2, xxl, insn_buff, len); 98 + PATCH_CASE(mmu, read_cr3, xxl, insn_buff, len); 99 + PATCH_CASE(mmu, write_cr3, xxl, insn_buff, len); 100 + 101 + # ifdef CONFIG_X86_64 102 + PATCH_CASE(cpu, usergs_sysret64, xxl, insn_buff, len); 103 + PATCH_CASE(cpu, swapgs, xxl, insn_buff, len); 104 + PATCH_CASE(cpu, wbinvd, xxl, insn_buff, len); 105 + # else 106 + PATCH_CASE(cpu, iret, xxl, insn_buff, len); 107 + # endif 108 + #endif 109 + 110 + #ifdef CONFIG_PARAVIRT_SPINLOCKS 111 + case PARAVIRT_PATCH(lock.queued_spin_unlock): 112 + if (pv_is_native_spin_unlock()) 113 + return PATCH(lock, queued_spin_unlock, insn_buff, len); 114 + break; 115 + 116 + case PARAVIRT_PATCH(lock.vcpu_is_preempted): 117 + if (pv_is_native_vcpu_is_preempted()) 118 + return PATCH(lock, vcpu_is_preempted, insn_buff, len); 119 + break; 120 + #endif 121 + default: 122 + break; 123 + } 124 + 125 + return paravirt_patch_default(type, insn_buff, addr, len); 126 + }
-67
arch/x86/kernel/paravirt_patch_32.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - #include <asm/paravirt.h> 3 - 4 - #ifdef CONFIG_PARAVIRT_XXL 5 - DEF_NATIVE(irq, irq_disable, "cli"); 6 - DEF_NATIVE(irq, irq_enable, "sti"); 7 - DEF_NATIVE(irq, restore_fl, "push %eax; popf"); 8 - DEF_NATIVE(irq, save_fl, "pushf; pop %eax"); 9 - DEF_NATIVE(cpu, iret, "iret"); 10 - DEF_NATIVE(mmu, read_cr2, "mov %cr2, %eax"); 11 - DEF_NATIVE(mmu, write_cr3, "mov %eax, %cr3"); 12 - DEF_NATIVE(mmu, read_cr3, "mov %cr3, %eax"); 13 - 14 - unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len) 15 - { 16 - /* arg in %edx:%eax, return in %edx:%eax */ 17 - return 0; 18 - } 19 - #endif 20 - 21 - #if defined(CONFIG_PARAVIRT_SPINLOCKS) 22 - DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%eax)"); 23 - DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax"); 24 - #endif 25 - 26 - extern bool pv_is_native_spin_unlock(void); 27 - extern bool pv_is_native_vcpu_is_preempted(void); 28 - 29 - unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len) 30 - { 31 - #define PATCH_SITE(ops, x) \ 32 - case PARAVIRT_PATCH(ops.x): \ 33 - return paravirt_patch_insns(ibuf, len, start_##ops##_##x, end_##ops##_##x) 34 - 35 - switch (type) { 36 - #ifdef CONFIG_PARAVIRT_XXL 37 - PATCH_SITE(irq, irq_disable); 38 - PATCH_SITE(irq, irq_enable); 39 - PATCH_SITE(irq, restore_fl); 40 - PATCH_SITE(irq, save_fl); 41 - PATCH_SITE(cpu, iret); 42 - PATCH_SITE(mmu, read_cr2); 43 - PATCH_SITE(mmu, read_cr3); 44 - PATCH_SITE(mmu, write_cr3); 45 - #endif 46 - #if defined(CONFIG_PARAVIRT_SPINLOCKS) 47 - case PARAVIRT_PATCH(lock.queued_spin_unlock): 48 - if (pv_is_native_spin_unlock()) 49 - return paravirt_patch_insns(ibuf, len, 50 - start_lock_queued_spin_unlock, 51 - end_lock_queued_spin_unlock); 52 - break; 53 - 54 - case PARAVIRT_PATCH(lock.vcpu_is_preempted): 55 - if (pv_is_native_vcpu_is_preempted()) 56 - return paravirt_patch_insns(ibuf, len, 57 - start_lock_vcpu_is_preempted, 58 - end_lock_vcpu_is_preempted); 59 - break; 60 - #endif 61 - 62 - default: 63 - break; 64 - } 65 - #undef PATCH_SITE 66 - return paravirt_patch_default(type, ibuf, addr, len); 67 - }
-75
arch/x86/kernel/paravirt_patch_64.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - #include <asm/paravirt.h> 3 - #include <asm/asm-offsets.h> 4 - #include <linux/stringify.h> 5 - 6 - #ifdef CONFIG_PARAVIRT_XXL 7 - DEF_NATIVE(irq, irq_disable, "cli"); 8 - DEF_NATIVE(irq, irq_enable, "sti"); 9 - DEF_NATIVE(irq, restore_fl, "pushq %rdi; popfq"); 10 - DEF_NATIVE(irq, save_fl, "pushfq; popq %rax"); 11 - DEF_NATIVE(mmu, read_cr2, "movq %cr2, %rax"); 12 - DEF_NATIVE(mmu, read_cr3, "movq %cr3, %rax"); 13 - DEF_NATIVE(mmu, write_cr3, "movq %rdi, %cr3"); 14 - DEF_NATIVE(cpu, wbinvd, "wbinvd"); 15 - 16 - DEF_NATIVE(cpu, usergs_sysret64, "swapgs; sysretq"); 17 - DEF_NATIVE(cpu, swapgs, "swapgs"); 18 - DEF_NATIVE(, mov64, "mov %rdi, %rax"); 19 - 20 - unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len) 21 - { 22 - return paravirt_patch_insns(insnbuf, len, 23 - start__mov64, end__mov64); 24 - } 25 - #endif 26 - 27 - #if defined(CONFIG_PARAVIRT_SPINLOCKS) 28 - DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%rdi)"); 29 - DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax"); 30 - #endif 31 - 32 - extern bool pv_is_native_spin_unlock(void); 33 - extern bool pv_is_native_vcpu_is_preempted(void); 34 - 35 - unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len) 36 - { 37 - #define PATCH_SITE(ops, x) \ 38 - case PARAVIRT_PATCH(ops.x): \ 39 - return paravirt_patch_insns(ibuf, len, start_##ops##_##x, end_##ops##_##x) 40 - 41 - switch (type) { 42 - #ifdef CONFIG_PARAVIRT_XXL 43 - PATCH_SITE(irq, restore_fl); 44 - PATCH_SITE(irq, save_fl); 45 - PATCH_SITE(irq, irq_enable); 46 - PATCH_SITE(irq, irq_disable); 47 - PATCH_SITE(cpu, usergs_sysret64); 48 - PATCH_SITE(cpu, swapgs); 49 - PATCH_SITE(cpu, wbinvd); 50 - PATCH_SITE(mmu, read_cr2); 51 - PATCH_SITE(mmu, read_cr3); 52 - PATCH_SITE(mmu, write_cr3); 53 - #endif 54 - #if defined(CONFIG_PARAVIRT_SPINLOCKS) 55 - case PARAVIRT_PATCH(lock.queued_spin_unlock): 56 - if (pv_is_native_spin_unlock()) 57 - return paravirt_patch_insns(ibuf, len, 58 - start_lock_queued_spin_unlock, 59 - end_lock_queued_spin_unlock); 60 - break; 61 - 62 - case PARAVIRT_PATCH(lock.vcpu_is_preempted): 63 - if (pv_is_native_vcpu_is_preempted()) 64 - return paravirt_patch_insns(ibuf, len, 65 - start_lock_vcpu_is_preempted, 66 - end_lock_vcpu_is_preempted); 67 - break; 68 - #endif 69 - 70 - default: 71 - break; 72 - } 73 - #undef PATCH_SITE 74 - return paravirt_patch_default(type, ibuf, addr, len); 75 - }
+4 -4
arch/x86/tools/insn_decoder_test.c
··· 111 111 int main(int argc, char **argv) 112 112 { 113 113 char line[BUFSIZE], sym[BUFSIZE] = "<unknown>"; 114 - unsigned char insn_buf[16]; 114 + unsigned char insn_buff[16]; 115 115 struct insn insn; 116 116 int insns = 0; 117 117 int warnings = 0; ··· 130 130 } 131 131 132 132 insns++; 133 - memset(insn_buf, 0, 16); 133 + memset(insn_buff, 0, 16); 134 134 strcpy(copy, line); 135 135 tab1 = strchr(copy, '\t'); 136 136 if (!tab1) ··· 143 143 *tab2 = '\0'; /* Characters beyond tab2 aren't examined */ 144 144 while (s < tab2) { 145 145 if (sscanf(s, "%x", &b) == 1) { 146 - insn_buf[nb++] = (unsigned char) b; 146 + insn_buff[nb++] = (unsigned char) b; 147 147 s += 3; 148 148 } else 149 149 break; 150 150 } 151 151 /* Decode an instruction */ 152 - insn_init(&insn, insn_buf, sizeof(insn_buf), x86_64); 152 + insn_init(&insn, insn_buff, sizeof(insn_buff), x86_64); 153 153 insn_get_length(&insn); 154 154 if (insn.length != nb) { 155 155 warnings++;
+14 -14
arch/x86/tools/insn_sanity.c
··· 83 83 } 84 84 85 85 static void dump_stream(FILE *fp, const char *msg, unsigned long nr_iter, 86 - unsigned char *insn_buf, struct insn *insn) 86 + unsigned char *insn_buff, struct insn *insn) 87 87 { 88 88 int i; 89 89 ··· 96 96 /* Input a decoded instruction sequence directly */ 97 97 fprintf(fp, " $ echo "); 98 98 for (i = 0; i < MAX_INSN_SIZE; i++) 99 - fprintf(fp, " %02x", insn_buf[i]); 99 + fprintf(fp, " %02x", insn_buff[i]); 100 100 fprintf(fp, " | %s -i -\n", prog); 101 101 102 102 if (!input_file) { ··· 124 124 } 125 125 126 126 /* Read given instruction sequence from the input file */ 127 - static int read_next_insn(unsigned char *insn_buf) 127 + static int read_next_insn(unsigned char *insn_buff) 128 128 { 129 129 char buf[256] = "", *tmp; 130 130 int i; ··· 134 134 return 0; 135 135 136 136 for (i = 0; i < MAX_INSN_SIZE; i++) { 137 - insn_buf[i] = (unsigned char)strtoul(tmp, &tmp, 16); 137 + insn_buff[i] = (unsigned char)strtoul(tmp, &tmp, 16); 138 138 if (*tmp != ' ') 139 139 break; 140 140 } ··· 142 142 return i; 143 143 } 144 144 145 - static int generate_insn(unsigned char *insn_buf) 145 + static int generate_insn(unsigned char *insn_buff) 146 146 { 147 147 int i; 148 148 149 149 if (input_file) 150 - return read_next_insn(insn_buf); 150 + return read_next_insn(insn_buff); 151 151 152 152 /* Fills buffer with random binary up to MAX_INSN_SIZE */ 153 153 for (i = 0; i < MAX_INSN_SIZE - 1; i += 2) 154 - *(unsigned short *)(&insn_buf[i]) = random() & 0xffff; 154 + *(unsigned short *)(&insn_buff[i]) = random() & 0xffff; 155 155 156 156 while (i < MAX_INSN_SIZE) 157 - insn_buf[i++] = random() & 0xff; 157 + insn_buff[i++] = random() & 0xff; 158 158 159 159 return i; 160 160 } ··· 226 226 int insns = 0; 227 227 int errors = 0; 228 228 unsigned long i; 229 - unsigned char insn_buf[MAX_INSN_SIZE * 2]; 229 + unsigned char insn_buff[MAX_INSN_SIZE * 2]; 230 230 231 231 parse_args(argc, argv); 232 232 233 233 /* Prepare stop bytes with NOPs */ 234 - memset(insn_buf + MAX_INSN_SIZE, INSN_NOP, MAX_INSN_SIZE); 234 + memset(insn_buff + MAX_INSN_SIZE, INSN_NOP, MAX_INSN_SIZE); 235 235 236 236 for (i = 0; i < iter_end; i++) { 237 - if (generate_insn(insn_buf) <= 0) 237 + if (generate_insn(insn_buff) <= 0) 238 238 break; 239 239 240 240 if (i < iter_start) /* Skip to given iteration number */ 241 241 continue; 242 242 243 243 /* Decode an instruction */ 244 - insn_init(&insn, insn_buf, sizeof(insn_buf), x86_64); 244 + insn_init(&insn, insn_buff, sizeof(insn_buff), x86_64); 245 245 insn_get_length(&insn); 246 246 247 247 if (insn.next_byte <= insn.kaddr || 248 248 insn.kaddr + MAX_INSN_SIZE < insn.next_byte) { 249 249 /* Access out-of-range memory */ 250 - dump_stream(stderr, "Error: Found an access violation", i, insn_buf, &insn); 250 + dump_stream(stderr, "Error: Found an access violation", i, insn_buff, &insn); 251 251 errors++; 252 252 } else if (verbose && !insn_complete(&insn)) 253 - dump_stream(stdout, "Info: Found an undecodable input", i, insn_buf, &insn); 253 + dump_stream(stdout, "Info: Found an undecodable input", i, insn_buff, &insn); 254 254 else if (verbose >= 2) 255 255 dump_insn(stdout, &insn); 256 256 insns++;