Previously, Xen used information from the BDA to detect the amount of
available low memory. This does not work on some scenarios such as
Coreboot, or when booting from Kexec on a UEFI system without CSM.

Prioritize the information supplied by Multiboot instead. If this is not
available, fall back to the old BDA method.

Signed-off-by: Tu Dinh Ngoc <[email protected]>
---
Changes in v3:
- Prioritize using Multiboot's memory information.. Fall back to using
  BDA in case MBI does not supply memory info.

Changes in v2:
- Detect if Multiboot claims there's more than 640 KB of low memory
  (happens with old Kexec versions), and correct the memory unit in such
  cases.
---
 xen/arch/x86/boot/head.S | 44 ++++++++++++++++++++++++++--------------
 1 file changed, 29 insertions(+), 15 deletions(-)

diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S
index dd1bea0d10..da7810060e 100644
--- a/xen/arch/x86/boot/head.S
+++ b/xen/arch/x86/boot/head.S
@@ -524,27 +524,41 @@ trampoline_bios_setup:
         mov     %ecx,%fs
         mov     %ecx,%gs
 
-        /* Set up trampoline segment 64k below EBDA */
-        movzwl  0x40e,%ecx          /* EBDA segment */
-        cmp     $0xa000,%ecx        /* sanity check (high) */
-        jae     0f
-        cmp     $0x4000,%ecx        /* sanity check (low) */
-        jae     1f
+        /* Check if Multiboot provides us with low memory size. */
+        mov     %edx,%ecx
+        test    %ecx,%ecx
+        jz      1f
+
+        /*
+         * Old Kexec used to report memory sizes in bytes instead of kilobytes
+         * like it's supposed to.
+         *
+         * If Multiboot reports more than 640 KB of low memory, assume we have
+         * this problem.
+         */
+        cmp     $640,%ecx
+        jbe     0f
+        shr     $10,%ecx
 0:
-        movzwl  0x413,%ecx          /* use base memory size on failure */
+        /* %ecx now contains the low memory size in kilobytes. */
         shl     $10-4,%ecx
+        jmp     3f
+
 1:
         /*
-         * Compare the value in the BDA with the information from the
-         * multiboot structure (if available) and use the smallest.
+         * Multiboot doesn't provide us with memory info. Set up trampoline
+         * segment 64k below EBDA as fallback.
          */
-        cmp     $0x100,%edx         /* is the multiboot value too small? */
-        jb      2f                  /* if so, do not use it */
-        shl     $10-4,%edx
-        cmp     %ecx,%edx           /* compare with BDA value */
-        cmovb   %edx,%ecx           /* and use the smaller */
-
+        movzwl  0x40e,%ecx          /* EBDA segment */
+        cmp     $0xa000,%ecx        /* sanity check (high) */
+        jae     2f
+        cmp     $0x4000,%ecx        /* sanity check (low) */
+        jae     3f
 2:
+        movzwl  0x413,%ecx          /* use base memory size on failure */
+        shl     $10-4,%ecx
+
+3:
         /* Reserve memory for the trampoline and the low-memory stack. */
         sub     $((TRAMPOLINE_SPACE+TRAMPOLINE_STACK_SPACE)>>4),%ecx
 
-- 
2.25.1


Reply via email to