From 6e7a315eb67cb6c113cf37e1d66c4f11a51a2b3e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 18:29:51 +0200 Subject: Adding upstream version 2.06. Signed-off-by: Daniel Baumann --- grub-core/lib/x86_64/xen/relocator.S | 133 +++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 grub-core/lib/x86_64/xen/relocator.S (limited to 'grub-core/lib/x86_64/xen/relocator.S') diff --git a/grub-core/lib/x86_64/xen/relocator.S b/grub-core/lib/x86_64/xen/relocator.S new file mode 100644 index 0000000..f5364ed --- /dev/null +++ b/grub-core/lib/x86_64/xen/relocator.S @@ -0,0 +1,133 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2013 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +/* Macro to load an imm64 value stored by the C-part into %rax: */ +#define MOV_IMM64_RAX(var) .byte 0x48, 0xb8; VARIABLE(var); .quad 0 + + .p2align 4 /* force 16-byte alignment */ + +VARIABLE(grub_relocator_xen_remap_start) +LOCAL(base): + /* Remap the remapper to it's new address. */ + MOV_IMM64_RAX(grub_relocator_xen_remapper_virt) + + movq %rax, %rdi /* %rdi: new virtual address of remapper */ + movq %rax, %rbx /* Remember new virtual address */ + + MOV_IMM64_RAX(grub_relocator_xen_remapper_map) + + movq %rax, %rsi /* %rsi: page table entry */ + + movq $UVMF_INVLPG, %rdx /* %rdx: flags (inv. single entry) */ + movq $__HYPERVISOR_update_va_mapping, %rax + syscall /* Do the remap operation */ + + addq $(LOCAL(cont) - LOCAL(base)), %rbx + + jmp *%rbx /* Continue with new virtual address */ + +LOCAL(cont): + /* Modify mappings of new page tables to be read-only. */ + MOV_IMM64_RAX(grub_relocator_xen_mfn_list) + + movq %rax, %rbx /* %rbx is the base of the p2m list */ + leaq EXT_C(grub_relocator_xen_paging_areas) (%rip), %r8 + +1: + movq 0(%r8), %r12 /* Get start pfn of the current area */ + movq GRUB_TARGET_SIZEOF_LONG(%r8), %rcx /* Get # of pg tables */ + testq %rcx, %rcx /* 0 -> last area reached */ + jz 3f +2: + movq %r12, %rdi + shlq $PAGE_SHIFT, %rdi /* virtual address (1:1 mapping) */ + movq (%rbx, %r12, 8), %rsi /* mfn */ + shlq $PAGE_SHIFT, %rsi + orq $(GRUB_PAGE_PRESENT | GRUB_PAGE_USER), %rsi /* Build pte */ + movq $UVMF_INVLPG, %rdx + movq %rcx, %r9 /* %rcx clobbered by hypercall */ + movq $__HYPERVISOR_update_va_mapping, %rax + syscall + + movq %r9, %rcx + incq %r12 /* next pfn */ + + loop 2b + + addq $(2 * GRUB_TARGET_SIZEOF_LONG), %r8 /* next pg table area */ + jmp 1b + +3: + /* Switch page tables: pin new L4 pt, load cr3, unpin old L4. */ + leaq EXT_C(grub_relocator_xen_mmu_op) (%rip), %rdi + movq $3, %rsi /* 3 mmu ops */ + movq $0, %rdx /* pdone (not used) */ + movq $DOMID_SELF, %r10 + movq $__HYPERVISOR_mmuext_op, %rax + syscall + + /* Continue in virtual kernel mapping. */ + MOV_IMM64_RAX(grub_relocator_xen_remap_continue) + + jmp *%rax + +VARIABLE(grub_relocator_xen_paging_areas) + /* array of start, size pairs, size 0 is end marker */ + .quad 0, 0, 0, 0, 0, 0, 0, 0 + +VARIABLE(grub_relocator_xen_mmu_op) + .space 256 + +VARIABLE(grub_relocator_xen_remap_end) + + +VARIABLE(grub_relocator_xen_start) + /* Unmap old remapper area. */ + MOV_IMM64_RAX(grub_relocator_xen_remapper_virt2) + + movq %rax, %rdi + + xorq %rax, %rax /* Invalid pte */ + movq %rax, %rsi + + movq $UVMF_INVLPG, %rdx + movq $__HYPERVISOR_update_va_mapping, %rax + syscall + + /* Prepare registers for starting kernel. */ + MOV_IMM64_RAX(grub_relocator_xen_stack) + + movq %rax, %rsp + + MOV_IMM64_RAX(grub_relocator_xen_start_info) + + movq %rax, %rsi + + cld + + MOV_IMM64_RAX(grub_relocator_xen_entry_point) + + /* Now start the new kernel. */ + jmp *%rax + +VARIABLE(grub_relocator_xen_end) -- cgit v1.2.3