From mboxrd@z Thu Jan 1 00:00:00 1970 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 5E829C10DC2 for ; Wed, 29 Nov 2023 12:31:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:Message-ID: References:Mime-Version:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=0lcpf7OgNze85ZQHphNHidYsWhndMoEw7g9HGuRE2Ow=; b=KL6U+Z5RoQ1D51ArF0gmAqMVhA 3Hqyhd1MPVBZBkvMJ2bQ2JK4NgTDD94IzpLsv1wn52Zlsz/sv8kF2TIi7n3QpG743qgMKAbcgsjl5 j+09RJNWWZD21bhznZVFATxVnI7csXckf0MVaeXdMZkp0bBwH5zoTBvGRQ8s8wbz5nLvsOF4fKVaD kpovxyjfRvA+23Ab9SC0Gy5ou1+8fkkuP8i+oKRpinejUbzKn/y/MBIskkxrAjOnkJMAGX7pugnyn E1cI2oM3uDbkrnTjNbjXRftwhAb5r76PkM1nPpZnvC+MXnF1AUqfSiuu3VIicy0ZA/oKpAaBDW2lZ X8a3y13g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1r8Jij-008KGD-0F; Wed, 29 Nov 2023 12:31:13 +0000 Received: from mail-yw1-x1149.google.com ([2607:f8b0:4864:20::1149]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1r8IZj-007zKn-0J for linux-arm-kernel@lists.infradead.org; Wed, 29 Nov 2023 11:17:53 +0000 Received: by mail-yw1-x1149.google.com with SMTP id 00721157ae682-5cd573c2cccso6155487b3.1 for ; Wed, 29 Nov 2023 03:17:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1701256670; x=1701861470; darn=lists.infradead.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=p/WrAkNiGS1lyZlRoenmtvI9LCOO0S2O06anfvwOFrM=; b=tjk3nVh1ilfixM41V7cowcr879Vd7RLw1ubQLbeqFpmOD8JQNGkWAGIxZE1aZ5xbPO mCQeSqqoy1GJI7SdO/gE0jVfehlMJSMX/Sq1U4fv5D3bBnNqgsG+ejNq6un+XdkG3zOr 1xGj4djk2Puw4TEwpSwYi675tyaPJ/gGa8/df28lS/JCS4oIkKOrzv2TL9dCiT+J3B02 /iP6l+zyEWrqZdG9WiJOogKnUSaYgtthH4dxGW5w1US6w9glVelTL/3Qhe1cvPCOUpPx moy7mK2AXyOjOZbvBGDgB65cqZOqJZ9cJEI/DSSHWRIEmjwq3KM0ePRhU/t8ddvbDsNG GAcw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701256670; x=1701861470; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=p/WrAkNiGS1lyZlRoenmtvI9LCOO0S2O06anfvwOFrM=; b=DqI+Mies6/j+yTx1dM3pY90EgBPBZ1TElesejTxvAhB9lYOOQSQCF3joO3/jm9i6fl 7P28yNJy1iU4LZo60G7BrnMoPiw9hMASeNH6lOWniAmLpnyXcpb+anbDu83jxi3EhlzV tkS2BhGQGtQvqXOXUd8ylO7jovc8p7W/GVtJS97gufKMunffoMHFKlpeZxYdoFUdm/NY wr0mhZTlH3m2OeCiUoRI2OmMynPXDIJZBTSzZtizYCYeLcTPFkprm8yeHfYHqfbutk1W +96At0wyiXgOAGVpaLkR+JTWENGCkABUh9SbNL688TR5LJY8EwoJcYOQ4LrDtZBuQCgQ hHPA== X-Gm-Message-State: AOJu0YwmfocrZP51kheqyrcXeSDzE1I4DDDZpqlXNnqVBsqnYv6YEWgT RHgaLjWf33x0P/s6AIvD/q5ZfMTCc8dVKP07EUCG9AnAeBpimrezrAkThlL4Rh1TQkfMrRG6GSg BOBu7WXUaQFqyskUXY2mGpJQCMiRJWPDi2n50GSV6I+jh+Uz6NSN8DCocR6TbZoDaeU85uGXVhy Y= X-Google-Smtp-Source: AGHT+IGRjQ8KnvEbJ7JecVBntKMTIrm9kkghiuG/eOhQ0ILtV2IBf6jOqXT8V/m2/SHhjgHtCpUE7CbC X-Received: from palermo.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:118a]) (user=ardb job=sendgmr) by 2002:a05:690c:fd3:b0:5be:baac:54e4 with SMTP id dg19-20020a05690c0fd300b005bebaac54e4mr764894ywb.5.1701256669866; Wed, 29 Nov 2023 03:17:49 -0800 (PST) Date: Wed, 29 Nov 2023 12:16:11 +0100 In-Reply-To: <20231129111555.3594833-43-ardb@google.com> Mime-Version: 1.0 References: <20231129111555.3594833-43-ardb@google.com> X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Developer-Signature: v=1; a=openpgp-sha256; l=7072; i=ardb@kernel.org; h=from:subject; bh=q8XT5L50RWvW1cUh3bTsT037wqt/LAoX/+cOsWkmJ74=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JITVdtpZP44KHmtC+TWE86rLMTFET9hS1S/C0cgtlXGzd2 Bd8eV5HKQuDGAeDrJgii8Dsv+92np4oVes8SxZmDisTyBAGLk4BmEhME8M/U45pl6939/2bbdTQ e/d9za0whq+rfiT2yzGtFbz7W/mUMsP/zEcVR9cU9hZLfbrH/OHYmisLdt+XuXp2gdsps6w3Srp /+QE= X-Mailer: git-send-email 2.43.0.rc1.413.gea7ed67945-goog Message-ID: <20231129111555.3594833-58-ardb@google.com> Subject: [PATCH v6 15/41] arm64: idreg-override: Prepare for place relative reloc patching From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , Catalin Marinas , Will Deacon , Marc Zyngier , Mark Rutland , Ryan Roberts , Anshuman Khandual , Kees Cook X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20231129_031751_137983_82AAFF00 X-CRM114-Status: GOOD ( 21.22 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Ard Biesheuvel The ID reg override handling code uses a rather elaborate data structure that relies on statically initialized absolute address values in pointer fields. This means that this code cannot run until relocation fixups have been applied, and this is unfortunate, because it means we cannot discover overrides for KASLR or LVA/LPA without creating the kernel mapping and performing the relocations first. This can be solved by switching to place-relative relocations, which can be applied by the linker at build time. This means some additional arithmetic is required when dereferencing these pointers, as we can no longer dereference the pointer members directly. So let's implement this for idreg-override.c in a preliminary way, i.e., convert all the references in code to use a special accessor that produces the correct absolute value at runtime. Signed-off-by: Ard Biesheuvel --- arch/arm64/kernel/idreg-override.c | 89 ++++++++++++-------- 1 file changed, 56 insertions(+), 33 deletions(-) diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c index 536bc33859bc..ca1b8d2dbe99 100644 --- a/arch/arm64/kernel/idreg-override.c +++ b/arch/arm64/kernel/idreg-override.c @@ -21,14 +21,25 @@ static u64 __boot_status __initdata; +// temporary __prel64 related definitions +// to be removed when this code is moved under pi/ + +#define __prel64_initconst __initconst + +#define PREL64(type, name) union { type *name; } + +#define prel64_pointer(__d) (__d) + +typedef bool filter_t(u64 val); + struct ftr_set_desc { char name[FTR_DESC_NAME_LEN]; - struct arm64_ftr_override *override; + PREL64(struct arm64_ftr_override, override); struct { char name[FTR_DESC_FIELD_LEN]; u8 shift; u8 width; - bool (*filter)(u64 val); + PREL64(filter_t, filter); } fields[]; }; @@ -46,7 +57,7 @@ static bool __init mmfr1_vh_filter(u64 val) val == 0); } -static const struct ftr_set_desc mmfr1 __initconst = { +static const struct ftr_set_desc mmfr1 __prel64_initconst = { .name = "id_aa64mmfr1", .override = &id_aa64mmfr1_override, .fields = { @@ -70,7 +81,7 @@ static bool __init pfr0_sve_filter(u64 val) return true; } -static const struct ftr_set_desc pfr0 __initconst = { +static const struct ftr_set_desc pfr0 __prel64_initconst = { .name = "id_aa64pfr0", .override = &id_aa64pfr0_override, .fields = { @@ -94,7 +105,7 @@ static bool __init pfr1_sme_filter(u64 val) return true; } -static const struct ftr_set_desc pfr1 __initconst = { +static const struct ftr_set_desc pfr1 __prel64_initconst = { .name = "id_aa64pfr1", .override = &id_aa64pfr1_override, .fields = { @@ -105,7 +116,7 @@ static const struct ftr_set_desc pfr1 __initconst = { }, }; -static const struct ftr_set_desc isar1 __initconst = { +static const struct ftr_set_desc isar1 __prel64_initconst = { .name = "id_aa64isar1", .override = &id_aa64isar1_override, .fields = { @@ -117,7 +128,7 @@ static const struct ftr_set_desc isar1 __initconst = { }, }; -static const struct ftr_set_desc isar2 __initconst = { +static const struct ftr_set_desc isar2 __prel64_initconst = { .name = "id_aa64isar2", .override = &id_aa64isar2_override, .fields = { @@ -128,7 +139,7 @@ static const struct ftr_set_desc isar2 __initconst = { }, }; -static const struct ftr_set_desc smfr0 __initconst = { +static const struct ftr_set_desc smfr0 __prel64_initconst = { .name = "id_aa64smfr0", .override = &id_aa64smfr0_override, .fields = { @@ -149,7 +160,7 @@ static bool __init hvhe_filter(u64 val) ID_AA64MMFR1_EL1_VH_SHIFT)); } -static const struct ftr_set_desc sw_features __initconst = { +static const struct ftr_set_desc sw_features __prel64_initconst = { .name = "arm64_sw", .override = &arm64_sw_feature_override, .fields = { @@ -159,14 +170,15 @@ static const struct ftr_set_desc sw_features __initconst = { }, }; -static const struct ftr_set_desc * const regs[] __initconst = { - &mmfr1, - &pfr0, - &pfr1, - &isar1, - &isar2, - &smfr0, - &sw_features, +static const +PREL64(const struct ftr_set_desc, reg) regs[] __prel64_initconst = { + { &mmfr1 }, + { &pfr0 }, + { &pfr1 }, + { &isar1 }, + { &isar2 }, + { &smfr0 }, + { &sw_features }, }; static const struct { @@ -214,15 +226,20 @@ static void __init match_options(const char *cmdline) int i; for (i = 0; i < ARRAY_SIZE(regs); i++) { + const struct ftr_set_desc *reg = prel64_pointer(regs[i].reg); + struct arm64_ftr_override *override; int f; - for (f = 0; strlen(regs[i]->fields[f].name); f++) { - u64 shift = regs[i]->fields[f].shift; - u64 width = regs[i]->fields[f].width ?: 4; + override = prel64_pointer(reg->override); + + for (f = 0; strlen(reg->fields[f].name); f++) { + u64 shift = reg->fields[f].shift; + u64 width = reg->fields[f].width ?: 4; u64 mask = GENMASK_ULL(shift + width - 1, shift); + bool (*filter)(u64 val); u64 v; - if (find_field(cmdline, regs[i], f, &v)) + if (find_field(cmdline, reg, f, &v)) continue; /* @@ -230,16 +247,16 @@ static void __init match_options(const char *cmdline) * it by setting the value to the all-ones while * clearing the mask... Yes, this is fragile. */ - if (regs[i]->fields[f].filter && - !regs[i]->fields[f].filter(v)) { - regs[i]->override->val |= mask; - regs[i]->override->mask &= ~mask; + filter = prel64_pointer(reg->fields[f].filter); + if (filter && !filter(v)) { + override->val |= mask; + override->mask &= ~mask; continue; } - regs[i]->override->val &= ~mask; - regs[i]->override->val |= (v << shift) & mask; - regs[i]->override->mask |= mask; + override->val &= ~mask; + override->val |= (v << shift) & mask; + override->mask |= mask; return; } @@ -313,11 +330,16 @@ void init_feature_override(u64 boot_status); asmlinkage void __init init_feature_override(u64 boot_status) { + struct arm64_ftr_override *override; + const struct ftr_set_desc *reg; int i; for (i = 0; i < ARRAY_SIZE(regs); i++) { - regs[i]->override->val = 0; - regs[i]->override->mask = 0; + reg = prel64_pointer(regs[i].reg); + override = prel64_pointer(reg->override); + + override->val = 0; + override->mask = 0; } __boot_status = boot_status; @@ -325,8 +347,9 @@ asmlinkage void __init init_feature_override(u64 boot_status) parse_cmdline(); for (i = 0; i < ARRAY_SIZE(regs); i++) { - dcache_clean_inval_poc((unsigned long)regs[i]->override, - (unsigned long)regs[i]->override + - sizeof(*regs[i]->override)); + reg = prel64_pointer(regs[i].reg); + override = prel64_pointer(reg->override); + dcache_clean_inval_poc((unsigned long)override, + (unsigned long)(override + 1)); } } -- 2.43.0.rc1.413.gea7ed67945-goog _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel