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 80CB8C636D0 for ; Fri, 24 Nov 2023 11:31:55 +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=EkG4bG5x2lt/sO98bPuD/nxwedXeawDf2Bj/6j/9rug=; b=28HEyYzfnafTn666Giwj0GKuMv guLs5pynx08JfA6rSktNIQ4PLxT3jO3JqtUE/vINXGqkMSvfyYVa5vxBfB6/8DjW48dz5icxhOpXq 25350rUu72lgST4T/x8U4bMjyoJQwse5xgODcT6xwbLZJOeYKQXuveyWNFh8WBynMK3lQLBxDLZJr VgBM1+R0KQCYBB+KM9fXohKETnDraGbZQVO8VDCX6tjyGSwx2g4PVn5BBbaccwZAViCVxxWzjLtPL gqazGmEHbPTkLx169nTkmo/YgGzManUw9GtF6ME+1IWwsbDFeGTRs0rDgbRTL34kW87UU/CB0bUan OK8JS8+Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1r6UPV-006yTW-2n; Fri, 24 Nov 2023 11:31:49 +0000 Received: from mail-wm1-x349.google.com ([2a00:1450:4864:20::349]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1r6TIn-006ohd-2I for linux-arm-kernel@lists.infradead.org; Fri, 24 Nov 2023 10:20:57 +0000 Received: by mail-wm1-x349.google.com with SMTP id 5b1f17b1804b1-40b357e2a01so8803415e9.1 for ; Fri, 24 Nov 2023 02:20:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1700821248; x=1701426048; 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=jyJ9aXJPr1TS0bTOf9aHRSmaKnZpYKNHVy9OuKiC+Do=; b=HnjQ5C9vXNXbctVO4zZfx7RQ5WRAZlv7XRpKQcjVXr7DmzLwPA1EznvWcwYT/NjHTr HdArOAwNvEBafMpX74hIj3eEI/cCA2hLHVnNQtOXtI5RgoRyqDK+fXjrjDFz0sOHEHLz EKqnYvcZ8uqzrksFeKzRu5mpUOpC0Nq5iw+Bq2q7YSLoIHC4sGgd542l/8AbHcJyuC5W hTclGeKweEj9SyvOD5dl7lWHTSWU6p69d+SDBtdUhrLwMwhG+5jJ8HtJoqaHskJIH9jj S5oR/kBmlF/8myvo/zxhmjrk9fZgBbWSFHH1VYgO7g67tjGoSi+fii5uL1fQA5f7Szc8 KPpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700821248; x=1701426048; 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=jyJ9aXJPr1TS0bTOf9aHRSmaKnZpYKNHVy9OuKiC+Do=; b=KfaXb3k1L2ZMF4xvlSc294sSme4yOOTsF5RevqVI1WUsgUcapekjour7sGn8PrrHKC G7WliPh1SRzaWpRWuIaw9jhGD1NYBdaVqrSJiMx+HIA44PGsBgl6tcAzMkQPRIAyU3Gv /5rqJedznKiH0hsUcQ55M2pJjePHccCzn9/skHoqHpdcsSbvE11hsO8X1pLbTtY7idBZ yv9/RzNkIoHvj9hbvjtwFpDBbR6S0r7F/pfeT7IXm+np54iB5i7tyqRDk+Ak9HrQ8wsK 7Pj7vp+2MSIH9ZoiXseZftdRDvEacbe0SFMH9Fxl8fkXEa4RGz8DOpASplb9VHV9ksHp avAg== X-Gm-Message-State: AOJu0Yyz7Plnmm8wHahor2NprOfb9eoiTkOA/QCnwVkk1d3AC4kyKk34 Po7RqfNNHjfHgAgGvVhrM6N+HnoHwLZk5/qiTa0Xpt9BKUl68yiTf6AguYObqrYvHJG78832YJz qvbFi50Wu6YjFHeddjNfBr98J9CPiBRZeV7ix/+PVZLOcBjbaEWKbUftk30rNDHF72edzz3gYRi s= X-Google-Smtp-Source: AGHT+IFOUHM8bDnIZMTKwXnUdhsi3OBeRJrwytyRzGngvnUXMh19tUxhXaJjhsJVDT4LBFuWULCJqYr/ X-Received: from palermo.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:118a]) (user=ardb job=sendgmr) by 2002:a05:6000:12d2:b0:32d:aa14:875f with SMTP id l18-20020a05600012d200b0032daa14875fmr39013wrx.7.1700821247689; Fri, 24 Nov 2023 02:20:47 -0800 (PST) Date: Fri, 24 Nov 2023 11:18:55 +0100 In-Reply-To: <20231124101840.944737-41-ardb@google.com> Mime-Version: 1.0 References: <20231124101840.944737-41-ardb@google.com> X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-Developer-Signature: v=1; a=openpgp-sha256; l=7408; i=ardb@kernel.org; h=from:subject; bh=OcGSnfOSPAAXJV7v/uYFRQlCxbOdTLOskF+X8oTTUBM=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JITWhYtI7ocuP/n2dWPP4vry97Xv31Rsfaxzqz1u3L9DHQ PZinP/mjlIWBjEOBlkxRRaB2X/f7Tw9UarWeZYszBxWJpAhDFycAjCR9a0M/5QvRnp8OrbcKS7l 0F/hmYvin9xSDWDiXzpFd+mmfoXU2j2MDF+vMB8x0Z921P/CVtV8+XUWOSuyL15g7/6xysndLeJ rASsA X-Mailer: git-send-email 2.43.0.rc1.413.gea7ed67945-goog Message-ID: <20231124101840.944737-56-ardb@google.com> Subject: [PATCH v5 15/39] 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-20231124_022049_785909_B59ED08B X-CRM114-Status: GOOD ( 20.91 ) 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. To preserve the strong type checking for the static initializers, use union types for representing the hybrid quantities. Signed-off-by: Ard Biesheuvel --- arch/arm64/kernel/idreg-override.c | 98 +++++++++++++------- 1 file changed, 65 insertions(+), 33 deletions(-) diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c index 536bc33859bc..4e32a44560bf 100644 --- a/arch/arm64/kernel/idreg-override.c +++ b/arch/arm64/kernel/idreg-override.c @@ -21,14 +21,32 @@ static u64 __boot_status __initdata; +// temporary __prel64 related definitions +// to be removed when this code is moved under pi/ + +#define __prel64_initconst __initconst + +typedef void *prel64_t; + +static void *prel64_to_pointer(const prel64_t *p) +{ + return *p; +} + struct ftr_set_desc { char name[FTR_DESC_NAME_LEN]; - struct arm64_ftr_override *override; + union { + struct arm64_ftr_override *override; + prel64_t override_prel; + }; struct { char name[FTR_DESC_FIELD_LEN]; u8 shift; u8 width; - bool (*filter)(u64 val); + union { + bool (*filter)(u64 val); + prel64_t filter_prel; + }; } fields[]; }; @@ -46,7 +64,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 +88,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 +112,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 +123,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 +135,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 +146,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 +167,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 +177,17 @@ 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 union { + const struct ftr_set_desc *reg; + prel64_t reg_prel; +} regs[] __prel64_initconst = { + { .reg = &mmfr1 }, + { .reg = &pfr0 }, + { .reg = &pfr1 }, + { .reg = &isar1 }, + { .reg = &isar2 }, + { .reg = &smfr0 }, + { .reg = &sw_features }, }; static const struct { @@ -214,15 +235,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_to_pointer(®s[i].reg_prel); + 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_to_pointer(®->override_prel); + + 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 +256,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_to_pointer(®->fields[f].filter_prel); + 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 +339,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_to_pointer(®s[i].reg_prel); + override = prel64_to_pointer(®->override_prel); + + override->val = 0; + override->mask = 0; } __boot_status = boot_status; @@ -325,8 +356,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_to_pointer(®s[i].reg_prel); + override = prel64_to_pointer(®->override_prel); + 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