From: Ross Philipson <ross.philip...@oracle.com> Signed-off-by: Ross Philipson <ross.philip...@oracle.com> Signed-off-by: Sergii Dmytruk <sergii.dmyt...@3mdeb.com> --- grub-core/loader/efi/dltrampoline.S | 94 +++++++++++++++++++++++++++++ grub-core/loader/slaunch/dlstub.c | 93 ++++++++++++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 grub-core/loader/efi/dltrampoline.S create mode 100644 grub-core/loader/slaunch/dlstub.c
diff --git a/grub-core/loader/efi/dltrampoline.S b/grub-core/loader/efi/dltrampoline.S new file mode 100644 index 000000000..461e14271 --- /dev/null +++ b/grub-core/loader/efi/dltrampoline.S @@ -0,0 +1,94 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2024, Oracle and/or its affiliates. + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <config.h> +#include <grub/symbol.h> + +#define GRUB_SMX_LEAF_SENTER 4 +#define CS_SEL32 0x0008 +#define DS_SEL 0x0010 + +#define CR0_PE 0x00000001 +#define CR0_MP 0x00000002 +#define CR0_TS 0x00000008 +#define CR0_NE 0x00000020 + + .file "dltrampoline.S" + .text + + .code64 + .globl dl_entry_trampoline +dl_entry_trampoline: + /* %edi should contain dl_context pointer */ + call EXT_C(dl_entry) + ud2 + + .globl dl_trampoline +dl_trampoline: + cli + leaq dl_gdt_base(%rip), %rax + leaq dl_gdt(%rip), %rbx + movl %ebx, (%eax) + lgdt dl_gdtr(%rip) + + /* Setup target to ret to compat mode */ + leal 1f(%rip), %ecx + pushq $CS_SEL32 + pushq %rcx + lretq + + .code32 +1: /* Now in IA-32e compatibility mode load data segments and do senter */ + movw $DS_SEL, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw %ax, %fs + movw %ax, %gs + + movl $GRUB_SMX_LEAF_SENTER, %eax + movl %edi, %ebx + movl %esi, %ecx + xorl %edx, %edx + getsec + + .align 8 +dl_gdt: + /* Null Segment */ + .quad 0 + /* 32b Code Segment */ + .word 0xffff /* Limit 1 */ + .word 0x0000 /* Base 1 */ + .byte 0x00 /* Base 2 */ + .byte 0x9b /* P=1 DPL=0 S=1 Type=0010 C=0 W=1 A=1 */ + .byte 0xcf /* G=1 D=1 L=0 AVL=0 Limit 2 */ + .byte 0x00 /* Base 3 */ + /* Data Segment, can be used both in 32b and 64b */ + .word 0xffff /* Limit 1 */ + .word 0x0000 /* Base 1 */ + .byte 0x00 /* Base 2 */ + .byte 0x93 /* P=1 DPL=0 S=1 Type=0010 C=0 W=1 A=1 */ + .byte 0xcf /* G=1 D=1 L=0 AVL=0 Limit 2 */ + .byte 0x00 /* Base 3 */ + + .word 0 +dl_gdtr: + .word 23 /* Limit */ +dl_gdt_base: + .long 0 /* Base */ + .long 0 diff --git a/grub-core/loader/slaunch/dlstub.c b/grub-core/loader/slaunch/dlstub.c new file mode 100644 index 000000000..d3c28645e --- /dev/null +++ b/grub-core/loader/slaunch/dlstub.c @@ -0,0 +1,93 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2024, Oracle and/or its affiliates. + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <grub/loader.h> +#include <grub/normal.h> +#include <grub/err.h> +#include <grub/misc.h> +#include <grub/types.h> +#include <grub/dl.h> +#include <grub/slr_table.h> +#include <grub/slaunch.h> +#include <grub/cpu/relocator.h> +#include <grub/i386/msr.h> +#include <grub/i386/mmio.h> +#include <grub/i386/txt.h> + +GRUB_MOD_LICENSE ("GPLv3+"); + +extern void dl_trampoline(grub_uint32_t dce_base, grub_uint32_t dce_size); + +void dl_entry (grub_uint64_t dl_ctx) +{ + struct grub_slr_bl_context *bl_ctx = (struct grub_slr_bl_context *)(grub_addr_t)dl_ctx; + struct grub_slaunch_params *slparams = (struct grub_slaunch_params *)(grub_addr_t)bl_ctx->context; + struct grub_relocator32_state state = {0}; + grub_err_t err; + + state.edi = slparams->platform_type; + + if (slparams->platform_type == SLP_INTEL_TXT) + { + if (slparams->boot_type == GRUB_SL_BOOT_TYPE_EFI) + grub_update_slrt_policy (slparams); + + err = grub_set_mtrrs_for_acmod ((void *)(grub_addr_t)slparams->dce_base); + if (err) + { + grub_error (GRUB_ERR_BAD_DEVICE, N_("setting MTRRs for TXT SINIT failed")); + return; + } + + err = grub_txt_prepare_cpu (); + if ( err ) + { + grub_error (GRUB_ERR_BAD_DEVICE, N_("prepare CPU for TXT SENTER failed")); + return; + } + } + else + { + grub_error (GRUB_ERR_BUG, N_("unknown dynamic launch platform: %d"), slparams->platform_type); + return; + } + + if (!(grub_rdmsr (GRUB_MSR_X86_APICBASE) & GRUB_MSR_X86_APICBASE_BSP)) + { + grub_error (GRUB_ERR_BAD_DEVICE, N_("x86 dynamic launch event must be performed on the BSP")); + return; + } + + if (slparams->boot_type == GRUB_SL_BOOT_TYPE_LINUX) + { + /* Configure relocator GETSEC[SENTER] call. */ + state.eax = GRUB_SMX_LEAF_SENTER; + state.ebx = slparams->dce_base; + state.ecx = slparams->dce_size; + state.edx = 0; + grub_relocator32_boot (slparams->relocator, state, 0); + } + else if (slparams->boot_type == GRUB_SL_BOOT_TYPE_EFI) + { + dl_trampoline (slparams->dce_base, slparams->dce_size); + } + else + { + grub_error (GRUB_ERR_BUG, N_("unknown dynamic launch boot type: %d"), slparams->boot_type); + } +} -- 2.47.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel