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

x86/paravirt/xen: Remove xen_patch()

Xen's paravirt patch function xen_patch() does some special casing for
irq_ops functions to apply relocations when those functions can be
patched inline instead of calls.

Unfortunately none of the special case function replacements is small
enough to be patched inline, so the special case never applies.

As xen_patch() will call paravirt_patch_default() in all cases it can
be just dropped. xen-asm.h doesn't seem necessary without xen_patch()
as the only thing left in it would be the definition of XEN_EFLAGS_NMI
used only once. So move that definition and remove xen-asm.h.

Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: boris.ostrovsky@oracle.com
Cc: lguest@lists.ozlabs.org
Cc: rusty@rustcorp.com.au
Cc: xen-devel@lists.xenproject.org
Link: http://lkml.kernel.org/r/20170816173157.8633-2-jgross@suse.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>

authored by

Juergen Gross and committed by
Ingo Molnar
edcb5cf8 ee97638b

+21 -138
+1 -58
arch/x86/xen/enlighten_pv.c
··· 981 981 } 982 982 } 983 983 984 - static unsigned xen_patch(u8 type, u16 clobbers, void *insnbuf, 985 - unsigned long addr, unsigned len) 986 - { 987 - char *start, *end, *reloc; 988 - unsigned ret; 989 - 990 - start = end = reloc = NULL; 991 - 992 - #define SITE(op, x) \ 993 - case PARAVIRT_PATCH(op.x): \ 994 - if (xen_have_vcpu_info_placement) { \ 995 - start = (char *)xen_##x##_direct; \ 996 - end = xen_##x##_direct_end; \ 997 - reloc = xen_##x##_direct_reloc; \ 998 - } \ 999 - goto patch_site 1000 - 1001 - switch (type) { 1002 - SITE(pv_irq_ops, irq_enable); 1003 - SITE(pv_irq_ops, irq_disable); 1004 - SITE(pv_irq_ops, save_fl); 1005 - SITE(pv_irq_ops, restore_fl); 1006 - #undef SITE 1007 - 1008 - patch_site: 1009 - if (start == NULL || (end-start) > len) 1010 - goto default_patch; 1011 - 1012 - ret = paravirt_patch_insns(insnbuf, len, start, end); 1013 - 1014 - /* Note: because reloc is assigned from something that 1015 - appears to be an array, gcc assumes it's non-null, 1016 - but doesn't know its relationship with start and 1017 - end. */ 1018 - if (reloc > start && reloc < end) { 1019 - int reloc_off = reloc - start; 1020 - long *relocp = (long *)(insnbuf + reloc_off); 1021 - long delta = start - (char *)addr; 1022 - 1023 - *relocp += delta; 1024 - } 1025 - break; 1026 - 1027 - default_patch: 1028 - default: 1029 - ret = paravirt_patch_default(type, clobbers, insnbuf, 1030 - addr, len); 1031 - break; 1032 - } 1033 - 1034 - return ret; 1035 - } 1036 - 1037 984 static const struct pv_info xen_info __initconst = { 1038 985 .shared_kernel_pmd = 0, 1039 986 ··· 988 1041 .extra_user_64bit_cs = FLAT_USER_CS64, 989 1042 #endif 990 1043 .name = "Xen", 991 - }; 992 - 993 - static const struct pv_init_ops xen_init_ops __initconst = { 994 - .patch = xen_patch, 995 1044 }; 996 1045 997 1046 static const struct pv_cpu_ops xen_cpu_ops __initconst = { ··· 1187 1244 1188 1245 /* Install Xen paravirt ops */ 1189 1246 pv_info = xen_info; 1190 - pv_init_ops = xen_init_ops; 1247 + pv_init_ops.patch = paravirt_patch_default; 1191 1248 pv_cpu_ops = xen_cpu_ops; 1192 1249 1193 1250 x86_platform.get_nmi_reason = xen_get_nmi_reason;
+6 -20
arch/x86/xen/xen-asm.S
··· 1 1 /* 2 - * Asm versions of Xen pv-ops, suitable for either direct use or 3 - * inlining. The inline versions are the same as the direct-use 4 - * versions, with the pre- and post-amble chopped off. 5 - * 6 - * This code is encoded for size rather than absolute efficiency, with 7 - * a view to being able to inline as much as possible. 2 + * Asm versions of Xen pv-ops, suitable for direct use. 8 3 * 9 4 * We only bother with direct forms (ie, vcpu in percpu data) of the 10 - * operations here; the indirect forms are better handled in C, since 11 - * they're generally too large to inline anyway. 5 + * operations here; the indirect forms are better handled in C. 12 6 */ 13 7 14 8 #include <asm/asm-offsets.h> ··· 10 16 #include <asm/processor-flags.h> 11 17 #include <asm/frame.h> 12 18 13 - #include "xen-asm.h" 19 + #include <linux/linkage.h> 14 20 15 21 /* 16 22 * Enable events. This clears the event mask and tests the pending ··· 32 38 testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending 33 39 jz 1f 34 40 35 - 2: call check_events 41 + call check_events 36 42 1: 37 - ENDPATCH(xen_irq_enable_direct) 38 43 FRAME_END 39 44 ret 40 45 ENDPROC(xen_irq_enable_direct) 41 - RELOC(xen_irq_enable_direct, 2b+1) 42 46 43 47 44 48 /* ··· 45 53 */ 46 54 ENTRY(xen_irq_disable_direct) 47 55 movb $1, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask 48 - ENDPATCH(xen_irq_disable_direct) 49 56 ret 50 - ENDPROC(xen_irq_disable_direct) 51 - RELOC(xen_irq_disable_direct, 0) 57 + ENDPROC(xen_irq_disable_direct) 52 58 53 59 /* 54 60 * (xen_)save_fl is used to get the current interrupt enable status. ··· 61 71 testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask 62 72 setz %ah 63 73 addb %ah, %ah 64 - ENDPATCH(xen_save_fl_direct) 65 74 ret 66 75 ENDPROC(xen_save_fl_direct) 67 - RELOC(xen_save_fl_direct, 0) 68 76 69 77 70 78 /* ··· 89 101 /* check for unmasked and pending */ 90 102 cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending 91 103 jnz 1f 92 - 2: call check_events 104 + call check_events 93 105 1: 94 - ENDPATCH(xen_restore_fl_direct) 95 106 FRAME_END 96 107 ret 97 108 ENDPROC(xen_restore_fl_direct) 98 - RELOC(xen_restore_fl_direct, 2b+1) 99 109 100 110 101 111 /*
-12
arch/x86/xen/xen-asm.h
··· 1 - #ifndef _XEN_XEN_ASM_H 2 - #define _XEN_XEN_ASM_H 3 - 4 - #include <linux/linkage.h> 5 - 6 - #define RELOC(x, v) .globl x##_reloc; x##_reloc=v 7 - #define ENDPATCH(x) .globl x##_end; x##_end=. 8 - 9 - /* Pseudo-flag used for virtual NMI, which we don't implement yet */ 10 - #define XEN_EFLAGS_NMI 0x80000000 11 - 12 - #endif
+5 -22
arch/x86/xen/xen-asm_32.S
··· 1 1 /* 2 - * Asm versions of Xen pv-ops, suitable for either direct use or 3 - * inlining. The inline versions are the same as the direct-use 4 - * versions, with the pre- and post-amble chopped off. 5 - * 6 - * This code is encoded for size rather than absolute efficiency, with 7 - * a view to being able to inline as much as possible. 2 + * Asm versions of Xen pv-ops, suitable for direct use. 8 3 * 9 4 * We only bother with direct forms (ie, vcpu in pda) of the 10 - * operations here; the indirect forms are better handled in C, since 11 - * they're generally too large to inline anyway. 5 + * operations here; the indirect forms are better handled in C. 12 6 */ 13 7 14 8 #include <asm/thread_info.h> ··· 12 18 13 19 #include <xen/interface/xen.h> 14 20 15 - #include "xen-asm.h" 21 + #include <linux/linkage.h> 16 22 17 - /* 18 - * Force an event check by making a hypercall, but preserve regs 19 - * before making the call. 20 - */ 21 - check_events: 22 - push %eax 23 - push %ecx 24 - push %edx 25 - call xen_force_evtchn_callback 26 - pop %edx 27 - pop %ecx 28 - pop %eax 29 - ret 23 + /* Pseudo-flag used for virtual NMI, which we don't implement yet */ 24 + #define XEN_EFLAGS_NMI 0x80000000 30 25 31 26 /* 32 27 * This is run where a normal iret would be run, with the same stack setup:
+5 -15
arch/x86/xen/xen-asm_64.S
··· 1 1 /* 2 - * Asm versions of Xen pv-ops, suitable for either direct use or 3 - * inlining. The inline versions are the same as the direct-use 4 - * versions, with the pre- and post-amble chopped off. 5 - * 6 - * This code is encoded for size rather than absolute efficiency, with 7 - * a view to being able to inline as much as possible. 2 + * Asm versions of Xen pv-ops, suitable for direct use. 8 3 * 9 4 * We only bother with direct forms (ie, vcpu in pda) of the 10 - * operations here; the indirect forms are better handled in C, since 11 - * they're generally too large to inline anyway. 5 + * operations here; the indirect forms are better handled in C. 12 6 */ 13 7 14 8 #include <asm/errno.h> ··· 14 20 15 21 #include <xen/interface/xen.h> 16 22 17 - #include "xen-asm.h" 23 + #include <linux/linkage.h> 18 24 19 25 ENTRY(xen_adjust_exception_frame) 20 26 mov 8+0(%rsp), %rcx ··· 40 46 */ 41 47 ENTRY(xen_iret) 42 48 pushq $0 43 - 1: jmp hypercall_iret 44 - ENDPATCH(xen_iret) 45 - RELOC(xen_iret, 1b+1) 49 + jmp hypercall_iret 46 50 47 51 ENTRY(xen_sysret64) 48 52 /* ··· 57 65 pushq %rcx 58 66 59 67 pushq $VGCF_in_syscall 60 - 1: jmp hypercall_iret 61 - ENDPATCH(xen_sysret64) 62 - RELOC(xen_sysret64, 1b+1) 68 + jmp hypercall_iret 63 69 64 70 /* 65 71 * Xen handles syscall callbacks much like ordinary exceptions, which
+4 -11
arch/x86/xen/xen-ops.h
··· 129 129 } 130 130 #endif 131 131 132 - /* Declare an asm function, along with symbols needed to make it 133 - inlineable */ 134 - #define DECL_ASM(ret, name, ...) \ 135 - __visible ret name(__VA_ARGS__); \ 136 - extern char name##_end[] __visible; \ 137 - extern char name##_reloc[] __visible 138 - 139 - DECL_ASM(void, xen_irq_enable_direct, void); 140 - DECL_ASM(void, xen_irq_disable_direct, void); 141 - DECL_ASM(unsigned long, xen_save_fl_direct, void); 142 - DECL_ASM(void, xen_restore_fl_direct, unsigned long); 132 + __visible void xen_irq_enable_direct(void); 133 + __visible void xen_irq_disable_direct(void); 134 + __visible unsigned long xen_save_fl_direct(void); 135 + __visible void xen_restore_fl_direct(unsigned long); 143 136 144 137 /* These are not functions, and cannot be called normally */ 145 138 __visible void xen_iret(void);