Merge branch 'x86-paravirt-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 00:34:44 +0000 (17:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 9 Jul 2019 00:34:44 +0000 (17:34 -0700)
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

arch/x86/events/intel/ds.c
arch/x86/include/asm/paravirt_types.h
arch/x86/kernel/Makefile
arch/x86/kernel/alternative.c
arch/x86/kernel/kprobes/opt.c
arch/x86/kernel/paravirt.c
arch/x86/kernel/paravirt_patch.c [new file with mode: 0644]
arch/x86/kernel/paravirt_patch_32.c [deleted file]
arch/x86/kernel/paravirt_patch_64.c [deleted file]
arch/x86/tools/insn_decoder_test.c
arch/x86/tools/insn_sanity.c

index 505c73dc6a730ee87cf9db820dd9b5a6c5848180..2c8db2c19328bcbf95e8c14b4f58e0d2d6d7d7ba 100644 (file)
@@ -337,7 +337,7 @@ static int alloc_pebs_buffer(int cpu)
        struct debug_store *ds = hwev->ds;
        size_t bsiz = x86_pmu.pebs_buffer_size;
        int max, node = cpu_to_node(cpu);
-       void *buffer, *ibuffer, *cea;
+       void *buffer, *insn_buff, *cea;
 
        if (!x86_pmu.pebs)
                return 0;
@@ -351,12 +351,12 @@ static int alloc_pebs_buffer(int cpu)
         * buffer then.
         */
        if (x86_pmu.intel_cap.pebs_format < 2) {
-               ibuffer = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
-               if (!ibuffer) {
+               insn_buff = kzalloc_node(PEBS_FIXUP_SIZE, GFP_KERNEL, node);
+               if (!insn_buff) {
                        dsfree_pages(buffer, bsiz);
                        return -ENOMEM;
                }
-               per_cpu(insn_buffer, cpu) = ibuffer;
+               per_cpu(insn_buffer, cpu) = insn_buff;
        }
        hwev->ds_pebs_vaddr = buffer;
        /* Update the cpu entry area mapping */
index 2474e434a6f72c42ed12f2ca6ab7ed2b4aeae08b..946f8f1f1efc54edf59112e7231a8ba498ab69a5 100644 (file)
@@ -88,7 +88,7 @@ struct pv_init_ops {
         * the number of bytes of code generated, as we nop pad the
         * rest in generic code.
         */
-       unsigned (*patch)(u8 type, void *insnbuf,
+       unsigned (*patch)(u8 type, void *insn_buff,
                          unsigned long addr, unsigned len);
 } __no_randomize_layout;
 
@@ -370,18 +370,11 @@ extern struct paravirt_patch_template pv_ops;
 /* Simple instruction patching code. */
 #define NATIVE_LABEL(a,x,b) "\n\t.globl " a #x "_" #b "\n" a #x "_" #b ":\n\t"
 
-#define DEF_NATIVE(ops, name, code)                                    \
-       __visible extern const char start_##ops##_##name[], end_##ops##_##name[];       \
-       asm(NATIVE_LABEL("start_", ops, name) code NATIVE_LABEL("end_", ops, name))
+unsigned paravirt_patch_ident_64(void *insn_buff, unsigned len);
+unsigned paravirt_patch_default(u8 type, void *insn_buff, unsigned long addr, unsigned len);
+unsigned paravirt_patch_insns(void *insn_buff, unsigned len, const char *start, const char *end);
 
-unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len);
-unsigned paravirt_patch_default(u8 type, void *insnbuf,
-                               unsigned long addr, unsigned len);
-
-unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
-                             const char *start, const char *end);
-
-unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len);
+unsigned native_patch(u8 type, void *insn_buff, unsigned long addr, unsigned len);
 
 int paravirt_disable_iospace(void);
 
@@ -679,8 +672,8 @@ u64 _paravirt_ident_64(u64);
 
 /* These all sit in the .parainstructions section to tell us what to patch. */
 struct paravirt_patch_site {
-       u8 *instr;              /* original instructions */
-       u8 instrtype;           /* type of this instruction */
+       u8 *instr;              /* original instructions */
+       u8 type;                /* type of this instruction */
        u8 len;                 /* length of original instruction */
 };
 
index ce1b5cc360a27ba13160856ddeffd4040ebeffca..3578ad248bc98319e3a0f5769615c72e191d5569 100644 (file)
@@ -30,7 +30,7 @@ KASAN_SANITIZE_paravirt.o                             := n
 
 OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o    := y
 OBJECT_FILES_NON_STANDARD_test_nx.o                    := y
-OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o     := y
+OBJECT_FILES_NON_STANDARD_paravirt_patch.o             := y
 
 ifdef CONFIG_FRAME_POINTER
 OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o             := y
@@ -112,7 +112,7 @@ obj-$(CONFIG_AMD_NB)                += amd_nb.o
 obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o
 
 obj-$(CONFIG_KVM_GUEST)                += kvm.o kvmclock.o
-obj-$(CONFIG_PARAVIRT)         += paravirt.o paravirt_patch_$(BITS).o
+obj-$(CONFIG_PARAVIRT)         += paravirt.o paravirt_patch.o
 obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= paravirt-spinlocks.o
 obj-$(CONFIG_PARAVIRT_CLOCK)   += pvclock.o
 obj-$(CONFIG_X86_PMEM_LEGACY_DEVICE) += pmem.o
index c3468b5242fdeec3edb0f81704049ed1bc658fc7..99ef8b6f9a1a5abf2e89c37a79da906d2103b66c 100644 (file)
@@ -278,7 +278,7 @@ static inline bool is_jmp(const u8 opcode)
 }
 
 static void __init_or_module
-recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insnbuf)
+recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insn_buff)
 {
        u8 *next_rip, *tgt_rip;
        s32 n_dspl, o_dspl;
@@ -287,7 +287,7 @@ recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insnbuf)
        if (a->replacementlen != 5)
                return;
 
-       o_dspl = *(s32 *)(insnbuf + 1);
+       o_dspl = *(s32 *)(insn_buff + 1);
 
        /* next_rip of the replacement JMP */
        next_rip = repl_insn + a->replacementlen;
@@ -313,9 +313,9 @@ recompute_jump(struct alt_instr *a, u8 *orig_insn, u8 *repl_insn, u8 *insnbuf)
 two_byte_jmp:
        n_dspl -= 2;
 
-       insnbuf[0] = 0xeb;
-       insnbuf[1] = (s8)n_dspl;
-       add_nops(insnbuf + 2, 3);
+       insn_buff[0] = 0xeb;
+       insn_buff[1] = (s8)n_dspl;
+       add_nops(insn_buff + 2, 3);
 
        repl_len = 2;
        goto done;
@@ -323,8 +323,8 @@ two_byte_jmp:
 five_byte_jmp:
        n_dspl -= 5;
 
-       insnbuf[0] = 0xe9;
-       *(s32 *)&insnbuf[1] = n_dspl;
+       insn_buff[0] = 0xe9;
+       *(s32 *)&insn_buff[1] = n_dspl;
 
        repl_len = 5;
 
