From nobody Thu Dec 05 00:18:56 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4Y3ZkS6HRZz5gRVl; Thu, 05 Dec 2024 00:18:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Y3ZkS3FSfz4bGR; Thu, 5 Dec 2024 00:18:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733357936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/nyx0ZH3qvP3gGLi14oaYQRcezwmVJYr5tXmEv7EWpA=; b=P9zcfFyK7KdO5o9W/Yya189R9gO1AozUUinwIsJqUxp+3ql/uIRrc0SQqoDYQGUtxodu+C bch+fATAQ7MPge5ryW5ejTArRCY25Ah8f7ORfxhGy4wczVYcREEOpDnsN5F12yARUQRAfZ 6WyMbvkQbG3s4+zgfE/L/zpcRL4u87oO0rePczWOca+qJ8bbPj4D4RDtF6m0H6foWziCXu XE7U+OI75rkZ4tknCw0VxsNnD2zcW1H3fwJtr1rslBwn5spB92wFzw0R433VNggxk0/1sQ xBDOyqLRuasnvsOa/MpeNBoEy865krcdiOJm8dQ4ng7rlf40a1uQW4+RUP7+3w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1733357936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=/nyx0ZH3qvP3gGLi14oaYQRcezwmVJYr5tXmEv7EWpA=; b=TkJf+gJ2OOzLNZZ8tzIcpMjL38kMCb13uTDF9lPFw895WpGIkoo0bzGlhZXIlwoolrXV/e XLT/EsD5ld/kFMoKTeW1ufLZZiGgg/OrLkznFTvJOUW6OmZZ61do9Sw3y/gXWa04KDSwds FeErstJa4HcC+Cj7OatNqQmIRV74xsP6+eUJY7+NmkBlTxgi4M8g7IE1SHwnimS3ZTm2KU 3sv7+kYVqo1NenND/nQj3/6sb77Q7f9DxzzZjnEFYyOLzu8iCzYZATKMQtNZSdoQijYe5j f6dJ0PKPCEZEJk/1SNoy5FEth18gCHBcuO24y3wmaYtOX7TzYlcdUdAtgt3KHw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1733357936; a=rsa-sha256; cv=none; b=NVd08EaJNOU6BNdd0B+Dkdpf3dsWpilOlyOazCmfMLQP5Bm14B87i+PYZbGRPFtXBcdVe5 hCPsJ0oBCqm5u7+YWw28PDjaVVTSigcMj9n1ZP6BDpHoG0r3gxYK0vPkRA8yN9pbW3YVWH TwDMJ+NHD6pMGBhtf5wLmy87wzxHgc+WpPRvLVJ4t+Mobawux6U7t+dYV16b04sO408nvX zn+0TWHJQWzSegIxf6qtVGyLmw/mxp647PzbGW3F05+V0s82ygOoTj5NGLs8h+x7PO8u9I vqfvuFnmhk4JEOBonroLWkY04EvuaMA3iCGd2YSfujLRCCaWAdoflsKbPFH63g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4Y3ZkS2mQBzTlw; Thu, 5 Dec 2024 00:18:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4B50Iumf013467; Thu, 5 Dec 2024 00:18:56 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4B50IuJR013464; Thu, 5 Dec 2024 00:18:56 GMT (envelope-from git) Date: Thu, 5 Dec 2024 00:18:56 GMT Message-Id: <202412050018.4B50IuJR013464@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Warner Losh Subject: git: 5e8bd45ffb41 - main - stand/elf64_freebsd.c: use headers instead of doing things ourselves List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 5e8bd45ffb416f6d4e041690e3e656fd907492bf Auto-Submitted: auto-generated The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=5e8bd45ffb416f6d4e041690e3e656fd907492bf commit 5e8bd45ffb416f6d4e041690e3e656fd907492bf Author: Ahmad Khalifa AuthorDate: 2024-09-27 16:08:11 +0000 Commit: Warner Losh CommitDate: 2024-12-05 00:19:17 +0000 stand/elf64_freebsd.c: use headers instead of doing things ourselves Try our best to use headers instead of doing things ourselves. With i386's headers, there are some holes we need to fill manually. Reviewed by: imp Pull Request: https://github.com/freebsd/freebsd-src/pull/1446 --- stand/efi/loader/arch/i386/elf64_freebsd.c | 104 ++++++++++++++++------------- stand/i386/libi386/elf64_freebsd.c | 24 ++++--- stand/userboot/userboot/elf64_freebsd.c | 53 ++++++--------- 3 files changed, 89 insertions(+), 92 deletions(-) diff --git a/stand/efi/loader/arch/i386/elf64_freebsd.c b/stand/efi/loader/arch/i386/elf64_freebsd.c index 0dc16437d905..b02cda2269bc 100644 --- a/stand/efi/loader/arch/i386/elf64_freebsd.c +++ b/stand/efi/loader/arch/i386/elf64_freebsd.c @@ -28,7 +28,11 @@ #define __ELF_WORD_SIZE 64 #include #include +#include +#include #include +#include +#include #include #include @@ -56,35 +60,14 @@ struct file_format *file_formats[] = { NULL }; -struct gdtr { - uint16_t size; - uint64_t ptr; -} __packed; - -#define PG_V 0x001 -#define PG_RW 0x002 -#define PG_PS 0x080 - -#define GDT_P 0x00800000000000 -#define GDT_E 0x00080000000000 -#define GDT_S 0x00100000000000 -#define GDT_RW 0x00020000000000 -#define GDT_L 0x20000000000000 - -typedef uint64_t p4_entry_t; -typedef uint64_t p3_entry_t; -typedef uint64_t p2_entry_t; -typedef uint64_t gdt_t; - -static p4_entry_t *PT4; -static p3_entry_t *PT3; -static p3_entry_t *PT3_l, *PT3_u; -static p2_entry_t *PT2; -static p2_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1; -static gdt_t *GDT; +/* + * i386's pmap_pae.h doesn't provide this, so + * just typedef our own. + */ +typedef pdpt_entry_t pml4_entry_t; static void (*trampoline)(uint32_t stack, void *copy_finish, uint32_t kernend, - uint32_t modulep, uint64_t *pagetable, struct gdtr *gdtr, uint64_t entry); + uint32_t modulep, uint64_t *pagetable, void *gdtr, uint64_t entry); extern void *amd64_tramp; extern uint32_t amd64_tramp_size; @@ -97,12 +80,23 @@ extern uint32_t amd64_tramp_size; static int elf64_exec(struct preloaded_file *fp) { + /* + * segments.h gives us a 32-bit gdtr, but + * we want a 64-bit one, so define our own. + */ + struct { + uint16_t rd_limit; + uint64_t rd_base; + } __packed *gdtr; EFI_PHYSICAL_ADDRESS ptr; EFI_ALLOCATE_TYPE type; EFI_STATUS err; struct file_metadata *md; - struct gdtr *gdtr; Elf_Ehdr *ehdr; + pml4_entry_t *PT4; + pdpt_entry_t *PT3; + pd_entry_t *PT2; + struct user_segment_descriptor *gdt; vm_offset_t modulep, kernend, trampstack; int i; @@ -123,36 +117,47 @@ elf64_exec(struct preloaded_file *fp) return (EFTYPE); ehdr = (Elf_Ehdr *)&(md->md_data); - /* - * Make our temporary stack 32 bytes big, which is - * a little more than we need. - */ ptr = G(1); err = BS->AllocatePages(type, EfiLoaderCode, - EFI_SIZE_TO_PAGES(amd64_tramp_size + 32), &ptr); + EFI_SIZE_TO_PAGES(amd64_tramp_size), &ptr); if (EFI_ERROR(err)) { printf("Unable to allocate trampoline\n"); return (ENOMEM); } trampoline = (void *)(uintptr_t)ptr; - trampstack = ptr + amd64_tramp_size + 32; bcopy(&amd64_tramp, trampoline, amd64_tramp_size); + /* + * Allocate enough space for the GDTR + two GDT segments + + * our temporary stack (28 bytes). + */ +#define DATASZ (sizeof(*gdtr) + \ + sizeof(struct user_segment_descriptor) * 2 + 28) + ptr = G(1); err = BS->AllocatePages(type, EfiLoaderData, - EFI_SIZE_TO_PAGES(sizeof(struct gdtr) + sizeof(uint64_t) * 2), &ptr); + EFI_SIZE_TO_PAGES(DATASZ), &ptr); if (EFI_ERROR(err)) { - printf("Unable to allocate GDT\n"); + printf("Unable to allocate GDT and stack\n"); BS->FreePages((uintptr_t)trampoline, 1); return (ENOMEM); } - GDT = (gdt_t *)(uintptr_t)ptr; - GDT[1] = GDT_P | GDT_E | GDT_S | GDT_RW | GDT_L; /* CS */ - GDT[0] = 0; - gdtr = (struct gdtr *)&GDT[2]; - gdtr->size = sizeof(uint64_t) * 2 - 1; - gdtr->ptr = (uintptr_t)GDT; + + trampstack = ptr + DATASZ; + +#undef DATASZ + + gdt = (void *)(uintptr_t)ptr; + gdt[0] = (struct user_segment_descriptor) { 0 }; + gdt[1] = (struct user_segment_descriptor) { + .sd_p = 1, .sd_long = 1, .sd_type = SDT_MEMERC + }; + + gdtr = (void *)(uintptr_t)(ptr + + sizeof(struct user_segment_descriptor) * 2); + gdtr->rd_limit = sizeof(struct user_segment_descriptor) * 2 - 1; + gdtr->rd_base = (uintptr_t)gdt; if (type == AllocateMaxAddress) { /* Copy staging enabled */ @@ -163,10 +168,10 @@ elf64_exec(struct preloaded_file *fp) if (EFI_ERROR(err)) { printf("Unable to allocate trampoline page table\n"); BS->FreePages((uintptr_t)trampoline, 1); - BS->FreePages((uintptr_t)GDT, 1); + BS->FreePages((uintptr_t)gdt, 1); return (ENOMEM); } - PT4 = (p4_entry_t *)(uintptr_t)ptr; + PT4 = (pml4_entry_t *)(uintptr_t)ptr; PT3 = &PT4[512]; PT2 = &PT3[512]; @@ -195,15 +200,18 @@ elf64_exec(struct preloaded_file *fp) PT2[i] = (i * M(2)) | PG_V | PG_RW | PG_PS; } } else { + pdpt_entry_t *PT3_l, *PT3_u; + pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1; + err = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, EFI_SIZE_TO_PAGES(512 * 9 * sizeof(uint64_t)), &ptr); if (EFI_ERROR(err)) { printf("Unable to allocate trampoline page table\n"); BS->FreePages((uintptr_t)trampoline, 1); - BS->FreePages((uintptr_t)GDT, 1); + BS->FreePages((uintptr_t)gdt, 1); return (ENOMEM); } - PT4 = (p4_entry_t *)(uintptr_t)ptr; + PT4 = (pml4_entry_t *)(uintptr_t)ptr; PT3_l = &PT4[512]; PT3_u = &PT3_l[512]; @@ -221,7 +229,7 @@ elf64_exec(struct preloaded_file *fp) PT3_l[2] = (uintptr_t)PT2_l2 | PG_V | PG_RW; PT3_l[3] = (uintptr_t)PT2_l3 | PG_V | PG_RW; for (i = 0; i < 2048; i++) { - PT2_l0[i] = ((p2_entry_t)i * M(2)) | PG_V | PG_RW | PG_PS; + PT2_l0[i] = ((pd_entry_t)i * M(2)) | PG_V | PG_RW | PG_PS; } /* mapping of kernel 2G below top */ @@ -240,7 +248,7 @@ elf64_exec(struct preloaded_file *fp) printf( "staging %#llx (%scopying) tramp %p PT4 %p GDT %p\n" "Start @ %#llx ...\n", staging, - type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, GDT, + type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, gdt, ehdr->e_entry ); diff --git a/stand/i386/libi386/elf64_freebsd.c b/stand/i386/libi386/elf64_freebsd.c index b1340fd1f2e2..89cc249e9d96 100644 --- a/stand/i386/libi386/elf64_freebsd.c +++ b/stand/i386/libi386/elf64_freebsd.c @@ -28,8 +28,11 @@ #include #include #include +#include +#include #include #include +#include #include #include @@ -43,16 +46,15 @@ static int elf64_obj_exec(struct preloaded_file *amp); struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; -#define PG_V 0x001 -#define PG_RW 0x002 -#define PG_PS 0x080 +/* + * i386's pmap_pae.h doesn't provide this, so + * just typedef our own. + */ +typedef pdpt_entry_t pml4_entry_t; -typedef uint64_t p4_entry_t; -typedef uint64_t p3_entry_t; -typedef uint64_t p2_entry_t; -extern p4_entry_t PT4[]; -extern p3_entry_t PT3[]; -extern p2_entry_t PT2[]; +extern pml4_entry_t PT4[]; +extern pdpt_entry_t PT3[]; +extern pd_entry_t PT2[]; uint32_t entry_hi; uint32_t entry_lo; @@ -91,11 +93,11 @@ elf64_exec(struct preloaded_file *fp) */ for (i = 0; i < 512; i++) { /* Each slot of the level 4 pages points to the same level 3 page */ - PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]); + PT4[i] = (pml4_entry_t)VTOP((uintptr_t)&PT3[0]); PT4[i] |= PG_V | PG_RW; /* Each slot of the level 3 pages points to the same level 2 page */ - PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]); + PT3[i] = (pdpt_entry_t)VTOP((uintptr_t)&PT2[0]); PT3[i] |= PG_V | PG_RW; /* The level 2 page slots are mapped with 2MB pages for 1GB. */ diff --git a/stand/userboot/userboot/elf64_freebsd.c b/stand/userboot/userboot/elf64_freebsd.c index 7f817a44da88..5a63fdb4990c 100644 --- a/stand/userboot/userboot/elf64_freebsd.c +++ b/stand/userboot/userboot/elf64_freebsd.c @@ -31,9 +31,10 @@ #ifdef DEBUG #include #endif -#include -#include +#include +#include #include +#include #include #include "bootstrap.h" @@ -45,35 +46,21 @@ static int elf64_obj_exec(struct preloaded_file *amp); struct file_format amd64_elf = { elf64_loadfile, elf64_exec }; struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec }; -#define MSR_EFER 0xc0000080 -#define EFER_LME 0x00000100 -#define EFER_LMA 0x00000400 /* Long mode active (R) */ -#define CR4_PAE 0x00000020 -#define CR4_VMXE (1UL << 13) -#define CR4_PSE 0x00000010 -#define CR0_PG 0x80000000 -#define CR0_PE 0x00000001 /* Protected mode Enable */ -#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */ - -#define PG_V 0x001 -#define PG_RW 0x002 -#define PG_PS 0x080 - -typedef uint64_t p4_entry_t; -typedef uint64_t p3_entry_t; -typedef uint64_t p2_entry_t; - #define GUEST_NULL_SEL 0 #define GUEST_CODE_SEL 1 #define GUEST_DATA_SEL 2 #define GUEST_GDTR_LIMIT (3 * 8 - 1) static void -setup_freebsd_gdt(uint64_t *gdtr) +setup_freebsd_gdt(struct user_segment_descriptor *gdt) { - gdtr[GUEST_NULL_SEL] = 0; - gdtr[GUEST_CODE_SEL] = 0x0020980000000000; - gdtr[GUEST_DATA_SEL] = 0x0000900000000000; + gdt[GUEST_NULL_SEL] = (struct user_segment_descriptor) { 0 }; + gdt[GUEST_CODE_SEL] = (struct user_segment_descriptor) { + .sd_p = 1, .sd_long = 1, .sd_type = SDT_MEME + }; + gdt[GUEST_DATA_SEL] = (struct user_segment_descriptor) { + .sd_p = 1, .sd_type = SDT_MEMRO + }; } /* @@ -90,10 +77,10 @@ elf64_exec(struct preloaded_file *fp) int err; int i; uint32_t stack[1024]; - p4_entry_t PT4[512]; - p3_entry_t PT3[512]; - p2_entry_t PT2[512]; - uint64_t gdtr[3]; + pml4_entry_t PT4[512]; + pdp_entry_t PT3[512]; + pd_entry_t PT2[512]; + struct user_segment_descriptor gdt[3]; if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); @@ -122,11 +109,11 @@ elf64_exec(struct preloaded_file *fp) */ for (i = 0; i < 512; i++) { /* Each slot of the level 4 pages points to the same level 3 page */ - PT4[i] = (p4_entry_t) 0x3000; + PT4[i] = (pml4_entry_t) 0x3000; PT4[i] |= PG_V | PG_RW; /* Each slot of the level 3 pages points to the same level 2 page */ - PT3[i] = (p3_entry_t) 0x4000; + PT3[i] = (pdp_entry_t) 0x4000; PT3[i] |= PG_V | PG_RW; /* The level 2 page slots are mapped with 2MB pages for 1GB. */ @@ -154,9 +141,9 @@ elf64_exec(struct preloaded_file *fp) CALLBACK(setcr, 3, 0x2000); CALLBACK(setcr, 0, CR0_PG | CR0_PE | CR0_NE); - setup_freebsd_gdt(gdtr); - CALLBACK(copyin, gdtr, 0x5000, sizeof(gdtr)); - CALLBACK(setgdt, 0x5000, sizeof(gdtr)); + setup_freebsd_gdt(gdt); + CALLBACK(copyin, gdt, 0x5000, sizeof(gdt)); + CALLBACK(setgdt, 0x5000, sizeof(gdt)); CALLBACK(exec, ehdr->e_entry);