From patchwork Fri Nov 24 10:19:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 13467460 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 ADC88C636CB for ; Fri, 24 Nov 2023 10:23:46 +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=MsAtw/0FNe0B374Z2l266x1NgFpbR2HqIPtCUqpzDMc=; b=IsmcBy+c4L9pClnajfDb9BqXUs Jd0By8MtWBxi7vDvwsJ888hnTbMqtkmH5M0MnSUeFKkcKCAYGgvyOexr4ImBdyu625Ac+MeEcsQBv gJEAcc3wCTfmBxytPgFq4g9F8q4lttAjwWPX2atQVCTZUW7yaLChyYSOz2vX6LWSuiNXNA5BX/GZh wOeSUCAsE3g2Wb6qYKs/Vln/zKR0gRZDXMNBgojetoXvG3p/FZ61OcW4pPF37O4QMtzSpKs3jBtNm Lvwq0W98hN+DCcVI7355ASHGbHPp1Ad9fgC81y1/ZjNhMe2qcFYIAM9Xi2WGh6keaqxKfdYaCxnCB T4lppEhA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1r6TL4-006pwL-2N; Fri, 24 Nov 2023 10:23:10 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1r6TKA-006pc8-2H for linux-arm-kernel@bombadil.infradead.org; Fri, 24 Nov 2023 10:22:14 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Type:Cc:To:From:Subject: Message-ID:References:Mime-Version:In-Reply-To:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=via/947AL7nxdvgSE2nro4c+kFND3Teh9zjacOXE+kk=; b=JDYi09Cc7sVEcmWViHdZN61XO8 Pzc7499PMkMRJmMHPf1m4TTvq5usIpeQLpaZGdEQNmnj3ZSZHFmfHIzwtFzFlGtR3GXmCEPCNcrWr ppmjmmKtkvahep7zwnRH59ABHjxmRrB0uJOzPXcTtwWqIA2vB6QTHIruhJUFN+oXCPI1isHKYRkmC 6HHtRjsZm6crHr/S3Cpe4UL+Az21WF1w8TPIvCY5ak+q1QpKkBX0/3zNpG1SIMb7rWHgfJ1Pg64gr wudezvAYewde9mFTKDcKt9F3vyzvaauOghoYP4zF3TFBUAqyNL7e14+yr56k1hR8nBBelRC3Y0XCg pJ3AL8gA==; Received: from mail-wm1-x34a.google.com ([2a00:1450:4864:20::34a]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1r6TJu-00DqX5-25 for linux-arm-kernel@lists.infradead.org; Fri, 24 Nov 2023 10:22:11 +0000 Received: by mail-wm1-x34a.google.com with SMTP id 5b1f17b1804b1-40b2977d6baso8984925e9.2 for ; Fri, 24 Nov 2023 02:21:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1700821291; x=1701426091; 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=via/947AL7nxdvgSE2nro4c+kFND3Teh9zjacOXE+kk=; b=TCc7Sn6pZcR2RyO8q+t7w+h8fLbG4/aH/ryoTSY77bxKYwyFiauXwBqAJZufS26ngE txjqAdzMcpHMijKXZolOWP/gJklIQMpZ6kXviLJn4iRDi6FRkTYKmf7Fpnv+lYp7SjEB 2AyyrIW/9cXFxNeRgWWIvzoRzyDhvGI2hphpXXvwfN6oqmoIgvGZzR39x6SKdqOoaCYa DN1CQaooF9PYaQky+q4qMhe04cb/NjOZoNL3euFvvk7GkPAIH+aGbG6WaKwDCpKppUe7 /AQmUzC409EYKRozV+O1BKOfB7/vzrVMpYQ9nTBQL46LcgJmtptWbh/K0pAvlj7DkCgm n/jA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700821291; x=1701426091; 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=via/947AL7nxdvgSE2nro4c+kFND3Teh9zjacOXE+kk=; b=RJSTBYDzSKmc1IEOl29zCIxLOVyCCb5eisC/vkjZB/tp577PUgOQ9+RNSiaBQCQ98V y7Djaiu6V7NS3oU9ucerb2XnLLN56R5Hnqjw8mZ5bsPtuS4+lTfPfXJVMcoHemVZw5rp BjbaIcHXKQ0LkigEBjh9iwSthN+Sxzga82oH6R2txykFA7F1cEy9GLtLBQA8vDwwRa7r JUUk5iDqebkNFd7PLMz5EUaSKVhgSuq7MtSdigF1P3bnhwmo6CY9FSwjoH5gEp6Hkngd 7NX/HuaR3nYL+eeaO1C2/7L4vR6WzcFWF6udplkw0ZnI9vseuNoCQr6pwyo5H6N1JQJT m5FA== X-Gm-Message-State: AOJu0Yzgo+CmMw9KU+MjtEIoH2XbHFWsq5chg64DjaqSjrCweFFXnamh vIi/c75D/Bu3OD3KDePwMo2Fc5IS668GkgLTLUUEmahvpu77XLgIu9vQ7rirKK2UWmotW4V2PZp FDRr235ftM6wmQiR7DreIRdAPRhI+MesUAE5gogNNjYbD4t8MXGzDFkJ+VXr/6VAV/Aref8BYiO M= X-Google-Smtp-Source: AGHT+IHm36msVnMBXl33QHj8GorzwrPvPaR0u3k5ghjYFMKvMpUioUpD/47euE4C+Y/rm+z6ZkvzJLdi X-Received: from palermo.c.googlers.com ([fda3:e722:ac3:cc00:28:9cb1:c0a8:118a]) (user=ardb job=sendgmr) by 2002:adf:b60a:0:b0:332:ddd8:859b with SMTP id f10-20020adfb60a000000b00332ddd8859bmr42532wre.2.1700821291564; Fri, 24 Nov 2023 02:21:31 -0800 (PST) Date: Fri, 24 Nov 2023 11:19:14 +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=7014; i=ardb@kernel.org; h=from:subject; bh=V8rU2zh2WeBn4WszMWjet22dmrtBYY4KlyDB/jHLvnc=; b=owGbwMvMwCFmkMcZplerG8N4Wi2JITWhYt21RdHXJa0TzMsagnt+vJ7ytkBZhn9qQwBbWNrjz fGzup51lLIwiHEwyIopsgjM/vtu5+mJUrXOs2Rh5rAygQxh4OIUgInsM2NkOK7wIkzk04KQS2eX n3fkUzC1+bgpsnWGjPaqy8ecT+l6CzAydBpVL7xgtUvqOc/bCSvqk3etU3WtSP8raVcauPWtw11 dFgA= X-Mailer: git-send-email 2.43.0.rc1.413.gea7ed67945-goog Message-ID: <20231124101840.944737-75-ardb@google.com> Subject: [PATCH v5 34/39] arm64: mm: Use 48-bit virtual addressing for the permanent ID map 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_102159_020409_102CDC03 X-CRM114-Status: GOOD ( 24.12 ) 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 From: Ard Biesheuvel Even though we support loading kernels anywhere in 48-bit addressable physical memory, we create the ID maps based on the number of levels that we happened to configure for the kernel VA and user VA spaces. The reason for this is that the PGD/PUD/PMD based classification of translation levels, along with the associated folding when the number of levels is less than 5, does not permit creating a page table hierarchy of a set number of levels. This means that, for instance, on 39-bit VA kernels we need to configure an additional level above PGD level on the fly, and 36-bit VA kernels still only support 47-bit virtual addressing with this trick applied. Now that we have a separate helper to populate page table hierarchies that does not define the levels in terms of PUDS/PMDS/etc at all, let's reuse it to create the permanent ID map with a fixed VA size of 48 bits. Signed-off-by: Ard Biesheuvel --- arch/arm64/include/asm/kernel-pgtable.h | 3 ++ arch/arm64/kernel/head.S | 5 +++ arch/arm64/kvm/mmu.c | 15 +++------ arch/arm64/mm/mmu.c | 32 +++++++++++--------- arch/arm64/mm/proc.S | 9 ++---- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/arch/arm64/include/asm/kernel-pgtable.h b/arch/arm64/include/asm/kernel-pgtable.h index 0631604995ee..742a4b2778f7 100644 --- a/arch/arm64/include/asm/kernel-pgtable.h +++ b/arch/arm64/include/asm/kernel-pgtable.h @@ -35,6 +35,9 @@ #define SWAPPER_PGTABLE_LEVELS (CONFIG_PGTABLE_LEVELS) #endif +#define IDMAP_VA_BITS 48 +#define IDMAP_LEVELS ARM64_HW_PGTABLE_LEVELS(IDMAP_VA_BITS) +#define IDMAP_ROOT_LEVEL (4 - IDMAP_LEVELS) /* * A relocatable kernel may execute from an address that differs from the one at diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S index ffacce7b5a02..a1c29d64e875 100644 --- a/arch/arm64/kernel/head.S +++ b/arch/arm64/kernel/head.S @@ -729,6 +729,11 @@ SYM_FUNC_START_LOCAL(__no_granule_support) SYM_FUNC_END(__no_granule_support) SYM_FUNC_START_LOCAL(__primary_switch) + mrs x1, tcr_el1 + mov x2, #64 - VA_BITS + tcr_set_t0sz x1, x2 + msr tcr_el1, x1 + adrp x1, reserved_pg_dir adrp x2, init_idmap_pg_dir bl __enable_mmu diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c index d87c8fcc4c24..234b03e18ff7 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1873,16 +1873,9 @@ int __init kvm_mmu_init(u32 *hyp_va_bits) BUG_ON((hyp_idmap_start ^ (hyp_idmap_end - 1)) & PAGE_MASK); /* - * The ID map may be configured to use an extended virtual address - * range. This is only the case if system RAM is out of range for the - * currently configured page size and VA_BITS_MIN, in which case we will - * also need the extended virtual range for the HYP ID map, or we won't - * be able to enable the EL2 MMU. - * - * However, in some cases the ID map may be configured for fewer than - * the number of VA bits used by the regular kernel stage 1. This - * happens when VA_BITS=52 and the kernel image is placed in PA space - * below 48 bits. + * The ID map is always configured for 48 bits of translation, which + * may be fewer than the number of VA bits used by the regular kernel + * stage 1, when VA_BITS=52. * * At EL2, there is only one TTBR register, and we can't switch between * translation tables *and* update TCR_EL2.T0SZ at the same time. Bottom @@ -1893,7 +1886,7 @@ int __init kvm_mmu_init(u32 *hyp_va_bits) * 1 VA bits to assure that the hypervisor can both ID map its code page * and map any kernel memory. */ - idmap_bits = 64 - ((idmap_t0sz & TCR_T0SZ_MASK) >> TCR_T0SZ_OFFSET); + idmap_bits = IDMAP_VA_BITS; kernel_bits = vabits_actual; *hyp_va_bits = max(idmap_bits, kernel_bits); diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 03c73e9197ac..94847dbd31cd 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -754,22 +754,21 @@ static void __init map_kernel(pgd_t *pgdp) kasan_copy_shadow(pgdp); } +void __pi_map_range(u64 *pgd, u64 start, u64 end, u64 pa, pgprot_t prot, + int level, pte_t *tbl, bool may_use_cont, u64 va_offset); + +static u8 idmap_ptes[IDMAP_LEVELS - 1][PAGE_SIZE] __aligned(PAGE_SIZE) __ro_after_init, + kpti_ptes[IDMAP_LEVELS - 1][PAGE_SIZE] __aligned(PAGE_SIZE) __ro_after_init; + static void __init create_idmap(void) { u64 start = __pa_symbol(__idmap_text_start); - u64 size = __pa_symbol(__idmap_text_end) - start; - pgd_t *pgd = idmap_pg_dir; - u64 pgd_phys; - - /* check if we need an additional level of translation */ - if (VA_BITS < 48 && idmap_t0sz < (64 - VA_BITS_MIN)) { - pgd_phys = early_pgtable_alloc(PAGE_SHIFT); - set_pgd(&idmap_pg_dir[start >> VA_BITS], - __pgd(pgd_phys | P4D_TYPE_TABLE)); - pgd = __va(pgd_phys); - } - __create_pgd_mapping(pgd, start, start, size, PAGE_KERNEL_ROX, - early_pgtable_alloc, 0); + u64 end = __pa_symbol(__idmap_text_end); + u64 ptep = __pa_symbol(idmap_ptes); + + __pi_map_range(&ptep, start, end, start, PAGE_KERNEL_ROX, + IDMAP_ROOT_LEVEL, (pte_t *)idmap_pg_dir, false, + __phys_to_virt(ptep) - ptep); if (IS_ENABLED(CONFIG_UNMAP_KERNEL_AT_EL0)) { extern u32 __idmap_kpti_flag; @@ -779,8 +778,10 @@ static void __init create_idmap(void) * The KPTI G-to-nG conversion code needs a read-write mapping * of its synchronization flag in the ID map. */ - __create_pgd_mapping(pgd, pa, pa, sizeof(u32), PAGE_KERNEL, - early_pgtable_alloc, 0); + ptep = __pa_symbol(kpti_ptes); + __pi_map_range(&ptep, pa, pa + sizeof(u32), pa, PAGE_KERNEL, + IDMAP_ROOT_LEVEL, (pte_t *)idmap_pg_dir, false, + __phys_to_virt(ptep) - ptep); } } @@ -805,6 +806,7 @@ void __init paging_init(void) memblock_allow_resize(); create_idmap(); + idmap_t0sz = TCR_T0SZ(IDMAP_VA_BITS); } #ifdef CONFIG_MEMORY_HOTPLUG diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 7c1bdaf25408..47ede52bb900 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -421,9 +421,9 @@ SYM_FUNC_START(__cpu_setup) mair .req x17 tcr .req x16 mov_q mair, MAIR_EL1_SET - mov_q tcr, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ - TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ - TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS + mov_q tcr, TCR_T0SZ(IDMAP_VA_BITS) | TCR_T1SZ(VA_BITS) | TCR_CACHE_FLAGS | \ + TCR_SMP_FLAGS | TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ + TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS tcr_clear_errata_bits tcr, x9, x5 @@ -431,10 +431,7 @@ SYM_FUNC_START(__cpu_setup) sub x9, xzr, x0 add x9, x9, #64 tcr_set_t1sz tcr, x9 -#else - idmap_get_t0sz x9 #endif - tcr_set_t0sz tcr, x9 /* * Set the IPS bits in TCR_EL1.