@@ -371,7 +371,7 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
 {
        struct alt_instr *a;
        u8 *instr, *replacement;
-       u8 insnbuf[MAX_PATCH_LEN];
+       u8 insn_buff[MAX_PATCH_LEN];
 
        DPRINTK("alt table %px, -> %px", start, end);
        /*
@@ -384,11 +384,11 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
         * order.
         */
        for (a = start; a < end; a++) {
-               int insnbuf_sz = 0;
+               int insn_buff_sz = 0;
 
                instr = (u8 *)&a->instr_offset + a->instr_offset;
                replacement = (u8 *)&a->repl_offset + a->repl_offset;
-               BUG_ON(a->instrlen > sizeof(insnbuf));
+               BUG_ON(a->instrlen > sizeof(insn_buff));
                BUG_ON(a->cpuid >= (NCAPINTS + NBUGINTS) * 32);
                if (!boot_cpu_has(a->cpuid)) {
                        if (a->padlen > 1)
@@ -406,8 +406,8 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
                DUMP_BYTES(instr, a->instrlen, "%px: old_insn: ", instr);
                DUMP_BYTES(replacement, a->replacementlen, "%px: rpl_insn: ", replacement);
 
-               memcpy(insnbuf, replacement, a->replacementlen);
-               insnbuf_sz = a->replacementlen;
+               memcpy(insn_buff, replacement, a->replacementlen);
+               insn_buff_sz = a->replacementlen;
 
                /*
                 * 0xe8 is a relative jump; fix the offset.
@@ -415,24 +415,24 @@ void __init_or_module noinline apply_alternatives(struct alt_instr *start,
                 * Instruction length is checked before the opcode to avoid
                 * accessing uninitialized bytes for zero-length replacements.
                 */
-               if (a->replacementlen == 5 && *insnbuf == 0xe8) {
-                       *(s32 *)(insnbuf + 1) += replacement - instr;
+               if (a->replacementlen == 5 && *insn_buff == 0xe8) {
+                       *(s32 *)(insn_buff + 1) += replacement - instr;
                        DPRINTK("Fix CALL offset: 0x%x, CALL 0x%lx",
-                               *(s32 *)(insnbuf + 1),
-                               (unsigned long)instr + *(s32 *)(insnbuf + 1) + 5);
+                               *(s32 *)(insn_buff + 1),
+                               (unsigned long)instr + *(s32 *)(insn_buff + 1) + 5);
                }
 
                if (a->replacementlen && is_jmp(replacement[0]))
-                       recompute_jump(a, instr, replacement, insnbuf);
+                       recompute_jump(a, instr, replacement, insn_buff);
 
                if (a->instrlen > a->replacementlen) {
-                       add_nops(insnbuf + a->replacementlen,
+                       add_nops(insn_buff + a->replacementlen,
                                 a->instrlen - a->replacementlen);
-                       insnbuf_sz += a->instrlen - a->replacementlen;
+                       insn_buff_sz += a->instrlen - a->replacementlen;
                }
-               DUMP_BYTES(insnbuf, insnbuf_sz, "%px: final_insn: ", instr);
+               DUMP_BYTES(insn_buff, insn_buff_sz, "%px: final_insn: ", instr);
 
-               text_poke_early(instr, insnbuf, insnbuf_sz);
+               text_poke_early(instr, insn_buff, insn_buff_sz);
        }
 }
 
@@ -594,22 +594,21 @@ void __init_or_module apply_paravirt(struct paravirt_patch_site *start,
                                     struct paravirt_patch_site *end)
 {
        struct paravirt_patch_site *p;
-       char insnbuf[MAX_PATCH_LEN];
+       char insn_buff[MAX_PATCH_LEN];
 
        for (p = start; p < end; p++) {
                unsigned int used;
 
                BUG_ON(p->len > MAX_PATCH_LEN);
                /* prep the buffer with the original instructions */
-               memcpy(insnbuf, p->instr, p->len);
-               used = pv_ops.init.patch(p->instrtype, insnbuf,
-                                        (unsigned long)p->instr, p->len);
+               memcpy(insn_buff, p->instr, p->len);
+               used = pv_ops.init.patch(p->type, insn_buff, (unsigned long)p->instr, p->len);
 
                BUG_ON(used > p->len);
 
                /* Pad the rest with nops */
-               add_nops(insnbuf + used, p->len - used);
-               text_poke_early(p->instr, insnbuf, p->len);
+               add_nops(insn_buff + used, p->len - used);
+               text_poke_early(p->instr, insn_buff, p->len);
        }
 }
 extern struct paravirt_patch_site __start_parainstructions[],
index 282b4eb67e30366167102fb1ecd268f59e6a769b..9d4aedece363cc28c696be0dbfa1af8deaba9fa3 100644 (file)
@@ -422,7 +422,7 @@ err:
 void arch_optimize_kprobes(struct list_head *oplist)
 {
        struct optimized_kprobe *op, *tmp;
-       u8 insn_buf[RELATIVEJUMP_SIZE];
+       u8 insn_buff[RELATIVEJUMP_SIZE];
 
        list_for_each_entry_safe(op, tmp, oplist, list) {
                s32 rel = (s32)((long)op->optinsn.insn -
@@ -434,10 +434,10 @@ void arch_optimize_kprobes(struct list_head *oplist)
                memcpy(op->optinsn.copied_insn, op->kp.addr + INT3_SIZE,
                       RELATIVE_ADDR_SIZE);
 
-               insn_buf[0] = RELATIVEJUMP_OPCODE;
-               *(s32 *)(&insn_buf[1]) = rel;
+               insn_buff[0] = RELATIVEJUMP_OPCODE;
+               *(s32 *)(&insn_buff[1]) = rel;
 
-               text_poke_bp(op->kp.addr, insn_buf, RELATIVEJUMP_SIZE,
+               text_poke_bp(op->kp.addr, insn_buff, RELATIVEJUMP_SIZE,
                             op->optinsn.insn);
 
                list_del_init(&op->list);
@@ -447,12 +447,12 @@ void arch_optimize_kprobes(struct list_head *oplist)
 /* Replace a relative jump with a breakpoint (int3).  */
 void arch_unoptimize_kprobe(struct optimized_kprobe *op)
 {
-       u8 insn_buf[RELATIVEJUMP_SIZE];
+       u8 insn_buff[RELATIVEJUMP_SIZE];
 
        /* Set int3 to first byte for kprobes */
-       insn_buf[0] = BREAKPOINT_INSTRUCTION;
-       memcpy(insn_buf + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE);
-       text_poke_bp(op->kp.addr, insn_buf, RELATIVEJUMP_SIZE,
+       insn_buff[0] = BREAKPOINT_INSTRUCTION;
+       memcpy(insn_buff + 1, op->optinsn.copied_insn, RELATIVE_ADDR_SIZE);
+       text_poke_bp(op->kp.addr, insn_buff, RELATIVEJUMP_SIZE,
                     op->optinsn.insn);
 }
 
index 06f6bb48d01891a31c668730697d00a093cd51e8..98039d7fb998c96152854d5488de834dc3537b3b 100644 (file)
@@ -58,24 +58,24 @@ struct branch {
        u32 delta;
 } __attribute__((packed));
 
-static unsigned paravirt_patch_call(void *insnbuf, const void *target,
+static unsigned paravirt_patch_call(void *insn_buff, const void *target,
                                    unsigned long addr, unsigned len)
 {
-       struct branch *b = insnbuf;
-       unsigned long delta = (unsigned long)target - (addr+5);
-
-       if (len < 5) {
-#ifdef CONFIG_RETPOLINE
-               WARN_ONCE(1, "Failing to patch indirect CALL in %ps\n", (void *)addr);
-#endif
-               return len;     /* call too long for patch site */
+       const int call_len = 5;
+       struct branch *b = insn_buff;
+       unsigned long delta = (unsigned long)target - (addr+call_len);
+
+       if (len < call_len) {
+               pr_warn("paravirt: Failed to patch indirect CALL at %ps\n", (void *)addr);
+               /* Kernel might not be viable if patching fails, bail out: */
+               BUG_ON(1);
        }
 
        b->opcode = 0xe8; /* call */
        b->delta = delta;
-       BUILD_BUG_ON(sizeof(*b) != 5);
+       BUILD_BUG_ON(sizeof(*b) != call_len);
 
-       return 5;
+       return call_len;
 }
 
 #ifdef CONFIG_PARAVIRT_XXL
@@ -85,10 +85,10 @@ u64 notrace _paravirt_ident_64(u64 x)
        return x;
 }
 
-static unsigned paravirt_patch_jmp(void *insnbuf, const void *target,
+static unsigned paravirt_patch_jmp(void *insn_buff, const void *target,
                                   unsigned long addr, unsigned len)
 {
-       struct branch *b = insnbuf;
+       struct branch *b = insn_buff;
        unsigned long delta = (unsigned long)target - (addr+5);
 
        if (len < 5) {
@@ -113,7 +113,7 @@ void __init native_pv_lock_init(void)
                static_branch_disable(&virt_spin_lock_key);
 }
 
-unsigned paravirt_patch_default(u8 type, void *insnbuf,
+unsigned paravirt_patch_default(u8 type, void *insn_buff,
                                unsigned long addr, unsigned len)
 {
        /*
@@ -125,36 +125,36 @@ unsigned paravirt_patch_default(u8 type, void *insnbuf,
 
        if (opfunc == NULL)
                /* If there's no function, patch it with a ud2a (BUG) */
-               ret = paravirt_patch_insns(insnbuf, len, ud2a, ud2a+sizeof(ud2a));
+               ret = paravirt_patch_insns(insn_buff, len, ud2a, ud2a+sizeof(ud2a));
        else if (opfunc == _paravirt_nop)
                ret = 0;
 
 #ifdef CONFIG_PARAVIRT_XXL
        /* identity functions just return their single argument */
        else if (opfunc == _paravirt_ident_64)
-               ret = paravirt_patch_ident_64(insnbuf, len);
+               ret = paravirt_patch_ident_64(insn_buff, len);
 
        else if (type == PARAVIRT_PATCH(cpu.iret) ||
                 type == PARAVIRT_PATCH(cpu.usergs_sysret64))
                /* If operation requires a jmp, then jmp */
-               ret = paravirt_patch_jmp(insnbuf, opfunc, addr, len);
+               ret = paravirt_patch_jmp(insn_buff, opfunc, addr, len);
 #endif
        else
                /* Otherwise call the function. */
-               ret = paravirt_patch_call(insnbuf, opfunc, addr, len);
+               ret = paravirt_patch_call(insn_buff, opfunc, addr, len);
 
        return ret;
 }
 
-unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
+unsigned paravirt_patch_insns(void *insn_buff, unsigned len,
                              const char *start, const char *end)
 {
        unsigned insn_len = end - start;
 
-       if (insn_len > len || start == NULL)
-               insn_len = len;
-       else
-               memcpy(insnbuf, start, insn_len);
+       /* Alternative instruction is too large for the patch site and we cannot continue: */
+       BUG_ON(insn_len > len || start == NULL);
+
+       memcpy(insn_buff, start, insn_len);
 
        return insn_len;
 }
diff --git a/arch/x86/kernel/paravirt_patch.c b/arch/x86/kernel/paravirt_patch.c
new file mode 100644 (file)
index 0000000..3eff63c
--- /dev/null
@@ -0,0 +1,126 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/stringify.h>
+
+#include <asm/paravirt.h>
+#include <asm/asm-offsets.h>
+
+#define PSTART(d, m)                                                   \
+       patch_data_##d.m
+
+#define PEND(d, m)                                                     \
+       (PSTART(d, m) + sizeof(patch_data_##d.m))
+
+#define PATCH(d, m, insn_buff, len)                                            \
+       paravirt_patch_insns(insn_buff, len, PSTART(d, m), PEND(d, m))
+
+#define PATCH_CASE(ops, m, data, insn_buff, len)                               \
+       case PARAVIRT_PATCH(ops.m):                                     \
+               return PATCH(data, ops##_##m, insn_buff, len)
+
+#ifdef CONFIG_PARAVIRT_XXL
+struct patch_xxl {
+       const unsigned char     irq_irq_disable[1];
+       const unsigned char     irq_irq_enable[1];
+       const unsigned char     irq_save_fl[2];
+       const unsigned char     mmu_read_cr2[3];
+       const unsigned char     mmu_read_cr3[3];
+       const unsigned char     mmu_write_cr3[3];
+       const unsigned char     irq_restore_fl[2];
+# ifdef CONFIG_X86_64
+       const unsigned char     cpu_wbinvd[2];
+       const unsigned char     cpu_usergs_sysret64[6];
+       const unsigned char     cpu_swapgs[3];
+       const unsigned char     mov64[3];
+# else
+       const unsigned char     cpu_iret[1];
+# endif
+};
+
+static const struct patch_xxl patch_data_xxl = {
+       .irq_irq_disable        = { 0xfa },             // cli
+       .irq_irq_enable         = { 0xfb },             // sti
+       .irq_save_fl            = { 0x9c, 0x58 },       // pushf; pop %[re]ax
+       .mmu_read_cr2           = { 0x0f, 0x20, 0xd0 }, // mov %cr2, %[re]ax
+       .mmu_read_cr3           = { 0x0f, 0x20, 0xd8 }, // mov %cr3, %[re]ax
+# ifdef CONFIG_X86_64
+       .mmu_write_cr3          = { 0x0f, 0x22, 0xdf }, // mov %rdi, %cr3
+       .irq_restore_fl         = { 0x57, 0x9d },       // push %rdi; popfq
+       .cpu_wbinvd             = { 0x0f, 0x09 },       // wbinvd
+       .cpu_usergs_sysret64    = { 0x0f, 0x01, 0xf8,
+                                   0x48, 0x0f, 0x07 }, // swapgs; sysretq
+       .cpu_swapgs             = { 0x0f, 0x01, 0xf8 }, // swapgs
+       .mov64                  = { 0x48, 0x89, 0xf8 }, // mov %rdi, %rax
+# else
+       .mmu_write_cr3          = { 0x0f, 0x22, 0xd8 }, // mov %eax, %cr3
+       .irq_restore_fl         = { 0x50, 0x9d },       // push %eax; popf
+       .cpu_iret               = { 0xcf },             // iret
+# endif
+};
+
+unsigned int paravirt_patch_ident_64(void *insn_buff, unsigned int len)
+{
+#ifdef CONFIG_X86_64
+       return PATCH(xxl, mov64, insn_buff, len);
+#endif
+       return 0;
+}
+# endif /* CONFIG_PARAVIRT_XXL */
+
+#ifdef CONFIG_PARAVIRT_SPINLOCKS
+struct patch_lock {
+       unsigned char queued_spin_unlock[3];
+       unsigned char vcpu_is_preempted[2];
+};
+
+static const struct patch_lock patch_data_lock = {
+       .vcpu_is_preempted      = { 0x31, 0xc0 },       // xor %eax, %eax
+
+# ifdef CONFIG_X86_64
+       .queued_spin_unlock     = { 0xc6, 0x07, 0x00 }, // movb $0, (%rdi)
+# else
+       .queued_spin_unlock     = { 0xc6, 0x00, 0x00 }, // movb $0, (%eax)
+# endif
+};
+#endif /* CONFIG_PARAVIRT_SPINLOCKS */
+
+unsigned int native_patch(u8 type, void *insn_buff, unsigned long addr,
+                         unsigned int len)
+{
+       switch (type) {
+
+#ifdef CONFIG_PARAVIRT_XXL
+       PATCH_CASE(irq, restore_fl, xxl, insn_buff, len);
+       PATCH_CASE(irq, save_fl, xxl, insn_buff, len);
+       PATCH_CASE(irq, irq_enable, xxl, insn_buff, len);
+       PATCH_CASE(irq, irq_disable, xxl, insn_buff, len);
+
+       PATCH_CASE(mmu, read_cr2, xxl, insn_buff, len);
+       PATCH_CASE(mmu, read_cr3, xxl, insn_buff, len);
+       PATCH_CASE(mmu, write_cr3, xxl, insn_buff, len);
+
+# ifdef CONFIG_X86_64
+       PATCH_CASE(cpu, usergs_sysret64, xxl, insn_buff, len);
+       PATCH_CASE(cpu, swapgs, xxl, insn_buff, len);
+       PATCH_CASE(cpu, wbinvd, xxl, insn_buff, len);
+# else
+       PATCH_CASE(cpu, iret, xxl, insn_buff, len);
+# endif
+#endif
+
+#ifdef CONFIG_PARAVIRT_SPINLOCKS
+       case PARAVIRT_PATCH(lock.queued_spin_unlock):
+               if (pv_is_native_spin_unlock())
+                       return PATCH(lock, queued_spin_unlock, insn_buff, len);
+               break;
+
+       case PARAVIRT_PATCH(lock.vcpu_is_preempted):
+               if (pv_is_native_vcpu_is_preempted())
+                       return PATCH(lock, vcpu_is_preempted, insn_buff, len);
+               break;
+#endif
+       default:
+               break;
+       }
+
+       return paravirt_patch_default(type, insn_buff, addr, len);
+}
diff --git a/arch/x86/kernel/paravirt_patch_32.c b/arch/x86/kernel/paravirt_patch_32.c
deleted file mode 100644 (file)
index de138d3..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <asm/paravirt.h>
-
-#ifdef CONFIG_PARAVIRT_XXL
-DEF_NATIVE(irq, irq_disable, "cli");
-DEF_NATIVE(irq, irq_enable, "sti");
-DEF_NATIVE(irq, restore_fl, "push %eax; popf");
-DEF_NATIVE(irq, save_fl, "pushf; pop %eax");
-DEF_NATIVE(cpu, iret, "iret");
-DEF_NATIVE(mmu, read_cr2, "mov %cr2, %eax");
-DEF_NATIVE(mmu, write_cr3, "mov %eax, %cr3");
-DEF_NATIVE(mmu, read_cr3, "mov %cr3, %eax");
-
-unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len)
-{
-       /* arg in %edx:%eax, return in %edx:%eax */
-       return 0;
-}
-#endif
-
-#if defined(CONFIG_PARAVIRT_SPINLOCKS)
-DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%eax)");
-DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax");
-#endif
-
-extern bool pv_is_native_spin_unlock(void);
-extern bool pv_is_native_vcpu_is_preempted(void);
-
-unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len)
-{
-#define PATCH_SITE(ops, x)                                     \
-       case PARAVIRT_PATCH(ops.x):                             \
-               return paravirt_patch_insns(ibuf, len, start_##ops##_##x, end_##ops##_##x)
-
-       switch (type) {
-#ifdef CONFIG_PARAVIRT_XXL
-               PATCH_SITE(irq, irq_disable);
-               PATCH_SITE(irq, irq_enable);
-               PATCH_SITE(irq, restore_fl);
-               PATCH_SITE(irq, save_fl);
-               PATCH_SITE(cpu, iret);
-               PATCH_SITE(mmu, read_cr2);
-               PATCH_SITE(mmu, read_cr3);
-               PATCH_SITE(mmu, write_cr3);
-#endif
-#if defined(CONFIG_PARAVIRT_SPINLOCKS)
-       case PARAVIRT_PATCH(lock.queued_spin_unlock):
-               if (pv_is_native_spin_unlock())
-                       return paravirt_patch_insns(ibuf, len,
-                                                   start_lock_queued_spin_unlock,
-                                                   end_lock_queued_spin_unlock);
-               break;
-
-       case PARAVIRT_PATCH(lock.vcpu_is_preempted):
-               if (pv_is_native_vcpu_is_preempted())
-                       return paravirt_patch_insns(ibuf, len,
-                                                   start_lock_vcpu_is_preempted,
-                                                   end_lock_vcpu_is_preempted);
-               break;
-#endif
-
-       default:
-               break;
-       }
-#undef PATCH_SITE
-       return paravirt_patch_default(type, ibuf, addr, len);
-}
diff --git a/arch/x86/kernel/paravirt_patch_64.c b/arch/x86/kernel/paravirt_patch_64.c
deleted file mode 100644 (file)
index 9d9e04b..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <asm/paravirt.h>
-#include <asm/asm-offsets.h>
-#include <linux/stringify.h>
-
-#ifdef CONFIG_PARAVIRT_XXL
-DEF_NATIVE(irq, irq_disable, "cli");
-DEF_NATIVE(irq, irq_enable, "sti");
-DEF_NATIVE(irq, restore_fl, "pushq %rdi; popfq");
-DEF_NATIVE(irq, save_fl, "pushfq; popq %rax");
-DEF_NATIVE(mmu, read_cr2, "movq %cr2, %rax");
-DEF_NATIVE(mmu, read_cr3, "movq %cr3, %rax");
-DEF_NATIVE(mmu, write_cr3, "movq %rdi, %cr3");
-DEF_NATIVE(cpu, wbinvd, "wbinvd");
-
-DEF_NATIVE(cpu, usergs_sysret64, "swapgs; sysretq");
-DEF_NATIVE(cpu, swapgs, "swapgs");
-DEF_NATIVE(, mov64, "mov %rdi, %rax");
-
-unsigned paravirt_patch_ident_64(void *insnbuf, unsigned len)
-{
-       return paravirt_patch_insns(insnbuf, len,
-                                   start__mov64, end__mov64);
-}
-#endif
-
-#if defined(CONFIG_PARAVIRT_SPINLOCKS)
-DEF_NATIVE(lock, queued_spin_unlock, "movb $0, (%rdi)");
-DEF_NATIVE(lock, vcpu_is_preempted, "xor %eax, %eax");
-#endif
-
-extern bool pv_is_native_spin_unlock(void);
-extern bool pv_is_native_vcpu_is_preempted(void);
-
-unsigned native_patch(u8 type, void *ibuf, unsigned long addr, unsigned len)
-{
-#define PATCH_SITE(ops, x)                                     \
-       case PARAVIRT_PATCH(ops.x):                             \
-               return paravirt_patch_insns(ibuf, len, start_##ops##_##x, end_##ops##_##x)
-
-       switch (type) {
-#ifdef CONFIG_PARAVIRT_XXL
-               PATCH_SITE(irq, restore_fl);
-               PATCH_SITE(irq, save_fl);
-               PATCH_SITE(irq, irq_enable);
-               PATCH_SITE(irq, irq_disable);
-               PATCH_SITE(cpu, usergs_sysret64);
-               PATCH_SITE(cpu, swapgs);
-               PATCH_SITE(cpu, wbinvd);
-               PATCH_SITE(mmu, read_cr2);
-               PATCH_SITE(mmu, read_cr3);
-               PATCH_SITE(mmu, write_cr3);
-#endif
-#if defined(CONFIG_PARAVIRT_SPINLOCKS)
-       case PARAVIRT_PATCH(lock.queued_spin_unlock):
-               if (pv_is_native_spin_unlock())
-                       return paravirt_patch_insns(ibuf, len,
-                                                   start_lock_queued_spin_unlock,
-                                                   end_lock_queued_spin_unlock);
-               break;
-
-       case PARAVIRT_PATCH(lock.vcpu_is_preempted):
-               if (pv_is_native_vcpu_is_preempted())
-                       return paravirt_patch_insns(ibuf, len,
-                                                   start_lock_vcpu_is_preempted,
-                                                   end_lock_vcpu_is_preempted);
-               break;
-#endif
-
-       default:
-               break;
-       }
-#undef PATCH_SITE
-       return paravirt_patch_default(type, ibuf, addr, len);
-}
index e455349e0ab5e5a44b0041f9efac90b4727173bf..34eda63c124b19cc1592d853f8b1862ddc269087 100644 (file)
@@ -111,7 +111,7 @@ static void parse_args(int argc, char **argv)
 int main(int argc, char **argv)
 {
        char line[BUFSIZE], sym[BUFSIZE] = "<unknown>";
-       unsigned char insn_buf[16];
+       unsigned char insn_buff[16];
        struct insn insn;
        int insns = 0;
        int warnings = 0;
@@ -130,7 +130,7 @@ int main(int argc, char **argv)
                }
 
                insns++;
-               memset(insn_buf, 0, 16);
+               memset(insn_buff, 0, 16);
                strcpy(copy, line);
                tab1 = strchr(copy, '\t');
                if (!tab1)
@@ -143,13 +143,13 @@ int main(int argc, char **argv)
                *tab2 = '\0';   /* Characters beyond tab2 aren't examined */
                while (s < tab2) {
                        if (sscanf(s, "%x", &b) == 1) {
-                               insn_buf[nb++] = (unsigned char) b;
+                               insn_buff[nb++] = (unsigned char) b;
                                s += 3;
                        } else
                                break;
                }
                /* Decode an instruction */
-               insn_init(&insn, insn_buf, sizeof(insn_buf), x86_64);
+               insn_init(&insn, insn_buff, sizeof(insn_buff), x86_64);
                insn_get_length(&insn);
                if (insn.length != nb) {
                        warnings++;
index 14cf07916081182935e8e13c19f5e8dc5d24e587..185ceba9d289bd5de91019cebc25502c9a385a2f 100644 (file)
@@ -83,7 +83,7 @@ static void dump_insn(FILE *fp, struct insn *insn)
 }
 
 static void dump_stream(FILE *fp, const char *msg, unsigned long nr_iter,
-                       unsigned char *insn_buf, struct insn *insn)
+                       unsigned char *insn_buff, struct insn *insn)
 {
        int i;
 
@@ -96,7 +96,7 @@ static void dump_stream(FILE *fp, const char *msg, unsigned long nr_iter,
        /* Input a decoded instruction sequence directly */
        fprintf(fp, " $ echo ");
        for (i = 0; i < MAX_INSN_SIZE; i++)
-               fprintf(fp, " %02x", insn_buf[i]);
+               fprintf(fp, " %02x", insn_buff[i]);
        fprintf(fp, " | %s -i -\n", prog);
 
        if (!input_file) {
@@ -124,7 +124,7 @@ fail:
 }
 
 /* Read given instruction sequence from the input file */
-static int read_next_insn(unsigned char *insn_buf)
+static int read_next_insn(unsigned char *insn_buff)
 {
        char buf[256]  = "", *tmp;
        int i;
@@ -134,7 +134,7 @@ static int read_next_insn(unsigned char *insn_buf)
                return 0;
 
        for (i = 0; i < MAX_INSN_SIZE; i++) {
-               insn_buf[i] = (unsigned char)strtoul(tmp, &tmp, 16);
+               insn_buff[i] = (unsigned char)strtoul(tmp, &tmp, 16);
                if (*tmp != ' ')
                        break;
        }
@@ -142,19 +142,19 @@ static int read_next_insn(unsigned char *insn_buf)
        return i;
 }
 
-static int generate_insn(unsigned char *insn_buf)
+static int generate_insn(unsigned char *insn_buff)
 {
        int i;
 
        if (input_file)
-               return read_next_insn(insn_buf);
+               return read_next_insn(insn_buff);
 
        /* Fills buffer with random binary up to MAX_INSN_SIZE */
        for (i = 0; i < MAX_INSN_SIZE - 1; i += 2)
-               *(unsigned short *)(&insn_buf[i]) = random() & 0xffff;
+               *(unsigned short *)(&insn_buff[i]) = random() & 0xffff;
 
        while (i < MAX_INSN_SIZE)
-               insn_buf[i++] = random() & 0xff;
+               insn_buff[i++] = random() & 0xff;
 
        return i;
 }
@@ -226,31 +226,31 @@ int main(int argc, char **argv)
        int insns = 0;
        int errors = 0;
        unsigned long i;
-       unsigned char insn_buf[MAX_INSN_SIZE * 2];
+       unsigned char insn_buff[MAX_INSN_SIZE * 2];
 
        parse_args(argc, argv);
 
        /* Prepare stop bytes with NOPs */
-       memset(insn_buf + MAX_INSN_SIZE, INSN_NOP, MAX_INSN_SIZE);
+       memset(insn_buff + MAX_INSN_SIZE, INSN_NOP, MAX_INSN_SIZE);
 
        for (i = 0; i < iter_end; i++) {
-               if (generate_insn(insn_buf) <= 0)
+               if (generate_insn(insn_buff) <= 0)
                        break;
 
                if (i < iter_start)     /* Skip to given iteration number */
                        continue;
 
                /* Decode an instruction */
-               insn_init(&insn, insn_buf, sizeof(insn_buf), x86_64);
+               insn_init(&insn, insn_buff, sizeof(insn_buff), x86_64);
                insn_get_length(&insn);
 
                if (insn.next_byte <= insn.kaddr ||
                    insn.kaddr + MAX_INSN_SIZE < insn.next_byte) {
                        /* Access out-of-range memory */
-                       dump_stream(stderr, "Error: Found an access violation", i, insn_buf, &insn);
+                       dump_stream(stderr, "Error: Found an access violation", i, insn_buff, &insn);
                        errors++;
                } else if (verbose && !insn_complete(&insn))
-                       dump_stream(stdout, "Info: Found an undecodable input", i, insn_buf, &insn);
+                       dump_stream(stdout, "Info: Found an undecodable input", i, insn_buff, &insn);
                else if (verbose >= 2)
                        dump_insn(stdout, &insn);
                insns++;