[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[xen staging] x86/kexec: Annotate embedded data with ELF metadata



commit 7764fd93cf24d59b98fd1ee1c3f03a1fda83633a
Author:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Wed Feb 16 18:24:43 2022 +0000
Commit:     Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Wed Feb 23 15:33:42 2022 +0000

    x86/kexec: Annotate embedded data with ELF metadata
    
    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.cooper3@xxxxxxxxxx>
    Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
 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 ba0d469d07..d4880818c1 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 08ec9fd43b..751a9efcaf 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 d488d127cf..89316bc3a7 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 82ad8feb6e..7ffecd4630 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. */
--
generated by git-patchbot for /home/xen/git/xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.