Scanning for embedded endbranch instructions involves parsing the .text disassembly. Data in the kexec trampoline has no ELF metadata, so objdump treats it as instructions and tries to disassemble. Convert:
ffff82d040396108 <compatibility_mode_far>: ffff82d040396108: 00 00 add %al,(%rax) ffff82d04039610a: 00 00 add %al,(%rax) ffff82d04039610c: 10 00 adc %al,(%rax) ffff82d04039610e <compat_mode_gdt_desc>: ffff82d04039610e: 17 (bad) ... ffff82d040396118 <compat_mode_gdt>: ... ffff82d040396120: ff (bad) ffff82d040396121: ff 00 incl (%rax) ffff82d040396123: 00 00 add %al,(%rax) ffff82d040396125: 93 xchg %eax,%ebx ffff82d040396126: cf iret ffff82d040396127: 00 ff add %bh,%bh ffff82d040396129: ff 00 incl (%rax) ffff82d04039612b: 00 00 add %al,(%rax) ffff82d04039612d: 9b fwait ffff82d04039612e: cf iret ... ffff82d040396130 <compat_mode_idt>: ... ffff82d0403961b6 <kexec_reloc_size>: ffff82d0403961b6: b6 01 mov $0x1,%dh ... to: ffff82d040396108 <compatibility_mode_far>: ffff82d040396108: 00 00 00 00 10 00 ...... ffff82d04039610e <compat_mode_gdt_desc>: ffff82d04039610e: 17 00 00 00 00 00 00 00 00 00 .......... ffff82d040396118 <compat_mode_gdt>: ... ffff82d040396120: ff ff 00 00 00 93 cf 00 ff ff 00 00 00 9b cf 00 ................ ffff82d040396130 <compat_mode_idt>: ffff82d040396130: 00 00 00 00 00 00 ...... ffff82d040396136 <reloc_stack>: ... Most data just gains type and size metadata. The reloc_stack label is the wrong end of the data block to have a size, so move it to the lowest address and introduce .Lreloc_stack_base as a replacement. Also, fix the fact that it is misaligned by 2 bytes. While kexec_reloc_size could gain metadata, it's use in the linker assertion (while correct) is deeply confusing to follow. Drop it entirely, using a linker symbol instead to denote the end of the trampoline. No functional change. Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com> Reviewed-by: Jan Beulich <jbeul...@suse.com> --- CC: Jan Beulich <jbeul...@suse.com> CC: Roger Pau Monné <roger....@citrix.com> CC: Wei Liu <w...@xen.org> The remainder of the 32bit code has mode-invariant lengths, so disassembles safely as 64bit. The only differences come from 32/64bit implicit register sizes. v2.1: * New v2.2: * Fix stack alignment --- xen/arch/x86/include/asm/machine_kexec.h | 2 +- xen/arch/x86/machine_kexec.c | 2 +- xen/arch/x86/x86_64/kexec_reloc.S | 23 ++++++++++++++++++----- xen/arch/x86/xen.lds.S | 3 ++- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/include/asm/machine_kexec.h b/xen/arch/x86/include/asm/machine_kexec.h index ba0d469d077b..d4880818c1d9 100644 --- a/xen/arch/x86/include/asm/machine_kexec.h +++ b/xen/arch/x86/include/asm/machine_kexec.h @@ -9,7 +9,7 @@ extern void kexec_reloc(unsigned long reloc_code, unsigned long reloc_pt, unsigned long ind_maddr, unsigned long entry_maddr, unsigned long flags); -extern unsigned int kexec_reloc_size; +extern const char kexec_reloc_end[]; #endif diff --git a/xen/arch/x86/machine_kexec.c b/xen/arch/x86/machine_kexec.c index 08ec9fd43b1d..751a9efcaf6a 100644 --- a/xen/arch/x86/machine_kexec.c +++ b/xen/arch/x86/machine_kexec.c @@ -117,7 +117,7 @@ int machine_kexec_load(struct kexec_image *image) } code_page = __map_domain_page(image->control_code_page); - memcpy(code_page, kexec_reloc, kexec_reloc_size); + memcpy(code_page, kexec_reloc, kexec_reloc_end - (char *)kexec_reloc); unmap_domain_page(code_page); /* diff --git a/xen/arch/x86/x86_64/kexec_reloc.S b/xen/arch/x86/x86_64/kexec_reloc.S index d488d127cfb9..89316bc3a7ac 100644 --- a/xen/arch/x86/x86_64/kexec_reloc.S +++ b/xen/arch/x86/x86_64/kexec_reloc.S @@ -34,7 +34,7 @@ ENTRY(kexec_reloc) movq %rcx, %rbp /* Setup stack. */ - leaq (reloc_stack - kexec_reloc)(%rdi), %rsp + leaq (.Lreloc_stack_base - kexec_reloc)(%rdi), %rsp /* Load reloc page table. */ movq %rsi, %cr3 @@ -175,10 +175,16 @@ compatibility_mode_far: .long 0x00000000 /* set in call_32_bit above */ .word 0x0010 + .type compatibility_mode_far, @object + .size compatibility_mode_far, . - compatibility_mode_far + compat_mode_gdt_desc: .word .Lcompat_mode_gdt_end - compat_mode_gdt -1 .quad 0x0000000000000000 /* set in call_32_bit above */ + .type compat_mode_gdt_desc, @object + .size compat_mode_gdt_desc, . - compat_mode_gdt_desc + .align 8 compat_mode_gdt: .quad 0x0000000000000000 /* null */ @@ -186,16 +192,23 @@ compat_mode_gdt: .quad 0x00cf9b000000ffff /* 0x0010 ring 0 code, compatibility */ .Lcompat_mode_gdt_end: + .type compat_mode_gdt, @object + .size compat_mode_gdt, . - compat_mode_gdt + compat_mode_idt: .word 0 /* limit */ .long 0 /* base */ + .type compat_mode_idt, @object + .size compat_mode_idt, . - compat_mode_idt + /* * 16 words of stack are more than enough. */ - .fill 16,8,0 + .align 8 reloc_stack: + .fill 16,8,0 +.Lreloc_stack_base: - .globl kexec_reloc_size -kexec_reloc_size: - .long . - kexec_reloc + .type reloc_stack, @object + .size reloc_stack, . - reloc_stack diff --git a/xen/arch/x86/xen.lds.S b/xen/arch/x86/xen.lds.S index 82ad8feb6e99..7ffecd463070 100644 --- a/xen/arch/x86/xen.lds.S +++ b/xen/arch/x86/xen.lds.S @@ -84,6 +84,7 @@ SECTIONS _etextentry = .; *(.text.kexec) /* Page aligned in the object file. */ + kexec_reloc_end = .; *(.text.cold) *(.text.unlikely) @@ -428,7 +429,7 @@ ASSERT(__2M_rwdata_end <= XEN_VIRT_END - XEN_VIRT_START + __XEN_VIRT_START - "Xen image overlaps stubs area") #ifdef CONFIG_KEXEC -ASSERT(kexec_reloc_size - kexec_reloc <= PAGE_SIZE, "kexec_reloc is too large") +ASSERT(kexec_reloc_end - kexec_reloc <= PAGE_SIZE, "kexec_reloc is too large") #endif /* The Multiboot setup paths relies on this to simplify superpage PTE creation. */ -- 2.11.0