hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/arch/x86/boot/compressed/head_64.S
....@@ -454,11 +454,25 @@
454454 /* Save the trampoline address in RCX */
455455 movq %rax, %rcx
456456
457
+ /* Set up 32-bit addressable stack */
458
+ leaq TRAMPOLINE_32BIT_STACK_END(%rcx), %rsp
459
+
457460 /*
458
- * Load the address of trampoline_return() into RDI.
459
- * It will be used by the trampoline to return to the main code.
461
+ * Preserve live 64-bit registers on the stack: this is necessary
462
+ * because the architecture does not guarantee that GPRs will retain
463
+ * their full 64-bit values across a 32-bit mode switch.
464
+ */
465
+ pushq %rbp
466
+ pushq %rbx
467
+ pushq %rsi
468
+
469
+ /*
470
+ * Push the 64-bit address of trampoline_return() onto the new stack.
471
+ * It will be used by the trampoline to return to the main code. Due to
472
+ * the 32-bit mode switch, it cannot be kept it in a register either.
460473 */
461474 leaq trampoline_return(%rip), %rdi
475
+ pushq %rdi
462476
463477 /* Switch to compatibility mode (CS.L = 0 CS.D = 1) via far return */
464478 pushq $__KERNEL32_CS
....@@ -466,6 +480,11 @@
466480 pushq %rax
467481 lretq
468482 trampoline_return:
483
+ /* Restore live 64-bit registers */
484
+ popq %rsi
485
+ popq %rbx
486
+ popq %rbp
487
+
469488 /* Restore the stack, the 32-bit trampoline uses its own stack */
470489 leaq rva(boot_stack_end)(%rbx), %rsp
471490
....@@ -586,7 +605,7 @@
586605 /*
587606 * This is the 32-bit trampoline that will be copied over to low memory.
588607 *
589
- * RDI contains the return address (might be above 4G).
608
+ * Return address is at the top of the stack (might be above 4G).
590609 * ECX contains the base address of the trampoline memory.
591610 * Non zero RDX means trampoline needs to enable 5-level paging.
592611 */
....@@ -595,9 +614,6 @@
595614 movl $__KERNEL_DS, %eax
596615 movl %eax, %ds
597616 movl %eax, %ss
598
-
599
- /* Set up new stack */
600
- leal TRAMPOLINE_32BIT_STACK_END(%ecx), %esp
601617
602618 /* Disable paging */
603619 movl %cr0, %eax
....@@ -658,7 +674,7 @@
658674 .code64
659675 SYM_FUNC_START_LOCAL_NOALIGN(.Lpaging_enabled)
660676 /* Return from the trampoline */
661
- jmp *%rdi
677
+ retq
662678 SYM_FUNC_END(.Lpaging_enabled)
663679
664680 /*