From patchwork Fri Nov 11 17:11:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 13040632 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 9DD45C433FE for ; Fri, 11 Nov 2022 17:19:48 +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:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OTVOmj4ngzQyla8dFKpq7VEjRmyLE28IEbk2tL3PqGY=; b=E/Wkf8yHaXb7x4 WUCz/6702gh9I+NNDFBa9xozK5MTk9wkODsF9aO6I33VypVZrBY7H3DJUsFPhp3rYfgBfRHIPHgUw GTx1+z7nAcQkStRTGp7X4tasYIOkXU4Do56QL5j6YytOAmN+PJbiRFqE1GT1hX1oVYVQ/7WGXuFGj PD0R/RSqZGCL7uYPKWT8gfgNB22uarI2Jp/F8BM27tsV3PI5tX4bkUjZwIqunEZupXC37d6aSAddF t2VcR73vtQ/eay4l2ybwh76+RICst10S9e0dZ/LiVyu6VMf4PrduUKmMVrfEplBy8TNFh/ftHb4Ho pZFlMVS3jD/zCbooJlKw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otXfp-00HB1d-8Y; Fri, 11 Nov 2022 17:18:38 +0000 Received: from dfw.source.kernel.org ([139.178.84.217]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otXaB-00H7i6-63 for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 17:12:49 +0000 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 98EA7618C9; Fri, 11 Nov 2022 17:12:46 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2EA52C43143; Fri, 11 Nov 2022 17:12:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1668186766; bh=gLi5zeKVhBRT8OeLpkGKtd7SxypDRIvJhPj5bROHmFQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=W/u74QK8d5RuVF6qpDaf+5PHS5Q7NBKCSJI1BjAHCKWjlxNOYAq/p9Sq4O8e69E7I kEhkB3PkTqrX6nPDorC6UmK9GpatmaoV2xwlfBK9Xx/BNvW0HFjGJeluMmVlJAxRek +XCEBr5nz4eLwXfLLf/8KkZj4oPEkr1wfDq1akNbIGlLKOcFp6KGb1XCavUm7F5lzR Hr89xUsJEv8o/9T88whJ1SglzsujhkxvWttOaX0ouaPDxzQnE9e80zeC/lrHVpAGcV QYHqJH7pkZC6Rba0m04izUzPbfBI+gzK2OKXQtDVZci4swM9B9lDljn93Yjihl1Csw tqsvqlnZqyo5w== From: Ard Biesheuvel To: linux-arm-kernel@lists.infradead.org Cc: Ard Biesheuvel , Marc Zyngier , Will Deacon , Mark Rutland , Kees Cook , Catalin Marinas , Mark Brown , Anshuman Khandual Subject: [PATCH v7 12/33] arm64: idreg-override: Use relative references to filter routines Date: Fri, 11 Nov 2022 18:11:40 +0100 Message-Id: <20221111171201.2088501-13-ardb@kernel.org> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221111171201.2088501-1-ardb@kernel.org> References: <20221111171201.2088501-1-ardb@kernel.org> MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6429; i=ardb@kernel.org; h=from:subject; bh=gLi5zeKVhBRT8OeLpkGKtd7SxypDRIvJhPj5bROHmFQ=; b=owEB7QES/pANAwAKAcNPIjmS2Y8kAcsmYgBjboI8+j8VZM1CSX/rO62HZ0eW0hT6Ys3HmP9PAKwR LQwvQCaJAbMEAAEKAB0WIQT72WJ8QGnJQhU3VynDTyI5ktmPJAUCY26CPAAKCRDDTyI5ktmPJIjGC/ 48G3FrEJr2K8IAbmisVQ+/DEoABnZLbXN40qLPh9gS+rHSgiX75dWczg1WRUJvhFm5+uRQFiOSQsJj DdenhIIA9vhXeyBLLur7lYlxFjuRpiMXZoh579jjKPQZo4707QG4owEYiLOq4MnU+oTVjfR3jwL8Nk ApCTcCY5RZ2ZhWY6mUcWhdlMMQPj2IJGfzgaQSOG8FjXt+5PbhOqK4FA3QRicXw877tqFG3SGaJpaG nJP9r3s7EdChNdtCrYWowCvB8BAlDapMErI2VeJJquoxO++ovlZdSzNiaUWXH79mFZCs6acYmyCdTk kYMCWoTT3rpbMiNBzqJ9J5WZ58t9J6SAwhcN0TY0xNaL5LriTbr8VWIzmU9qV0+sXM53L0JTM8ma1J kIYb84bgVid5ONF7HmVztR3nr9KCmoys3RjbrSouSWNONm11jk7s0uDO1XEvDY4opxM9s5rT+1+Gmh YZzwrD0x63z70bO/sWk6AY7BaL7n+NrpNm3vTnGXwraKM= X-Developer-Key: i=ardb@kernel.org; a=openpgp; fpr=F43D03328115A198C90016883D200E9CA6329909 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_091247_388125_7A1CCD2E X-CRM114-Status: GOOD ( 19.36 ) 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: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org To avoid statically initialized pointer variables, which need runtime relocation and therefore prevent this code from being used before relocations have been processed, tweak the static declarations so that relative references are used instead. This means we will be doing the job of the compiler and calculate where exactly the relocation needs to point, so add some asserts to ensure we notice when we get it wrong. Signed-off-by: Ard Biesheuvel --- arch/arm64/kernel/idreg-override.c | 63 +++++++++++++------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c index f8ae7f6d0d9b4fd0..01eed0eaba7c1cdd 100644 --- a/arch/arm64/kernel/idreg-override.c +++ b/arch/arm64/kernel/idreg-override.c @@ -15,8 +15,8 @@ #include #include -#define FTR_DESC_NAME_LEN 20 -#define FTR_DESC_FIELD_LEN 10 +#define FTR_DESC_NAME_LEN 20 // must remain multiple of 4 +#define FTR_DESC_FIELD_LEN 10 // must remain multiple of 4 +/- 2 #define FTR_ALIAS_NAME_LEN 30 #define FTR_ALIAS_OPTION_LEN 116 @@ -26,16 +26,20 @@ struct ftr_set_desc { s32 override_offset; // must remain first char name[FTR_DESC_NAME_LEN]; struct { + s32 filter_offset; // must remain first char name[FTR_DESC_FIELD_LEN]; u8 shift; u8 width; - bool (*filter)(u64 val); } fields[]; }; static_assert(offsetof(struct ftr_set_desc, override_offset) == 0); +static_assert(offsetof(struct ftr_set_desc, fields[0].filter_offset) == + 4 + FTR_DESC_NAME_LEN); +static_assert(offsetof(struct ftr_set_desc, fields[1].filter_offset) == + 4 + FTR_DESC_NAME_LEN + 4 + FTR_DESC_FIELD_LEN + 2); -#define FIELD(n, s, f) { .name = n, .shift = s, .width = 4, .filter = f } +#define FIELD(n, s) { .name = n, .shift = s, .width = 4 } #define DEFINE_OVERRIDE(__idx, __id, __name, __ovr, ...) \ asmlinkage const struct ftr_set_desc __initconst __id = { \ @@ -46,7 +50,12 @@ static_assert(offsetof(struct ftr_set_desc, override_offset) == 0); ".reloc " #__id ", R_AARCH64_PREL32, " #__ovr "; " \ ".reloc regs + (4 * " #__idx "), R_AARCH64_PREL32, " #__id) -static bool __init mmfr1_vh_filter(u64 val) +#define DEFINE_OVERRIDE_FILTER(__id, __idx, __filter) \ + asm(".reloc " #__id " + 4 + " __stringify(FTR_DESC_NAME_LEN) \ + " + " #__idx " * (4 + " __stringify(FTR_DESC_FIELD_LEN) " + 2)," \ + "R_AARCH64_PREL32, " #__filter) + +asmlinkage bool __init mmfr1_vh_filter(u64 val) { /* * If we ever reach this point while running VHE, we're @@ -59,10 +68,11 @@ static bool __init mmfr1_vh_filter(u64 val) } DEFINE_OVERRIDE(0, mmfr1, "id_aa64mmfr1", id_aa64mmfr1_override, - FIELD("vh", ID_AA64MMFR1_EL1_VH_SHIFT, mmfr1_vh_filter), + FIELD("vh", ID_AA64MMFR1_EL1_VH_SHIFT), {}); +DEFINE_OVERRIDE_FILTER(mmfr1, 0, mmfr1_vh_filter); -static bool __init pfr0_sve_filter(u64 val) +asmlinkage bool __init pfr0_sve_filter(u64 val) { /* * Disabling SVE also means disabling all the features that @@ -78,10 +88,11 @@ static bool __init pfr0_sve_filter(u64 val) } DEFINE_OVERRIDE(1, pfr0, "id_aa64pfr0", id_aa64pfr0_override, - FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT, pfr0_sve_filter), + FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT), {}); +DEFINE_OVERRIDE_FILTER(pfr0, 0, pfr0_sve_filter); -static bool __init pfr1_sme_filter(u64 val) +asmlinkage bool __init pfr1_sme_filter(u64 val) { /* * Similarly to SVE, disabling SME also means disabling all @@ -97,30 +108,31 @@ static bool __init pfr1_sme_filter(u64 val) } DEFINE_OVERRIDE(2, pfr1, "id_aa64pfr1", id_aa64pfr1_override, - FIELD("bt", ID_AA64PFR1_EL1_BT_SHIFT, NULL ), - FIELD("mte", ID_AA64PFR1_EL1_MTE_SHIFT, NULL), - FIELD("sme", ID_AA64PFR1_EL1_SME_SHIFT, pfr1_sme_filter), + FIELD("bt", ID_AA64PFR1_EL1_BT_SHIFT ), + FIELD("mte", ID_AA64PFR1_EL1_MTE_SHIFT), + FIELD("sme", ID_AA64PFR1_EL1_SME_SHIFT), {}); +DEFINE_OVERRIDE_FILTER(pfr1, 2, pfr1_sme_filter); DEFINE_OVERRIDE(3, isar1, "id_aa64isar1", id_aa64isar1_override, - FIELD("gpi", ID_AA64ISAR1_EL1_GPI_SHIFT, NULL), - FIELD("gpa", ID_AA64ISAR1_EL1_GPA_SHIFT, NULL), - FIELD("api", ID_AA64ISAR1_EL1_API_SHIFT, NULL), - FIELD("apa", ID_AA64ISAR1_EL1_APA_SHIFT, NULL), + FIELD("gpi", ID_AA64ISAR1_EL1_GPI_SHIFT), + FIELD("gpa", ID_AA64ISAR1_EL1_GPA_SHIFT), + FIELD("api", ID_AA64ISAR1_EL1_API_SHIFT), + FIELD("apa", ID_AA64ISAR1_EL1_APA_SHIFT), {}); DEFINE_OVERRIDE(4, isar2, "id_aa64isar2", id_aa64isar2_override, - FIELD("gpa3", ID_AA64ISAR2_EL1_GPA3_SHIFT, NULL), - FIELD("apa3", ID_AA64ISAR2_EL1_APA3_SHIFT, NULL), + FIELD("gpa3", ID_AA64ISAR2_EL1_GPA3_SHIFT), + FIELD("apa3", ID_AA64ISAR2_EL1_APA3_SHIFT), {}); DEFINE_OVERRIDE(5, smfr0, "id_aa64smfr0", id_aa64smfr0_override, /* FA64 is a one bit field... :-/ */ - { "fa64", ID_AA64SMFR0_EL1_FA64_SHIFT, 1, }, + { 0, "fa64", ID_AA64SMFR0_EL1_FA64_SHIFT, 1, }, {}); DEFINE_OVERRIDE(6, sw_features, "arm64_sw", arm64_sw_feature_override, - FIELD("nokaslr", ARM64_SW_FEATURE_OVERRIDE_NOKASLR, NULL), + FIELD("nokaslr", ARM64_SW_FEATURE_OVERRIDE_NOKASLR), {}); /* @@ -169,6 +181,13 @@ static int __init find_field(const char *cmdline, return kstrtou64(cmdline + len, 0, v); } +static const void * __init get_filter(const struct ftr_set_desc *reg, int idx) +{ + const s32 *offset = ®->fields[idx].filter_offset; + + return *offset ? offset_to_ptr(offset) : NULL; +} + static void __init match_options(const char *cmdline) { int i; @@ -181,6 +200,7 @@ static void __init match_options(const char *cmdline) u64 shift = reg->fields[f].shift; u64 width = reg->fields[f].width ?: 4; u64 mask = GENMASK_ULL(shift + width - 1, shift); + bool (*filter)(u64) = get_filter(reg, f); u64 v; if (find_field(cmdline, reg, f, &v)) @@ -191,8 +211,7 @@ 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 (reg->fields[f].filter && - !reg->fields[f].filter(v)) { + if (filter && !filter(v)) { reg_override(i)->val |= mask; reg_override(i)->mask &= ~mask; continue;