From patchwork Wed Sep 4 14:56:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frediano Ziglio X-Patchwork-Id: 13791075 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8F61ECD4857 for ; Wed, 4 Sep 2024 14:57:24 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.790436.1200183 (Exim 4.92) (envelope-from ) id 1slrRR-0001CA-Pg; Wed, 04 Sep 2024 14:57:05 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 790436.1200183; Wed, 04 Sep 2024 14:57:05 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRR-0001C3-Mv; Wed, 04 Sep 2024 14:57:05 +0000 Received: by outflank-mailman (input) for mailman id 790436; Wed, 04 Sep 2024 14:57:03 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRP-0001Be-QU for xen-devel@lists.xenproject.org; Wed, 04 Sep 2024 14:57:03 +0000 Received: from mail-ed1-x531.google.com (mail-ed1-x531.google.com [2a00:1450:4864:20::531]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f1a4bf85-6acd-11ef-a0b3-8be0dac302b0; Wed, 04 Sep 2024 16:57:02 +0200 (CEST) Received: by mail-ed1-x531.google.com with SMTP id 4fb4d7f45d1cf-5bef295a429so1070863a12.2 for ; Wed, 04 Sep 2024 07:57:02 -0700 (PDT) Received: from fziglio-xenia-fedora.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5c3cc56c501sm18862a12.52.2024.09.04.07.57.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 07:57:01 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: f1a4bf85-6acd-11ef-a0b3-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1725461822; x=1726066622; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=H2XLzta5aUPYVTAfd1K28dnU5rjnLpIfui7Cf5/r5KQ=; b=jP8ZevKMqmmu/mAMD0kGn4lr4Zo+qcxrEJfw4TaVrxEc7QMWGsXSEiIbricKrCogXi if09DwlKKuhBI6exLFSecbJE87cOOqUH0sAnC2w2kZxNx5CV/SpkzI5ZXRS+2v7i0dPY 3m/MW089iQXAYMdL6vtakwHMCe3HZJzIdZt/c= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725461822; x=1726066622; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=H2XLzta5aUPYVTAfd1K28dnU5rjnLpIfui7Cf5/r5KQ=; b=lBlNYQunj0Ky/eB6e+NQD4CZPUR69QhW6RfXAqvhejr5PDLc11mp8BMzUKRsdcQfS9 RQCiVoXy+l4KnUVV1BrSPO3QoIeTnzGqgOhyG5iuBo8thtrzuMA6woVViJ9+fp08aSzg 8zmO6cezKzzHx6BB6CwmjVsULPR5SoW8bBDAKZab6DWkv5MulVhMVF/cS1RAfvkAL/ZJ kN62Z1YOuLkLOe+XmTgxHQJ+pjdBejPzanjo8AR2/aC2nAvBun0ZRPoqOH9myKriR7cH rIQmIJMFPCmpZW/JIJFHdehodDyDAwkFSwH3106dOXIXqp0qNfYfXiZ/sHpR4zaNq5jw A0Sw== X-Gm-Message-State: AOJu0YxYq5mrK7jFNFh+2GnfTU4li1aIourUIyx6fdbl3c+XQESvwDmL Ltn7dmGOCKg6Jlp4k+FF6uw2/G8FcOBwDzhpvsu+NBtowOdobuvwo0qrjOOoQV018CsoZQGE0OW 4 X-Google-Smtp-Source: AGHT+IGqgeZCHMlbOlVzNCPm9aIs6RyyjIS1QCMGTLMuwlRgWzHc7PSzqeWrVWP56rm7TMUE30KSBw== X-Received: by 2002:a05:6402:210b:b0:5c2:5ca0:807a with SMTP id 4fb4d7f45d1cf-5c2caf22e50mr2018608a12.22.1725461821752; Wed, 04 Sep 2024 07:57:01 -0700 (PDT) From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [RFC 1/5] Avoid usage of global in reloc.c Date: Wed, 4 Sep 2024 15:56:44 +0100 Message-ID: <20240904145648.33707-2-frediano.ziglio@cloud.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240904145648.33707-1-frediano.ziglio@cloud.com> References: <20240904145648.33707-1-frediano.ziglio@cloud.com> MIME-Version: 1.0 All code and dat from this file will go into a text section which we want to not be writeable. Signed-off-by: Frediano Ziglio --- xen/arch/x86/boot/reloc.c | 62 ++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c index 201e38d544..de8487483a 100644 --- a/xen/arch/x86/boot/reloc.c +++ b/xen/arch/x86/boot/reloc.c @@ -72,11 +72,13 @@ struct vesa_mode_info { #define get_mb2_data(tag, type, member) (((const multiboot2_tag_##type##_t *)(tag))->member) #define get_mb2_string(tag, type, member) ((uint32_t)get_mb2_data(tag, type, member)) -static uint32_t alloc; +typedef struct memctx { + uint32_t alloc; +} memctx; -static uint32_t alloc_mem(uint32_t bytes) +static uint32_t alloc_mem(uint32_t bytes, memctx *ctx) { - return alloc -= ROUNDUP(bytes, 16); + return ctx->alloc -= ROUNDUP(bytes, 16); } static void zero_mem(uint32_t s, uint32_t bytes) @@ -85,11 +87,11 @@ static void zero_mem(uint32_t s, uint32_t bytes) *(char *)s++ = 0; } -static uint32_t copy_mem(uint32_t src, uint32_t bytes) +static uint32_t copy_mem(uint32_t src, uint32_t bytes, memctx *ctx) { uint32_t dst, dst_ret; - dst = alloc_mem(bytes); + dst = alloc_mem(bytes, ctx); dst_ret = dst; while ( bytes-- ) @@ -98,7 +100,7 @@ static uint32_t copy_mem(uint32_t src, uint32_t bytes) return dst_ret; } -static uint32_t copy_string(uint32_t src) +static uint32_t copy_string(uint32_t src, memctx *ctx) { uint32_t p; @@ -108,17 +110,17 @@ static uint32_t copy_string(uint32_t src) for ( p = src; *(char *)p != '\0'; p++ ) continue; - return copy_mem(src, p - src + 1); + return copy_mem(src, p - src + 1, ctx); } -static struct hvm_start_info *pvh_info_reloc(uint32_t in) +static struct hvm_start_info *pvh_info_reloc(uint32_t in, memctx *ctx) { struct hvm_start_info *out; - out = _p(copy_mem(in, sizeof(*out))); + out = _p(copy_mem(in, sizeof(*out), ctx)); if ( out->cmdline_paddr ) - out->cmdline_paddr = copy_string(out->cmdline_paddr); + out->cmdline_paddr = copy_string(out->cmdline_paddr, ctx); if ( out->nr_modules ) { @@ -127,51 +129,51 @@ static struct hvm_start_info *pvh_info_reloc(uint32_t in) out->modlist_paddr = copy_mem(out->modlist_paddr, - out->nr_modules * sizeof(struct hvm_modlist_entry)); + out->nr_modules * sizeof(struct hvm_modlist_entry), ctx); mods = _p(out->modlist_paddr); for ( i = 0; i < out->nr_modules; i++ ) { if ( mods[i].cmdline_paddr ) - mods[i].cmdline_paddr = copy_string(mods[i].cmdline_paddr); + mods[i].cmdline_paddr = copy_string(mods[i].cmdline_paddr, ctx); } } return out; } -static multiboot_info_t *mbi_reloc(uint32_t mbi_in) +static multiboot_info_t *mbi_reloc(uint32_t mbi_in, memctx *ctx) { int i; multiboot_info_t *mbi_out; - mbi_out = _p(copy_mem(mbi_in, sizeof(*mbi_out))); + mbi_out = _p(copy_mem(mbi_in, sizeof(*mbi_out), ctx)); if ( mbi_out->flags & MBI_CMDLINE ) - mbi_out->cmdline = copy_string(mbi_out->cmdline); + mbi_out->cmdline = copy_string(mbi_out->cmdline, ctx); if ( mbi_out->flags & MBI_MODULES ) { module_t *mods; mbi_out->mods_addr = copy_mem(mbi_out->mods_addr, - mbi_out->mods_count * sizeof(module_t)); + mbi_out->mods_count * sizeof(module_t), ctx); mods = _p(mbi_out->mods_addr); for ( i = 0; i < mbi_out->mods_count; i++ ) { if ( mods[i].string ) - mods[i].string = copy_string(mods[i].string); + mods[i].string = copy_string(mods[i].string, ctx); } } if ( mbi_out->flags & MBI_MEMMAP ) - mbi_out->mmap_addr = copy_mem(mbi_out->mmap_addr, mbi_out->mmap_length); + mbi_out->mmap_addr = copy_mem(mbi_out->mmap_addr, mbi_out->mmap_length, ctx); if ( mbi_out->flags & MBI_LOADERNAME ) - mbi_out->boot_loader_name = copy_string(mbi_out->boot_loader_name); + mbi_out->boot_loader_name = copy_string(mbi_out->boot_loader_name, ctx); /* Mask features we don't understand or don't relocate. */ mbi_out->flags &= (MBI_MEMLIMITS | @@ -183,7 +185,7 @@ static multiboot_info_t *mbi_reloc(uint32_t mbi_in) return mbi_out; } -static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out) +static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out, memctx *ctx) { const multiboot2_fixed_t *mbi_fix = _p(mbi_in); const multiboot2_memory_map_t *mmap_src; @@ -197,7 +199,7 @@ static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out) uint32_t ptr; unsigned int i, mod_idx = 0; - ptr = alloc_mem(sizeof(*mbi_out)); + ptr = alloc_mem(sizeof(*mbi_out), ctx); mbi_out = _p(ptr); zero_mem(ptr, sizeof(*mbi_out)); @@ -222,7 +224,7 @@ static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out) * __start_xen() may put Xen image placement into it. */ mbi_out->mods_addr = alloc_mem((mbi_out->mods_count + 1) * - sizeof(*mbi_out_mods)); + sizeof(*mbi_out_mods), ctx); mbi_out_mods = _p(mbi_out->mods_addr); } @@ -238,13 +240,13 @@ static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out) case MULTIBOOT2_TAG_TYPE_BOOT_LOADER_NAME: mbi_out->flags |= MBI_LOADERNAME; ptr = get_mb2_string(tag, string, string); - mbi_out->boot_loader_name = copy_string(ptr); + mbi_out->boot_loader_name = copy_string(ptr, ctx); break; case MULTIBOOT2_TAG_TYPE_CMDLINE: mbi_out->flags |= MBI_CMDLINE; ptr = get_mb2_string(tag, string, string); - mbi_out->cmdline = copy_string(ptr); + mbi_out->cmdline = copy_string(ptr, ctx); break; case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO: @@ -263,7 +265,7 @@ static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out) mbi_out->mmap_length /= get_mb2_data(tag, mmap, entry_size); mbi_out->mmap_length *= sizeof(*mmap_dst); - mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length); + mbi_out->mmap_addr = alloc_mem(mbi_out->mmap_length, ctx); mmap_src = get_mb2_data(tag, mmap, entries); mmap_dst = _p(mbi_out->mmap_addr); @@ -290,7 +292,7 @@ static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out) mbi_out_mods[mod_idx].mod_start = get_mb2_data(tag, module, mod_start); mbi_out_mods[mod_idx].mod_end = get_mb2_data(tag, module, mod_end); ptr = get_mb2_string(tag, module, cmdline); - mbi_out_mods[mod_idx].string = copy_string(ptr); + mbi_out_mods[mod_idx].string = copy_string(ptr, ctx); mbi_out_mods[mod_idx].reserved = 0; ++mod_idx; break; @@ -356,19 +358,19 @@ static multiboot_info_t *mbi2_reloc(uint32_t mbi_in, uint32_t video_out) void *reloc(uint32_t magic, uint32_t in, uint32_t trampoline, uint32_t video_info) { - alloc = trampoline; + memctx ctx = { trampoline }; switch ( magic ) { case MULTIBOOT_BOOTLOADER_MAGIC: - return mbi_reloc(in); + return mbi_reloc(in, &ctx); case MULTIBOOT2_BOOTLOADER_MAGIC: - return mbi2_reloc(in, video_info); + return mbi2_reloc(in, video_info, &ctx); case XEN_HVM_START_MAGIC_VALUE: if ( IS_ENABLED(CONFIG_PVH_GUEST) ) - return pvh_info_reloc(in); + return pvh_info_reloc(in, &ctx); /* Fallthrough */ default: From patchwork Wed Sep 4 14:56:45 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frediano Ziglio X-Patchwork-Id: 13791070 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8B040CD4851 for ; Wed, 4 Sep 2024 14:57:23 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.790438.1200195 (Exim 4.92) (envelope-from ) id 1slrRS-0001LK-Bf; Wed, 04 Sep 2024 14:57:06 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 790438.1200195; Wed, 04 Sep 2024 14:57:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRS-0001Ke-7B; Wed, 04 Sep 2024 14:57:06 +0000 Received: by outflank-mailman (input) for mailman id 790438; Wed, 04 Sep 2024 14:57:04 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRQ-0001Be-K0 for xen-devel@lists.xenproject.org; Wed, 04 Sep 2024 14:57:04 +0000 Received: from mail-lj1-x234.google.com (mail-lj1-x234.google.com [2a00:1450:4864:20::234]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f22c8885-6acd-11ef-a0b3-8be0dac302b0; Wed, 04 Sep 2024 16:57:03 +0200 (CEST) Received: by mail-lj1-x234.google.com with SMTP id 38308e7fff4ca-2f3edb2d908so22911411fa.2 for ; Wed, 04 Sep 2024 07:57:03 -0700 (PDT) Received: from fziglio-xenia-fedora.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5c3cc56c501sm18862a12.52.2024.09.04.07.57.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 07:57:02 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: f22c8885-6acd-11ef-a0b3-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1725461823; x=1726066623; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=mhuenP36n8TMCf74RJXF7g3MJ6TuGNcropEsMnWR+Rk=; b=OghulXcBnAsCCzGu3dlqy7nClgnDfB7Q/pwBufg3z97Wdrq4e0c/D8PBvb1HdiZkdd lwOtjhUD0hJr67pHdw5vPKPbA6tSVHLNEfYaIlFUNqAlw9p54/4nkROCmztuDgwtUdF6 MYj1/xDZK41umc8kNKu1qMPJQmL1hf9w0vWlY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725461823; x=1726066623; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=mhuenP36n8TMCf74RJXF7g3MJ6TuGNcropEsMnWR+Rk=; b=m1QL9FH5H6me9Bstbn7YUhzyCeM/DSdgZGU1sVtCNcBy16EnOgQaLkSeZnknEz4k40 npBLlJSous9hB3qesVxx1ycFut7Hq7O6xYYcR5kBdFU0BL3FD4N8gMmc4FbB6fKgxiqN 7H1jCXBKnIov0+hrID0JBqnsBOR2VVg/glc0PpG03QfX1m2Kyc8XtnedlnPU0zQ4gWUD LoEkgC9Qlw96qb1HdSV5+4R6nQ9yNcpea+dVi0r3AMqDsleFzcOaBJ4lU45GobVUmv9i +Y21++Z+1I+CG3oJrGNa6dkhK2cU1SmVU0T8FotxLkB9pLibO7+j45OfvKxY/XKmgBCd UEMg== X-Gm-Message-State: AOJu0YwEcAnQKqLjjIGoAeqSbj0PqUpPvFN2jtd7aW0scX/L+phUFeyi cztF8M8w/ujrjZvuC86RbiDdjniFD/vaURYxoN0dI969K7i5IjOqGvCJVTT50CckWTJyp+WoUQH K X-Google-Smtp-Source: AGHT+IE/ZGUZ8ql2kd9pUeMGocx9V4rXrh5/OY7MrGom8aGtdFt0XR3t6lelnO/LleaOkNqgZ1FhBA== X-Received: by 2002:a2e:bc09:0:b0:2ef:2c91:502a with SMTP id 38308e7fff4ca-2f6443faf63mr62366771fa.3.1725461822493; Wed, 04 Sep 2024 07:57:02 -0700 (PDT) From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Andrew Cooper , Jan Beulich , Julien Grall , Stefano Stabellini , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [RFC 2/5] x86/boot: create a C bundle for 32 bit boot code and use it Date: Wed, 4 Sep 2024 15:56:45 +0100 Message-ID: <20240904145648.33707-3-frediano.ziglio@cloud.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240904145648.33707-1-frediano.ziglio@cloud.com> References: <20240904145648.33707-1-frediano.ziglio@cloud.com> MIME-Version: 1.0 The current method to include 32 bit C boot code is: - compile each function we want to use into a separate object file; - each function is compiled with -fpic option; - convert these object files to binary files. This operation removes GOP which we don't want in the executable; - a small assembly part in each file add the entry point; - code can't have external references, all possible variables are passed by value or pointer; - include these binary files in head.S. There are currently some limitations: - code is compiled separately, it's not possible to share a function (like memcpy) between different functions to use; - although code is compiled with -fpic there's no certainty there are no relocations, specifically data ones. This can lead into hard to find bugs; - it's hard to add a simple function; - having to pass external variables makes hard to do multiple things otherwise functions would require a lot of parameters so code would have to be split into multiple functions which is not easy; - we generate a single text section containing data and code, not a problem at the moment but if we want to add W^X protection it's not helpful. Current change extends the current process: - all object files are linked together before getting converted making possible to share code between the function we want to call; - a single object file is generated with all functions to use and exported symbols to easily call; - variables to use are declared in linker script and easily used inside C code. Declaring them manually could be annoying but makes also easier to check them. Using external pointers can be still an issue if they are not fixed. If an external symbol is not declared this gives a link error; - linker script put data (bss and data) into a separate section and check that that section is empty making sure code is W^X compatible; Some details of the implementation: - C code is compiled with -fpic flags (as before); - object files from C code are linked together; - the single bundled object file is linked with 2 slightly different script files to generate 2 bundled object files; - the 2 bundled object files are converted to binary removing the need for global offset tables; - a Python script is used to generate assembly source from the 2 binaries; - the single assembly file is compiled to generate final bundled object file; - to detect possible unwanted relocation in data/code code is generated with different addresses. This is enforced starting .text section at different positions and adding a fixed "gap" at the beginning. This makes sure code and data is position independent; - to detect used symbols in data/code symbols are placed in .text section at different offsets (based on the line in the linker script). This is needed as potentially a reference to a symbol is converted to a reference to the containing section so multiple symbols could be converted to reference to same symbol (section name) and we need to distinguish them; - to avoid relocations - --orphan-handling=error option to linker is used to make sure we account for all possible sections from C code; Current limitations: - the main one is the lack of support for 64 bit code. It would make sure that even the code used for 64 bit (at the moment EFI code) is code and data position independent. We cannot assume that code that came from code compiled for 32 bit and compiled for 64 bit is code and data position independent, different compiler options lead to different code/data. Signed-off-by: Frediano Ziglio --- .gitignore | 3 +- xen/arch/x86/boot/Makefile | 28 ++- .../x86/boot/{build32.lds => build32.lds.S} | 46 ++++- xen/arch/x86/boot/cmdline.c | 7 - xen/arch/x86/boot/head.S | 12 -- xen/arch/x86/boot/reloc.c | 7 - xen/tools/make_output | 177 ++++++++++++++++++ 7 files changed, 242 insertions(+), 38 deletions(-) rename xen/arch/x86/boot/{build32.lds => build32.lds.S} (62%) create mode 100755 xen/tools/make_output diff --git a/.gitignore b/.gitignore index d8b57e32f8..442f3272de 100644 --- a/.gitignore +++ b/.gitignore @@ -251,8 +251,7 @@ xen/System.map xen/arch/x86/boot/mkelf32 xen/arch/x86/boot/cmdline.S xen/arch/x86/boot/reloc.S -xen/arch/x86/boot/*.bin -xen/arch/x86/boot/*.lnk +xen/arch/x86/boot/build32.*.lds xen/arch/x86/efi.lds xen/arch/x86/efi/check.efi xen/arch/x86/efi/mkreloc diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index 8f5bbff0cc..ed8d55866d 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -1,4 +1,4 @@ -obj-bin-y += head.o +obj-bin-y += head.o cbundle.o head-bin-objs := cmdline.o reloc.o @@ -9,7 +9,6 @@ targets += $(head-bin-objs) head-bin-objs := $(addprefix $(obj)/,$(head-bin-objs)) $(obj)/head.o: AFLAGS-y += -Wa$(comma)-I$(obj) -$(obj)/head.o: $(head-bin-objs:.o=.bin) CFLAGS_x86_32 := $(subst -m64,-m32 -march=i686,$(XEN_TREEWIDE_CFLAGS)) $(call cc-options-add,CFLAGS_x86_32,CC,$(EMBEDDED_EXTRA_CFLAGS)) @@ -24,10 +23,31 @@ $(head-bin-objs): XEN_CFLAGS := $(CFLAGS_x86_32) -fpic LDFLAGS_DIRECT-$(call ld-option,--warn-rwx-segments) := --no-warn-rwx-segments LDFLAGS_DIRECT += $(LDFLAGS_DIRECT-y) +$(obj)/build32.final.lds: AFLAGS-y += -DFINAL +$(obj)/build32.other.lds $(obj)/build32.final.lds: $(src)/build32.lds.S + $(call if_changed_dep,cpp_lds_S) + %.bin: %.lnk $(OBJCOPY) -j .text -O binary $< $@ -%.lnk: %.o $(src)/build32.lds - $(LD) $(subst x86_64,i386,$(LDFLAGS_DIRECT)) -N -T $(filter %.lds,$^) -o $@ $< +$(obj)/cbundle.o: $(head-bin-objs) $(obj)/build32.other.lds $(obj)/build32.final.lds +## link all object files together + $(LD) $(subst x86_64,i386,$(LDFLAGS_DIRECT)) -r -o $(obj)/cbundle.tmp.o $(head-bin-objs) +## link twice with 2 different layouts + $(LD) $(subst x86_64,i386,$(LDFLAGS_DIRECT)) --orphan-handling=error -N -T $(obj)/build32.other.lds -o $@.1.o $(obj)/cbundle.tmp.o + $(LD) $(subst x86_64,i386,$(LDFLAGS_DIRECT)) --orphan-handling=error -N -T $(obj)/build32.final.lds -Map $(obj)/cbundle.map -o $@.2.o $(obj)/cbundle.tmp.o +## extract binaries from them + $(OBJCOPY) -j .text -O binary $@.1.o $@.1.bin + $(OBJCOPY) -j .text -O binary $@.2.o $@.2.bin +## generate final assembly file combining and checking above binaries + $(PYTHON) $(srctree)/tools/make_output \ + --script $(obj)/build32.final.lds \ + --bin1 $@.1.bin --bin2 $@.2.bin \ + --map $(obj)/cbundle.map --exports cmdline_parse_early,reloc \ + --section-header '.section .init.text, "ax", @progbits' \ + --output $(obj)/cbundle.s + $(CC) -c $(obj)/cbundle.s -o $@.tmp + rm -f $(obj)/cbundle.tmp.o $@.1.o $@.2.o $@.1.bin $@.2.bin $(obj)/cbundle.map $(obj)/cbundle.s $@ + mv $@.tmp $@ clean-files := *.lnk *.bin diff --git a/xen/arch/x86/boot/build32.lds b/xen/arch/x86/boot/build32.lds.S similarity index 62% rename from xen/arch/x86/boot/build32.lds rename to xen/arch/x86/boot/build32.lds.S index 56edaa727b..87d2a589b5 100644 --- a/xen/arch/x86/boot/build32.lds +++ b/xen/arch/x86/boot/build32.lds.S @@ -15,22 +15,54 @@ * with this program. If not, see . */ -ENTRY(_start) +#undef ENTRY + +#ifdef FINAL +# define GAP 0 +# define MULT 0 +# define TEXT_START +#else +# define GAP 0x010200 +# define MULT 1 +# define TEXT_START 0x408020 +#endif +# define DECLARE_IMPORT(name) name = . + (__LINE__ * MULT) + +ENTRY(dummy_start) SECTIONS { - /* Merge code and data into one section. */ - .text : { + /* Merge code and read-only data into one section. */ + .text TEXT_START : { + /* Silence linker warning, we are not going to use it */ + dummy_start = .; + + /* Declare below any symbol name needed. + * Each symbol should be on its own line. + * It looks like a tedious work but we make sure the things we use. + * Potentially they should be all variables. */ + DECLARE_IMPORT(__base_relocs_start); + DECLARE_IMPORT(__base_relocs_end); + . = . + GAP; *(.text) *(.text.*) - *(.data) - *(.data.*) *(.rodata) *(.rodata.*) + } + + /* Writeable data sections. Check empty. + * We collapse all into code section and we don't want it to be writeable. */ + .data : { + *(.data) + *(.data.*) *(.bss) *(.bss.*) } - + /DISCARD/ : { + *(.comment) + *(.comment.*) + *(.note.*) + } /* Dynamic linkage sections. Collected simply so we can check they're empty. */ .got : { *(.got) @@ -49,6 +81,7 @@ SECTIONS } .rel : { *(.rel.*) + *(.data.rel.*) } } @@ -64,3 +97,4 @@ ASSERT(SIZEOF(.igot.plt) == 0, ".igot.plt non-empty") ASSERT(SIZEOF(.iplt) == 0, ".iplt non-empty") ASSERT(SIZEOF(.plt) == 0, ".plt non-empty") ASSERT(SIZEOF(.rel) == 0, "leftover relocations") +ASSERT(SIZEOF(.data) == 0, "we don't want data") diff --git a/xen/arch/x86/boot/cmdline.c b/xen/arch/x86/boot/cmdline.c index fc9241ede9..48062b21a0 100644 --- a/xen/arch/x86/boot/cmdline.c +++ b/xen/arch/x86/boot/cmdline.c @@ -23,13 +23,6 @@ * - %eax = &cmdline, * - %edx = &early_boot_opts. */ -asm ( - " .text \n" - " .globl _start \n" - "_start: \n" - " jmp cmdline_parse_early \n" - ); - #include #include #include diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 12bbb97f33..791a1fee80 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -870,18 +870,6 @@ trampoline_setup: /* Jump into the relocated trampoline. */ lret - /* - * cmdline and reloc are written in C, and linked to be 32bit PIC with - * entrypoints at 0 and using the fastcall convention. - */ - ALIGN -cmdline_parse_early: - .incbin "cmdline.bin" - - ALIGN -reloc: - .incbin "reloc.bin" - ENTRY(trampoline_start) #include "trampoline.S" ENTRY(trampoline_end) diff --git a/xen/arch/x86/boot/reloc.c b/xen/arch/x86/boot/reloc.c index de8487483a..6652f9bde9 100644 --- a/xen/arch/x86/boot/reloc.c +++ b/xen/arch/x86/boot/reloc.c @@ -19,13 +19,6 @@ * - %ecx = TOPMOST_LOW_MEMORY_STACK_ADDRESS. * - 0x04(%esp) = BOOT_VIDEO_INFO_ADDRESS. */ -asm ( - " .text \n" - " .globl _start \n" - "_start: \n" - " jmp reloc \n" - ); - #include #include #include diff --git a/xen/tools/make_output b/xen/tools/make_output new file mode 100755 index 0000000000..0644a4bf12 --- /dev/null +++ b/xen/tools/make_output @@ -0,0 +1,177 @@ +#!/usr/bin/env python3 + +import argparse +import re +import struct +import sys + +parser = argparse.ArgumentParser(description='Generate assembly file to merge into other code.') +parser.add_argument('--script', dest='script', + required=True, + help='Linker script for extracting symbols') +parser.add_argument('--bin1', dest='bin1', + required=True, + help='First binary') +parser.add_argument('--bin2', dest='bin2', + required=True, + help='Second binary') +parser.add_argument('--output', dest='output', + help='Output file') +parser.add_argument('--map', dest='mapfile', + help='Map file to read for symbols to export') +parser.add_argument('--exports', dest='exports', + help='Symbols to export') +parser.add_argument('--section-header', dest='section_header', + default='.text', + help='Section header declaration') +args = parser.parse_args() + +gap = 0x010200 +text_diff = 0x408020 + +# Parse linker script for external symbols to use. +symbol_re = re.compile(r'\s+(\S+)\s*=\s*\.\s*\+\s*\((\d+)\s*\*\s*0\s*\)\s*;') +symbols = {} +lines = {} +for line in open(args.script): + m = symbol_re.match(line) + if not m: + continue + l = int(m.group(2)) + if l == 0: + raise Exception(f"Invalid line number found:\n\t{line}") + if l in symbols: + raise Exception(f"Symbol with this line already present:\n\t{line}") + symbols[l] = m.group(1) + lines[m.group(1)] = l + +exports = [] +if args.exports is not None: + exports = dict([(name, None) for name in args.exports.split(',')]) + +# Parse mapfile, look for ther symbols we want to export. +if args.mapfile is not None: + symbol_re = re.compile(r'\s{15,}0x([0-9a-f]+)\s+(\S+)\n') + for line in open(args.mapfile): + m = symbol_re.match(line) + if not m or m.group(2) not in exports: + continue + addr = int(m.group(1), 16) + exports[m.group(2)] = addr +for (name, addr) in exports.items(): + if addr is None: + raise Exception(f"Required export symbols {name} not found") + +file1 = open(args.bin1, 'rb') +file2 = open(args.bin2, 'rb') +size1 = file1.seek(0, 2) +size2 = file2.seek(0, 2) +if size1 > size2: + file1, file2 = file2, file1 + size1, size2 = size2, size1 +if size2 != size1 + gap: + raise Exception('File sizes do not match') + +file1.seek(0, 0) +data1 = file1.read(size1) +file2.seek(gap, 0) +data2 = file2.read(size1) + +max_line = max(symbols.keys()) + +i = 0 +references = {} +internals = 0 +while i <= size1 - 4: + n1 = struct.unpack('= 10: + break + continue + # This is a relative relocation to a symbol, accepted, code/data is + # relocatable. + if diff < gap and diff >= gap - max_line: + n = gap - diff + symbol = symbols.get(n) + # check we have a symbol + if symbol is None: + raise Exception(f"Cannot find symbol for line {n}") + pos = i - 1 + print(f'Position {pos:#x} {n} {symbol}', file=sys.stderr) + i += 3 + references[pos] = symbol + continue + # First byte is the same, move to next byte + if diff & 0xff == 0 and i <= size1 - 4: + continue + # Probably a type of relocation we don't want or support + pos = i - 1 + suggestion = '' + symbol = symbols.get(-diff - text_diff) + if symbol is not None: + suggestion = f" Maybe {symbol} is not defined as hidden?" + raise Exception(f"Unexpected difference found at {i:#x} " + f"n1={n1:#x} n2={n2:#x} diff={diff:#x}.{suggestion}") +if internals != 0: + raise Exception("Previous relocations found") + +def line_bytes(buf, out): + '''Output an assembly line with all bytes in "buf"''' + print("\t.byte " + ','.join([str(n) for n in buf]), file=out) + +def part(start, end, out): + '''Output bytes of "data" from "start" to "end"''' + while start < end: + e = min(start + 16, end) + line_bytes(data1[start:e], out) + start = e + +def reference(pos, out): + name = references[pos] + n = struct.unpack('= (1 << 31): + n -= (1 << 32) + n += pos + if n < 0: + n = -n + sign = '-' + print(f"\t.hidden {name}\n\t.long {name} {sign} {n:#x} - .", file=out) + +def output(out): + prev = 0 + exports_by_addr = {} + for (sym, addr) in exports.items(): + exports_by_addr.setdefault(addr, []).append(sym) + positions = list(references.keys()) + positions += list(exports_by_addr.keys()) + for pos in sorted(positions): + part(prev, pos, out) + prev = pos + if pos in references: + reference(pos, out) + prev = pos + 4 + if pos in exports_by_addr: + for sym in exports_by_addr[pos]: + print(f"\t.global {sym}\n\t.hidden {sym}\n{sym}:", file=out) + part(prev, size1, out) + +out = sys.stdout +if args.output is not None: + out = open(args.output, 'w') +print(f'\t{args.section_header}', file=out) +output(out) +print('\n\t.section\t.note.GNU-stack,"",@progbits', file=out) +out.flush() From patchwork Wed Sep 4 14:56:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frediano Ziglio X-Patchwork-Id: 13791072 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4B623CD4F21 for ; Wed, 4 Sep 2024 14:57:25 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.790439.1200200 (Exim 4.92) (envelope-from ) id 1slrRS-0001Qo-Jq; Wed, 04 Sep 2024 14:57:06 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 790439.1200200; Wed, 04 Sep 2024 14:57:06 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRS-0001Oa-E3; Wed, 04 Sep 2024 14:57:06 +0000 Received: by outflank-mailman (input) for mailman id 790439; Wed, 04 Sep 2024 14:57:05 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRR-0001Be-GL for xen-devel@lists.xenproject.org; Wed, 04 Sep 2024 14:57:05 +0000 Received: from mail-lj1-x22e.google.com (mail-lj1-x22e.google.com [2a00:1450:4864:20::22e]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f27429ad-6acd-11ef-a0b3-8be0dac302b0; Wed, 04 Sep 2024 16:57:04 +0200 (CEST) Received: by mail-lj1-x22e.google.com with SMTP id 38308e7fff4ca-2f3f0bdbcd9so11667211fa.1 for ; Wed, 04 Sep 2024 07:57:04 -0700 (PDT) Received: from fziglio-xenia-fedora.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5c3cc56c501sm18862a12.52.2024.09.04.07.57.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 07:57:02 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: f27429ad-6acd-11ef-a0b3-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1725461823; x=1726066623; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=aixdLmcSOvSmo9UZ0i0ndwW8Hy8syPJyL13PWBC58Eg=; b=RF6usNQQkbxwvb6ngz5sgV0W/85wGGtgGBuXgpCI8zfIL5a4CV2y0QbvQNQ/stwsMD mohkViH8HykxmPzNx8Lqmqfso5kFJ49cmaaFqKtNzpt+WWF0UWOAFyUHPwwAv7DdtjqF qAUxJPHihjfdWnxicG5BrpLbhGYaBk8CnZ6/s= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725461823; x=1726066623; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aixdLmcSOvSmo9UZ0i0ndwW8Hy8syPJyL13PWBC58Eg=; b=Ufx+JsoBNY1ELBA/AwAkEoHpc9gCsSYfY21cW90zz9TcBp2+H2WbBf+B0EaxY2qvLy nMA13XsCIgG1nZRYz0WArdtcEShUzaTox2FYTT+Ll0C1FjnZ8Tk17izs+R9DPR2UtfX3 wwjTVEQHfXZapZiN1AP2xTZ3prRd83mON30mCX2PEzqW2o1+OyZZv8mPGbcb/gjfIIBf PEs7upTkRQHf7/2o43/Bz/CenVPpixm7d7ZSK3MlMxzgnt1TakGrcqR8fZZm1z4Wc7Ru Qm1eLB2hg/8hA2eoGm+nSqBb562sJNSq5MnGJJ7aZNt1VVYl9/TR7fA+QnDQGZL83n0V gvqQ== X-Gm-Message-State: AOJu0YwHt9bOLwyEJE+iw89z73NNNSywQH2U7HdisX9edARdfnx0xvMw lM3YzzETZIeXNvETqYmltIBvorGvhGrfT+lSxqg7Xw+oJtrqQgzoP6Oyv2EQX3Ebb2YYerkTF2/ W X-Google-Smtp-Source: AGHT+IHXHNW9AqsbZTsyY2+70qJQwGzsG+S49/O6eTtN3lb3Ja72QQLn8iCRoVFCorUIZP9TuJH1qQ== X-Received: by 2002:a2e:be13:0:b0:2f4:f255:4fc1 with SMTP id 38308e7fff4ca-2f651d6044bmr22475931fa.11.1725461823224; Wed, 04 Sep 2024 07:57:03 -0700 (PDT) From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , "Daniel P. Smith" , =?utf-8?q?Marek_Marczykow?= =?utf-8?q?ski-G=C3=B3recki?= Subject: [RFC 3/5] Reuse code to relocate trampoline Date: Wed, 4 Sep 2024 15:56:46 +0100 Message-ID: <20240904145648.33707-4-frediano.ziglio@cloud.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240904145648.33707-1-frediano.ziglio@cloud.com> References: <20240904145648.33707-1-frediano.ziglio@cloud.com> MIME-Version: 1.0 --- xen/arch/x86/boot/Makefile | 6 +++--- xen/arch/x86/boot/build32.lds.S | 4 ++++ xen/arch/x86/boot/head.S | 24 ++-------------------- xen/arch/x86/boot/reloc-trampoline.c | 28 ++++++++++++++++++++++++++ xen/arch/x86/boot/reloc-trampoline64.c | 1 + xen/arch/x86/efi/efi-boot.h | 15 ++------------ 6 files changed, 40 insertions(+), 38 deletions(-) create mode 100644 xen/arch/x86/boot/reloc-trampoline.c create mode 120000 xen/arch/x86/boot/reloc-trampoline64.c diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index ed8d55866d..42fd1721de 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -1,6 +1,6 @@ -obj-bin-y += head.o cbundle.o +obj-bin-y += head.o cbundle.o reloc-trampoline64.o -head-bin-objs := cmdline.o reloc.o +head-bin-objs := cmdline.o reloc.o reloc-trampoline.o nocov-y += $(head-bin-objs) noubsan-y += $(head-bin-objs) @@ -43,7 +43,7 @@ $(obj)/cbundle.o: $(head-bin-objs) $(obj)/build32.other.lds $(obj)/build32.final $(PYTHON) $(srctree)/tools/make_output \ --script $(obj)/build32.final.lds \ --bin1 $@.1.bin --bin2 $@.2.bin \ - --map $(obj)/cbundle.map --exports cmdline_parse_early,reloc \ + --map $(obj)/cbundle.map --exports cmdline_parse_early,reloc,reloc_trampoline32 \ --section-header '.section .init.text, "ax", @progbits' \ --output $(obj)/cbundle.s $(CC) -c $(obj)/cbundle.s -o $@.tmp diff --git a/xen/arch/x86/boot/build32.lds.S b/xen/arch/x86/boot/build32.lds.S index 87d2a589b5..0b7341edeb 100644 --- a/xen/arch/x86/boot/build32.lds.S +++ b/xen/arch/x86/boot/build32.lds.S @@ -43,6 +43,10 @@ SECTIONS * Potentially they should be all variables. */ DECLARE_IMPORT(__base_relocs_start); DECLARE_IMPORT(__base_relocs_end); + DECLARE_IMPORT(__trampoline_rel_start); + DECLARE_IMPORT(__trampoline_rel_stop); + DECLARE_IMPORT(__trampoline_seg_start); + DECLARE_IMPORT(__trampoline_seg_stop); . = . + GAP; *(.text) *(.text.*) diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 791a1fee80..8e35f2a791 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -817,28 +817,8 @@ trampoline_setup: mov %edx, sym_offs(l1_bootmap)(%esi, %ecx, 8) /* Apply relocations to bootstrap trampoline. */ - mov sym_esi(trampoline_phys), %edx - lea sym_esi(__trampoline_rel_start), %edi - lea sym_esi(__trampoline_rel_stop), %ecx -1: - mov (%edi), %eax - add %edx, (%edi, %eax) - add $4,%edi - - cmp %ecx, %edi - jb 1b - - /* Patch in the trampoline segment. */ - shr $4,%edx - lea sym_esi(__trampoline_seg_start), %edi - lea sym_esi(__trampoline_seg_stop), %ecx -1: - mov (%edi), %eax - mov %dx, (%edi, %eax) - add $4,%edi - - cmp %ecx, %edi - jb 1b + mov sym_esi(trampoline_phys), %eax + call reloc_trampoline32 /* Do not parse command line on EFI platform here. */ cmpb $0, sym_esi(efi_platform) diff --git a/xen/arch/x86/boot/reloc-trampoline.c b/xen/arch/x86/boot/reloc-trampoline.c new file mode 100644 index 0000000000..2a48890483 --- /dev/null +++ b/xen/arch/x86/boot/reloc-trampoline.c @@ -0,0 +1,28 @@ + +#include + +#pragma GCC visibility push(hidden) +extern const int32_t __trampoline_rel_start[], __trampoline_rel_stop[]; +extern const int32_t __trampoline_seg_start[], __trampoline_seg_stop[]; +#pragma GCC visibility pop + +#if defined(__i386__) +void reloc_trampoline32(unsigned long phys) +#elif defined (__x86_64__) +void reloc_trampoline64(unsigned long phys) +#else +#error Unknow architecture +#endif +{ + const int32_t *trampoline_ptr; + + /* Apply relocations to trampoline. */ + for ( trampoline_ptr = __trampoline_rel_start; + trampoline_ptr < __trampoline_rel_stop; + ++trampoline_ptr ) + *(uint32_t *)(*trampoline_ptr + (long)trampoline_ptr) += phys; + for ( trampoline_ptr = __trampoline_seg_start; + trampoline_ptr < __trampoline_seg_stop; + ++trampoline_ptr ) + *(uint16_t *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4; +} diff --git a/xen/arch/x86/boot/reloc-trampoline64.c b/xen/arch/x86/boot/reloc-trampoline64.c new file mode 120000 index 0000000000..20d6dfae1a --- /dev/null +++ b/xen/arch/x86/boot/reloc-trampoline64.c @@ -0,0 +1 @@ +reloc-trampoline.c \ No newline at end of file diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index f282358435..87a7f8abcf 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -101,27 +101,16 @@ static void __init efi_arch_relocate_image(unsigned long delta) } } -extern const s32 __trampoline_rel_start[], __trampoline_rel_stop[]; -extern const s32 __trampoline_seg_start[], __trampoline_seg_stop[]; +void reloc_trampoline64(unsigned long phys); static void __init relocate_trampoline(unsigned long phys) { - const s32 *trampoline_ptr; - trampoline_phys = phys; if ( !efi_enabled(EFI_LOADER) ) return; - /* Apply relocations to trampoline. */ - for ( trampoline_ptr = __trampoline_rel_start; - trampoline_ptr < __trampoline_rel_stop; - ++trampoline_ptr ) - *(u32 *)(*trampoline_ptr + (long)trampoline_ptr) += phys; - for ( trampoline_ptr = __trampoline_seg_start; - trampoline_ptr < __trampoline_seg_stop; - ++trampoline_ptr ) - *(u16 *)(*trampoline_ptr + (long)trampoline_ptr) = phys >> 4; + reloc_trampoline64(phys); } static void __init place_string(u32 *addr, const char *s) From patchwork Wed Sep 4 14:56:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frediano Ziglio X-Patchwork-Id: 13791071 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 722A4CD4853 for ; Wed, 4 Sep 2024 14:57:24 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.790441.1200229 (Exim 4.92) (envelope-from ) id 1slrRU-0002Ad-EF; Wed, 04 Sep 2024 14:57:08 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 790441.1200229; Wed, 04 Sep 2024 14:57:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRU-00029d-6l; Wed, 04 Sep 2024 14:57:08 +0000 Received: by outflank-mailman (input) for mailman id 790441; Wed, 04 Sep 2024 14:57:06 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRS-0001Bm-IQ for xen-devel@lists.xenproject.org; Wed, 04 Sep 2024 14:57:06 +0000 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [2a00:1450:4864:20::229]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id f2e2bd8d-6acd-11ef-99a1-01e77a169b0f; Wed, 04 Sep 2024 16:57:04 +0200 (CEST) Received: by mail-lj1-x229.google.com with SMTP id 38308e7fff4ca-2f3f90295a9so11247011fa.0 for ; Wed, 04 Sep 2024 07:57:04 -0700 (PDT) Received: from fziglio-xenia-fedora.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5c3cc56c501sm18862a12.52.2024.09.04.07.57.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 07:57:03 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: f2e2bd8d-6acd-11ef-99a1-01e77a169b0f DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1725461824; x=1726066624; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cNu6Puv0e8keSxUHB/R0XRglCAGHnvUUM3m8vz4KfqY=; b=ME2VYo9VRnmQDG84sXhlVn8lGLMJaXDHck9lEaJMztISuRankIqVIbp/IMMvvfc04z lH1+nME6CJn7NjksPXvyNedff68qhAfwdCcI4Uj+CeRnNAxHEz0E4kcYUwg4R1uMGdzv KDzJ4CwrO99lWF27W4ZyA8P+nMd2qOKpqPIHE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725461824; x=1726066624; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cNu6Puv0e8keSxUHB/R0XRglCAGHnvUUM3m8vz4KfqY=; b=eu+9P82zqanbFX6ZPBEL15ULmlxK1D5oPdbr06uDmt5n6WMWZM3BwzL2iRFjzrfb0p bEThDt0mKog7Ncd+8j/S+U/er4Xf8JY58c0UQ9eJ2wiwHYRwIdCBIIgvFKx12sK/Ata3 u1tSRZFEuRg3ZV4j79dIc6bFfu0qvTbbTTk2fG5ue28QCiMKiALNDsG59GM6PehqeCdj /IIPRnFNSp7QpgCnQP4ZsR3kt4IL45T0U1WkcL4lF3AsAdOwZtCoRvJFXhgSZrvuHZqY Nvgj2BM5h4OCgiKcRAh52uDHD8ITjgvSNWGxiwrkW1nprMSuJZIXsEg7J6YbFckJ97gn ZLMQ== X-Gm-Message-State: AOJu0YzpNC0HEDKP9Z9wnEHEm4sKGeWfLjNKD8W1BJsQVZzu7dco/7iw vCvqTCJyGLOZq69kgq7FWbdZFp73LK2eTVSJ1BkyvkckbKf7gyNLA7YMWdEt22mYOWW+OF2ITZH Q X-Google-Smtp-Source: AGHT+IH2iajKc/hwuONm00Xthdi39I7xcd2vmSPFrzl9jPAPQquPu7z8zcJP7eybp3yRtJlFAwefgQ== X-Received: by 2002:a2e:bc1a:0:b0:2f2:9a2e:c257 with SMTP id 38308e7fff4ca-2f651e5d42amr22342481fa.41.1725461823929; Wed, 04 Sep 2024 07:57:03 -0700 (PDT) From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , "Daniel P. Smith" , =?utf-8?q?Marek_Marczykow?= =?utf-8?q?ski-G=C3=B3recki?= Subject: [RFC 4/5] Remove duplication preparing pages Date: Wed, 4 Sep 2024 15:56:47 +0100 Message-ID: <20240904145648.33707-5-frediano.ziglio@cloud.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240904145648.33707-1-frediano.ziglio@cloud.com> References: <20240904145648.33707-1-frediano.ziglio@cloud.com> MIME-Version: 1.0 Pretty hacky, headers are not that compatible 32/64 bits --- xen/arch/x86/boot/Makefile | 6 +- xen/arch/x86/boot/build32.lds.S | 8 +++ xen/arch/x86/boot/head.S | 43 +----------- xen/arch/x86/boot/setup-pages.c | 105 ++++++++++++++++++++++++++++++ xen/arch/x86/boot/setup-pages64.c | 1 + xen/arch/x86/efi/efi-boot.h | 52 +-------------- 6 files changed, 121 insertions(+), 94 deletions(-) create mode 100644 xen/arch/x86/boot/setup-pages.c create mode 120000 xen/arch/x86/boot/setup-pages64.c diff --git a/xen/arch/x86/boot/Makefile b/xen/arch/x86/boot/Makefile index 42fd1721de..23e40769eb 100644 --- a/xen/arch/x86/boot/Makefile +++ b/xen/arch/x86/boot/Makefile @@ -1,6 +1,6 @@ -obj-bin-y += head.o cbundle.o reloc-trampoline64.o +obj-bin-y += head.o cbundle.o reloc-trampoline64.o setup-pages64.o -head-bin-objs := cmdline.o reloc.o reloc-trampoline.o +head-bin-objs := cmdline.o reloc.o reloc-trampoline.o setup-pages.o nocov-y += $(head-bin-objs) noubsan-y += $(head-bin-objs) @@ -43,7 +43,7 @@ $(obj)/cbundle.o: $(head-bin-objs) $(obj)/build32.other.lds $(obj)/build32.final $(PYTHON) $(srctree)/tools/make_output \ --script $(obj)/build32.final.lds \ --bin1 $@.1.bin --bin2 $@.2.bin \ - --map $(obj)/cbundle.map --exports cmdline_parse_early,reloc,reloc_trampoline32 \ + --map $(obj)/cbundle.map --exports cmdline_parse_early,reloc,reloc_trampoline32,setup_pages32 \ --section-header '.section .init.text, "ax", @progbits' \ --output $(obj)/cbundle.s $(CC) -c $(obj)/cbundle.s -o $@.tmp diff --git a/xen/arch/x86/boot/build32.lds.S b/xen/arch/x86/boot/build32.lds.S index 0b7341edeb..3796f9603b 100644 --- a/xen/arch/x86/boot/build32.lds.S +++ b/xen/arch/x86/boot/build32.lds.S @@ -47,6 +47,14 @@ SECTIONS DECLARE_IMPORT(__trampoline_rel_stop); DECLARE_IMPORT(__trampoline_seg_start); DECLARE_IMPORT(__trampoline_seg_stop); + DECLARE_IMPORT(l2_xenmap); + DECLARE_IMPORT(l2_directmap); + DECLARE_IMPORT(l2_bootmap); + DECLARE_IMPORT(l3_bootmap); + DECLARE_IMPORT(_start); + DECLARE_IMPORT(_end); + DECLARE_IMPORT(xen_phys_start); + //DECLARE_IMPORT(); . = . + GAP; *(.text) *(.text.*) diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 8e35f2a791..5ae0c2009e 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -763,48 +763,7 @@ trampoline_setup: test $(1 << L2_PAGETABLE_SHIFT) - 1, %eax jnz .Lnot_aligned - /* Map Xen into the higher mappings using 2M superpages. */ - lea _PAGE_PSE + PAGE_HYPERVISOR_RWX + sym_esi(_start), %eax - mov $sym_offs(_start), %ecx /* %eax = PTE to write ^ */ - mov $sym_offs(_end - 1), %edx - shr $L2_PAGETABLE_SHIFT, %ecx /* %ecx = First slot to write */ - shr $L2_PAGETABLE_SHIFT, %edx /* %edx = Final slot to write */ - -1: mov %eax, sym_offs(l2_xenmap)(%esi, %ecx, 8) - add $1, %ecx - add $1 << L2_PAGETABLE_SHIFT, %eax - - cmp %edx, %ecx - jbe 1b - - /* - * Map Xen into the directmap (needed for early-boot pagetable - * handling/walking), and identity map Xen into bootmap (needed for - * the transition into long mode), using 2M superpages. - */ - lea sym_esi(_start), %ecx - lea -1 + sym_esi(_end), %edx - lea _PAGE_PSE + PAGE_HYPERVISOR_RWX(%ecx), %eax /* PTE to write. */ - shr $L2_PAGETABLE_SHIFT, %ecx /* First slot to write. */ - shr $L2_PAGETABLE_SHIFT, %edx /* Final slot to write. */ - -1: mov %eax, sym_offs(l2_bootmap) (%esi, %ecx, 8) - mov %eax, sym_offs(l2_directmap)(%esi, %ecx, 8) - add $1, %ecx - add $1 << L2_PAGETABLE_SHIFT, %eax - - cmp %edx, %ecx - jbe 1b - - /* Map 4x l2_bootmap[] into l3_bootmap[0...3] */ - lea __PAGE_HYPERVISOR + sym_esi(l2_bootmap), %eax - mov %eax, 0 + sym_esi(l3_bootmap) - add $PAGE_SIZE, %eax - mov %eax, 8 + sym_esi(l3_bootmap) - add $PAGE_SIZE, %eax - mov %eax, 16 + sym_esi(l3_bootmap) - add $PAGE_SIZE, %eax - mov %eax, 24 + sym_esi(l3_bootmap) + call setup_pages32 /* Map l1_bootmap[] into l2_bootmap[0]. */ lea __PAGE_HYPERVISOR + sym_esi(l1_bootmap), %eax diff --git a/xen/arch/x86/boot/setup-pages.c b/xen/arch/x86/boot/setup-pages.c new file mode 100644 index 0000000000..0961282a01 --- /dev/null +++ b/xen/arch/x86/boot/setup-pages.c @@ -0,0 +1,105 @@ +#include +#include +#include +#ifndef __i386__ +#include +#endif + +#if defined(__i386__) + +#pragma GCC visibility push(hidden) +extern char _start[], _end[]; +extern uint64_t l2_xenmap[512], l3_bootmap[512], l2_directmap[512], l2_bootmap[512]; +extern unsigned long xen_phys_start; +#pragma GCC visibility pop + +#define _PAGE_PRESENT 0x001 +#define _PAGE_RW 0x002 +#define _PAGE_ACCESSED 0x020 +#define _PAGE_DIRTY 0x040 +#define _PAGE_PSE 0x080 +#define _PAGE_GLOBAL 0x100 + +#define PAGE_HYPERVISOR PAGE_HYPERVISOR_RW +#define PAGE_HYPERVISOR_RW (__PAGE_HYPERVISOR_RW | _PAGE_GLOBAL) +#define __PAGE_HYPERVISOR_RW (__PAGE_HYPERVISOR_RO | _PAGE_DIRTY | _PAGE_RW) +// TODO +#define _PAGE_NX 0 +#define __PAGE_HYPERVISOR_RO (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NX) +#define PAGE_HYPERVISOR_RWX (__PAGE_HYPERVISOR | _PAGE_GLOBAL) +#define __PAGE_HYPERVISOR (__PAGE_HYPERVISOR_RX | _PAGE_DIRTY | _PAGE_RW) +#define __PAGE_HYPERVISOR_RX (_PAGE_PRESENT | _PAGE_ACCESSED) + +#define L2_PAGETABLE_SHIFT 21 +#define L2_PAGETABLE_ENTRIES 512 +#define PAGE_SIZE 4096 +#define l2_table_offset(a) (((a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) +#define l2e_from_paddr(a,f) ((a) | put_pte_flags(f)) +#define l3e_from_paddr(a,f) ((a) | put_pte_flags(f)) +#define l2e_add_flags(x, flags) (x |= put_pte_flags(flags)) +typedef uint64_t l2_pgentry_t; +static inline int64_t put_pte_flags(unsigned int x) +{ + return (((int64_t)x & ~0xfff) << 40) | (x & 0xfff); +} + +void setup_pages32(void) +#elif defined (__x86_64__) +void setup_pages64(void) +#else +#error Unknow architecture +#endif +{ + unsigned int i; + + /* + * Map Xen into the higher mappings, using 2M superpages. + * + * NB: We are currently in physical mode, so a RIP-relative relocation + * against _start/_end result in our arbitrary placement by the bootloader + * in memory, rather than the intended high mappings position. Subtract + * xen_phys_start to get the appropriate slots in l2_xenmap[]. + */ + for ( i = l2_table_offset((unsigned long)_start - xen_phys_start); + i <= l2_table_offset((unsigned long)_end - 1 - xen_phys_start); ++i ) + l2_xenmap[i] = + l2e_from_paddr(xen_phys_start + (i << L2_PAGETABLE_SHIFT), + PAGE_HYPERVISOR_RWX | _PAGE_PSE); + + /* Check that there is at least 4G of mapping space in l2_*map[] */ +#ifndef __i386__ + BUILD_BUG_ON((sizeof(l2_bootmap) / L2_PAGETABLE_ENTRIES) < 4); + BUILD_BUG_ON((sizeof(l2_directmap) / L2_PAGETABLE_ENTRIES) < 4); +#endif + + /* Initialize L3 boot-map page directory entries. */ + for ( i = 0; i < 4; ++i ) + l3_bootmap[i] = l3e_from_paddr((unsigned long)l2_bootmap + i * PAGE_SIZE, + __PAGE_HYPERVISOR); + /* + * Map Xen into the directmap (needed for early-boot pagetable + * handling/walking), and identity map Xen into bootmap (needed for the + * transition from the EFI pagetables to Xen), using 2M superpages. + * + * NB: We are currently in physical mode, so a RIP-relative relocation + * against _start/_end gets their real position in memory, which are the + * appropriate l2 slots to map. + */ +#define l2_4G_offset(a) \ + (((a) >> L2_PAGETABLE_SHIFT) & (4 * L2_PAGETABLE_ENTRIES - 1)) + + for ( i = l2_4G_offset((unsigned long)_start); + i <= l2_4G_offset((unsigned long)_end - 1); ++i ) + { + l2_pgentry_t pte = l2e_from_paddr(i << L2_PAGETABLE_SHIFT, + __PAGE_HYPERVISOR | _PAGE_PSE); + + l2_bootmap[i] = pte; + + /* Bootmap RWX/Non-global. Directmap RW/Global. */ + l2e_add_flags(pte, PAGE_HYPERVISOR); + + l2_directmap[i] = pte; + } +#undef l2_4G_offset +} diff --git a/xen/arch/x86/boot/setup-pages64.c b/xen/arch/x86/boot/setup-pages64.c new file mode 120000 index 0000000000..9a5cf52290 --- /dev/null +++ b/xen/arch/x86/boot/setup-pages64.c @@ -0,0 +1 @@ +setup-pages.c \ No newline at end of file diff --git a/xen/arch/x86/efi/efi-boot.h b/xen/arch/x86/efi/efi-boot.h index 87a7f8abcf..4291af0b3d 100644 --- a/xen/arch/x86/efi/efi-boot.h +++ b/xen/arch/x86/efi/efi-boot.h @@ -615,9 +615,10 @@ static void __init efi_arch_edid(EFI_HANDLE gop_handle) #endif } +void setup_pages64(void); + static void __init efi_arch_memory_setup(void) { - unsigned int i; EFI_STATUS status; /* Allocate space for trampoline (in first Mb). */ @@ -641,54 +642,7 @@ static void __init efi_arch_memory_setup(void) if ( !efi_enabled(EFI_LOADER) ) return; - /* - * Map Xen into the higher mappings, using 2M superpages. - * - * NB: We are currently in physical mode, so a RIP-relative relocation - * against _start/_end result in our arbitrary placement by the bootloader - * in memory, rather than the intended high mappings position. Subtract - * xen_phys_start to get the appropriate slots in l2_xenmap[]. - */ - for ( i = l2_table_offset((UINTN)_start - xen_phys_start); - i <= l2_table_offset((UINTN)_end - 1 - xen_phys_start); ++i ) - l2_xenmap[i] = - l2e_from_paddr(xen_phys_start + (i << L2_PAGETABLE_SHIFT), - PAGE_HYPERVISOR_RWX | _PAGE_PSE); - - /* Check that there is at least 4G of mapping space in l2_*map[] */ - BUILD_BUG_ON((sizeof(l2_bootmap) / L2_PAGETABLE_ENTRIES) < 4); - BUILD_BUG_ON((sizeof(l2_directmap) / L2_PAGETABLE_ENTRIES) < 4); - - /* Initialize L3 boot-map page directory entries. */ - for ( i = 0; i < 4; ++i ) - l3_bootmap[i] = l3e_from_paddr((UINTN)l2_bootmap + i * PAGE_SIZE, - __PAGE_HYPERVISOR); - /* - * Map Xen into the directmap (needed for early-boot pagetable - * handling/walking), and identity map Xen into bootmap (needed for the - * transition from the EFI pagetables to Xen), using 2M superpages. - * - * NB: We are currently in physical mode, so a RIP-relative relocation - * against _start/_end gets their real position in memory, which are the - * appropriate l2 slots to map. - */ -#define l2_4G_offset(a) \ - (((a) >> L2_PAGETABLE_SHIFT) & (4 * L2_PAGETABLE_ENTRIES - 1)) - - for ( i = l2_4G_offset((UINTN)_start); - i <= l2_4G_offset((UINTN)_end - 1); ++i ) - { - l2_pgentry_t pte = l2e_from_paddr(i << L2_PAGETABLE_SHIFT, - __PAGE_HYPERVISOR | _PAGE_PSE); - - l2_bootmap[i] = pte; - - /* Bootmap RWX/Non-global. Directmap RW/Global. */ - l2e_add_flags(pte, PAGE_HYPERVISOR); - - l2_directmap[i] = pte; - } -#undef l2_4G_offset + setup_pages64(); } static void __init efi_arch_handle_module(const struct file *file, From patchwork Wed Sep 4 14:56:48 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frediano Ziglio X-Patchwork-Id: 13791074 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 528FBCD4F22 for ; Wed, 4 Sep 2024 14:57:25 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.790440.1200224 (Exim 4.92) (envelope-from ) id 1slrRU-000272-3m; Wed, 04 Sep 2024 14:57:08 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 790440.1200224; Wed, 04 Sep 2024 14:57:08 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRT-00026Q-Ux; Wed, 04 Sep 2024 14:57:07 +0000 Received: by outflank-mailman (input) for mailman id 790440; Wed, 04 Sep 2024 14:57:06 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1slrRS-0001Be-Gf for xen-devel@lists.xenproject.org; Wed, 04 Sep 2024 14:57:06 +0000 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [2a00:1450:4864:20::530]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f34c1b29-6acd-11ef-a0b3-8be0dac302b0; Wed, 04 Sep 2024 16:57:05 +0200 (CEST) Received: by mail-ed1-x530.google.com with SMTP id 4fb4d7f45d1cf-5c2561e8041so4116224a12.2 for ; Wed, 04 Sep 2024 07:57:05 -0700 (PDT) Received: from fziglio-xenia-fedora.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id 4fb4d7f45d1cf-5c3cc56c501sm18862a12.52.2024.09.04.07.57.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 04 Sep 2024 07:57:04 -0700 (PDT) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: f34c1b29-6acd-11ef-a0b3-8be0dac302b0 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cloud.com; s=cloud; t=1725461825; x=1726066625; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZcvMYN+jr5XUIeIsxJiT1pxAH2bfq4XVsUerM53EAdk=; b=L4e7st1QpUWX4pmJIfdMBnSCXb3EylFZ13rP0epa5667CvkWjsRmoCTrFSK5rW7TWM vCbweW1k7GRZrH2CefiVtiECp6KKFMUrwahc+w3AgCxI40TFQmgsWrnjk4NVnJQg/xv+ GBPuRr4CbaU0KhEgAVsy2KZKYFXXARnDBXO+8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725461825; x=1726066625; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZcvMYN+jr5XUIeIsxJiT1pxAH2bfq4XVsUerM53EAdk=; b=dS052MyKXb27l18F0ldSXn38H+MinUORQuhlJC7CRyDRoMK6AaZYVkQCTyCa1j1BhG Z7qpKE6RJm8YwenI8bKnhcXoocBDtuiEzcKk46BLG26u9PryjYuQXxRudoRWHbMssKnP 9Go9EFG6KUuCyK8IakFp4LnDrHF7zw/DmtkWi3l0jUrhEzgK9QpAbmRjD5TQ7XDcFX0E MHo3hChcWnIR2/EU8XLPDIDEjcxr8xkUHigDBq8sFxcZiPyuAdic6CDnV61X4JoJap93 VMXs9MJuu2sJQFUYG5HS9ufGSdK3GNQlekq6kTXQrT7hIgameaoxs+Z5Gb+61ljmsDGA /t6g== X-Gm-Message-State: AOJu0YxzFSPTpEk/q3/NZNmikqI7SB58L6+mnNvJl+vTVwtva6rnxBnm 7ezo8UdGpBC1zT/Twv97X+z4y76s4Xf6W/ArGb2HhOkmGrbuIquA9/kdYqt9D3WYAAQLMW/eUJq r X-Google-Smtp-Source: AGHT+IHTEBuxpy+UIZ/UjSONvgdj+wUsgOu58Nz4vjPcQQTv/Tufa8zRgvnXdsmUUxOdHP0H0GcFyw== X-Received: by 2002:a05:6402:3506:b0:5c2:6e5f:3bf9 with SMTP id 4fb4d7f45d1cf-5c26e5f3d09mr3653500a12.28.1725461824588; Wed, 04 Sep 2024 07:57:04 -0700 (PDT) From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [RFC 5/5] setup mapping for trampoline in setup_pagesXX Date: Wed, 4 Sep 2024 15:56:48 +0100 Message-ID: <20240904145648.33707-6-frediano.ziglio@cloud.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20240904145648.33707-1-frediano.ziglio@cloud.com> References: <20240904145648.33707-1-frediano.ziglio@cloud.com> MIME-Version: 1.0 Reduce assembly code, make boot page mappings more similar between multiple paths (direct EFI and not). --- xen/arch/x86/boot/build32.lds.S | 2 ++ xen/arch/x86/boot/head.S | 10 ---------- xen/arch/x86/boot/setup-pages.c | 25 ++++++++++++++++++------- xen/arch/x86/boot/x86_64.S | 2 +- xen/arch/x86/include/asm/page.h | 3 ++- 5 files changed, 23 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/boot/build32.lds.S b/xen/arch/x86/boot/build32.lds.S index 3796f9603b..aca747eb1d 100644 --- a/xen/arch/x86/boot/build32.lds.S +++ b/xen/arch/x86/boot/build32.lds.S @@ -49,11 +49,13 @@ SECTIONS DECLARE_IMPORT(__trampoline_seg_stop); DECLARE_IMPORT(l2_xenmap); DECLARE_IMPORT(l2_directmap); + DECLARE_IMPORT(l1_bootmap); DECLARE_IMPORT(l2_bootmap); DECLARE_IMPORT(l3_bootmap); DECLARE_IMPORT(_start); DECLARE_IMPORT(_end); DECLARE_IMPORT(xen_phys_start); + DECLARE_IMPORT(trampoline_phys); //DECLARE_IMPORT(); . = . + GAP; *(.text) diff --git a/xen/arch/x86/boot/head.S b/xen/arch/x86/boot/head.S index 5ae0c2009e..84d3c469de 100644 --- a/xen/arch/x86/boot/head.S +++ b/xen/arch/x86/boot/head.S @@ -765,16 +765,6 @@ trampoline_setup: call setup_pages32 - /* Map l1_bootmap[] into l2_bootmap[0]. */ - lea __PAGE_HYPERVISOR + sym_esi(l1_bootmap), %eax - mov %eax, sym_esi(l2_bootmap) - - /* Map the permanent trampoline page into l1_bootmap[]. */ - mov sym_esi(trampoline_phys), %ecx - lea __PAGE_HYPERVISOR_RX(%ecx), %edx /* %edx = PTE to write */ - shr $PAGE_SHIFT, %ecx /* %ecx = Slot to write */ - mov %edx, sym_offs(l1_bootmap)(%esi, %ecx, 8) - /* Apply relocations to bootstrap trampoline. */ mov sym_esi(trampoline_phys), %eax call reloc_trampoline32 diff --git a/xen/arch/x86/boot/setup-pages.c b/xen/arch/x86/boot/setup-pages.c index 0961282a01..f74734c036 100644 --- a/xen/arch/x86/boot/setup-pages.c +++ b/xen/arch/x86/boot/setup-pages.c @@ -9,8 +9,10 @@ #pragma GCC visibility push(hidden) extern char _start[], _end[]; -extern uint64_t l2_xenmap[512], l3_bootmap[512], l2_directmap[512], l2_bootmap[512]; +extern uint64_t l2_xenmap[512], l2_directmap[512], + l3_bootmap[512], l2_bootmap[512], l1_bootmap[512]; extern unsigned long xen_phys_start; +extern unsigned long trampoline_phys; #pragma GCC visibility pop #define _PAGE_PRESENT 0x001 @@ -19,12 +21,11 @@ extern unsigned long xen_phys_start; #define _PAGE_DIRTY 0x040 #define _PAGE_PSE 0x080 #define _PAGE_GLOBAL 0x100 +#define _PAGE_NX (1LLU << 63) #define PAGE_HYPERVISOR PAGE_HYPERVISOR_RW #define PAGE_HYPERVISOR_RW (__PAGE_HYPERVISOR_RW | _PAGE_GLOBAL) #define __PAGE_HYPERVISOR_RW (__PAGE_HYPERVISOR_RO | _PAGE_DIRTY | _PAGE_RW) -// TODO -#define _PAGE_NX 0 #define __PAGE_HYPERVISOR_RO (_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_NX) #define PAGE_HYPERVISOR_RWX (__PAGE_HYPERVISOR | _PAGE_GLOBAL) #define __PAGE_HYPERVISOR (__PAGE_HYPERVISOR_RX | _PAGE_DIRTY | _PAGE_RW) @@ -33,14 +34,16 @@ extern unsigned long xen_phys_start; #define L2_PAGETABLE_SHIFT 21 #define L2_PAGETABLE_ENTRIES 512 #define PAGE_SIZE 4096 +#define PAGE_SHIFT 12 #define l2_table_offset(a) (((a) >> L2_PAGETABLE_SHIFT) & (L2_PAGETABLE_ENTRIES - 1)) -#define l2e_from_paddr(a,f) ((a) | put_pte_flags(f)) -#define l3e_from_paddr(a,f) ((a) | put_pte_flags(f)) +#define l1e_from_paddr(a, flags) ((a) | put_pte_flags(flags)) +#define l2e_from_paddr(a, flags) ((a) | put_pte_flags(flags)) +#define l3e_from_paddr(a, flags) ((a) | put_pte_flags(flags)) #define l2e_add_flags(x, flags) (x |= put_pte_flags(flags)) typedef uint64_t l2_pgentry_t; -static inline int64_t put_pte_flags(unsigned int x) +static inline uint64_t put_pte_flags(uint64_t x) { - return (((int64_t)x & ~0xfff) << 40) | (x & 0xfff); + return x; } void __attribute__((__stdcall__)) setup_pages32(void) @@ -102,4 +105,12 @@ void setup_pages64(void) l2_directmap[i] = pte; } #undef l2_4G_offset + + /* Map l1_bootmap[] into l2_bootmap[0]. */ + l2_bootmap[0] = l2e_from_paddr((unsigned long)l1_bootmap, + __PAGE_HYPERVISOR); + + /* Map the permanent trampoline page into l1_bootmap[]. */ + l1_bootmap[(unsigned long)trampoline_phys >> PAGE_SHIFT] = + l1e_from_paddr((unsigned long)trampoline_phys, __PAGE_HYPERVISOR_RX); } diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 04bb62ae86..230ae6e2fb 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -195,7 +195,7 @@ GLOBAL(__page_tables_end) .section .init.data, "aw", @progbits .align PAGE_SIZE, 0 -l1_bootmap: +GLOBAL(l1_bootmap) .fill L1_PAGETABLE_ENTRIES, 8, 0 .size l1_bootmap, . - l1_bootmap diff --git a/xen/arch/x86/include/asm/page.h b/xen/arch/x86/include/asm/page.h index e01af28916..7e8c506dbc 100644 --- a/xen/arch/x86/include/asm/page.h +++ b/xen/arch/x86/include/asm/page.h @@ -286,7 +286,8 @@ extern l2_pgentry_t l2_xenmap[L2_PAGETABLE_ENTRIES], l2_bootmap[4*L2_PAGETABLE_ENTRIES]; extern l3_pgentry_t l3_bootmap[L3_PAGETABLE_ENTRIES]; extern l2_pgentry_t l2_directmap[4*L2_PAGETABLE_ENTRIES]; -extern l1_pgentry_t l1_fixmap[L1_PAGETABLE_ENTRIES]; +extern l1_pgentry_t l1_fixmap[L1_PAGETABLE_ENTRIES], + l1_bootmap[L1_PAGETABLE_ENTRIES]; void paging_init(void); void efi_update_l4_pgtable(unsigned int l4idx, l4_pgentry_t l4e); #endif /* !defined(__ASSEMBLY__) */