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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1E3B1C5479D for ; Wed, 11 Jan 2023 04:38:42 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 6C7768E0002; Tue, 10 Jan 2023 23:38:41 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 6773A8E0001; Tue, 10 Jan 2023 23:38:41 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 53EEE8E0002; Tue, 10 Jan 2023 23:38:41 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 44B118E0001 for ; Tue, 10 Jan 2023 23:38:41 -0500 (EST) Received: from smtpin05.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 1FA3716068A for ; Wed, 11 Jan 2023 04:38:41 +0000 (UTC) X-FDA: 80341262442.05.68FB5B1 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf12.hostedemail.com (Postfix) with ESMTP id 22EF340002 for ; Wed, 11 Jan 2023 04:38:38 +0000 (UTC) Authentication-Results: imf12.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf12.hostedemail.com: domain of anshuman.khandual@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=anshuman.khandual@arm.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1673411919; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2qanr2fQxlD3VcUPqhbmqVEldx1pzwFr09UkbKZwG5s=; b=2zBoyL14KipoiTv634Pg253qt0OAqjzIVKge9BsJX2IxkxGlTrOLDQGAOODa988jvyQNcB 54Sq58uN1o3taRRRFUfJdKnX9H0d3zwymOm/IH0a/IGewM9Mwp/m3J1bC9jZotfVCDoUGf 1sb2xliSUh7LxYoWU8YuUczTTdt9KsU= ARC-Authentication-Results: i=1; imf12.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf12.hostedemail.com: domain of anshuman.khandual@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=anshuman.khandual@arm.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1673411919; a=rsa-sha256; cv=none; b=WHMcJguUDuvAgFAmYEQ9exBbgBFodjCx3I3Y7DlXNG6fJiu1xj65rjU3YpAJdJ4eb1K1UD Cp9gADFYnmBE61Z7egbKCl3YZvN563cVTbSs8H+NDt84MGAa8ADRm1mFpI+vFtpQFl+GI+ zC4BGXRte69SbP72GcBvg+3Vs5CoaQM= Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 09A5FFEC; Tue, 10 Jan 2023 20:39:20 -0800 (PST) Received: from [10.162.40.17] (unknown [10.162.40.17]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id CCA9D3F71A; Tue, 10 Jan 2023 20:38:36 -0800 (PST) Message-ID: <026177fa-e9ce-59c1-3e15-0a8b39366716@arm.com> Date: Wed, 11 Jan 2023 10:08:33 +0530 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.2 Subject: Re: [PATCH v3] mm/debug: use valid physical memory for pmd/pud tests Content-Language: en-US To: Frank van der Linden , Andrew Morton , linux-mm@kvack.org References: <20230110181208.1633879-1-fvdl@google.com> From: Anshuman Khandual In-Reply-To: <20230110181208.1633879-1-fvdl@google.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 22EF340002 X-Stat-Signature: y63f57engawnc5sum6pgrxa3odw1wbbg X-HE-Tag: 1673411918-860531 X-HE-Meta: U2FsdGVkX18AI+3whW0PgCjmxpcatXEZscs5NepIj2zQjGZEkT0BYz0U/OrX4R8wygXr1uGJtjtULiGA/OLGhGYcCsD/dzvr9+Gc8ujfAgMdftZ5QWSQM/F9k2oF+jcIVRzRUSsqk7xq9IY6HNLXf7HbpUsx7uK5gu7yWke54CQ+F1b7nuVkePzTmvb2YWvtSGQsYQHkAyRqg0UEqrUsdE5IkNL0/WzXYR6v72Hr87tE/FGYo+cfwY9fmNxkCqdmrhCYkUmOTHXpSGb0JRalXO0z9FluHNx6rTowC1ZpYBLWKLaAnIhCBEyFPbaCJaULnRq9g5VwIdv67PlSW4smuFHrortvljQvLyF9C5VCPLjCbAXkLIE5aZEmb95EsCZRCdLCv82WpQzqk5QWmo6NnebUqTRwuOUCjgfoRYsrznIXPRJKu4pAZFS0Rw5ROLW+7SG400G0Iy9B/t0CUKIKnbzE7piMXCpxO/yhG4j8lW6JBt1SXtatBn1/rnNzj7dAnlIIeZ/GEcEiDrm7r1pL0WUrcboQMpN6IyHBnMFxuwTV45Rf/wtqtjE/xnUMmAzQ8rAx86cQ21xVz6BejjStFq3eS4Y7EMfoYULQMviz3oE7NC2skiJqlcCDviYxALDQAHllk6nryEUuDyR8vzKEZfM7V3+hQoel+mJvgVnVhsY5MRCqwefqOtuPEko3wEBM3sy4ayPZL4M1IEmeI59w7MXgc2268TOxeEtZfRy2vERTJAG9yb49Fwqr+Rc6fx0dLxZyToZPsOFFMUyl2I0p+sG66iTIvba+1FwgPU1eUs1ZC9u9VGw7YPcdooJ4zbi+5OGY8FBUlcc= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On 1/10/23 23:42, Frank van der Linden wrote: > The page table debug tests need a physical address to validate > low-level page table manipulation with. The memory at this address > is not actually touched, it just encoded in the page table entries > at various levels during the tests only. > > Since the memory is not used, the code just picks the physical > address of the start_kernel symbol. This value is then truncated > to get a properly aligned address that is to be used for various > tests. Because of the truncation, the address might not actually > exist, or might not describe a complete huge page. That's not a > problem for most tests, but the arch-specific code may check > for attribute validity and consistency. The x86 version of > {pud,pmd}_set_huge actually validates the MTRRs for the PMD/PUD > range. This may fail with an address derived from start_kernel, > depending on where the kernel was loaded and what the physical > memory layout of the system is. This then leads to false negatives > for the {pud,pmd}_set_huge tests. > > Avoid this by finding a properly aligned memory range that exists > and is usable. If such a range is not found, skip the tests that > needed it. > > Fixes: 399145f9eb6c ("mm/debug: add tests validating architecture page table helpers") > Cc: Anshuman Khandual Reviewed-by: Anshuman Khandual > Signed-off-by: Frank van der Linden > --- > mm/debug_vm_pgtable.c | 102 ++++++++++++++++++++++++++++++++++-------- > 1 file changed, 83 insertions(+), 19 deletions(-) > > diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c > index c631ade3f1d2..bb3328f46126 100644 > --- a/mm/debug_vm_pgtable.c > +++ b/mm/debug_vm_pgtable.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -80,6 +81,7 @@ struct pgtable_debug_args { > unsigned long pmd_pfn; > unsigned long pte_pfn; > > + unsigned long fixed_alignment; > unsigned long fixed_pgd_pfn; > unsigned long fixed_p4d_pfn; > unsigned long fixed_pud_pfn; > @@ -430,7 +432,8 @@ static void __init pmd_huge_tests(struct pgtable_debug_args *args) > { > pmd_t pmd; > > - if (!arch_vmap_pmd_supported(args->page_prot)) > + if (!arch_vmap_pmd_supported(args->page_prot) || > + args->fixed_alignment < PMD_SIZE) > return; > > pr_debug("Validating PMD huge\n"); > @@ -449,7 +452,8 @@ static void __init pud_huge_tests(struct pgtable_debug_args *args) > { > pud_t pud; > > - if (!arch_vmap_pud_supported(args->page_prot)) > + if (!arch_vmap_pud_supported(args->page_prot) || > + args->fixed_alignment < PUD_SIZE) > return; > > pr_debug("Validating PUD huge\n"); > @@ -1077,10 +1081,85 @@ debug_vm_pgtable_alloc_huge_page(struct pgtable_debug_args *args, int order) > return page; > } > > +/* > + * Check if a physical memory range described by contains > + * an area that is of size psize, and aligned to psize. > + * > + * Don't use address 0, an all-zeroes physical address might mask bugs, and > + * it's not used on x86. > + */ > +static void __init phys_align_check(phys_addr_t pstart, > + phys_addr_t pend, unsigned long psize, > + phys_addr_t *physp, unsigned long *alignp) > +{ > + phys_addr_t aligned_start, aligned_end; > + > + if (pstart == 0) > + pstart = PAGE_SIZE; > + > + aligned_start = ALIGN(pstart, psize); > + aligned_end = aligned_start + psize; > + > + if (aligned_end > aligned_start && aligned_end <= pend) { > + *alignp = psize; > + *physp = aligned_start; > + } > +} > + > +static void __init init_fixed_pfns(struct pgtable_debug_args *args) > +{ > + u64 idx; > + phys_addr_t phys, pstart, pend; > + > + /* > + * Initialize the fixed pfns. To do this, try to find a > + * valid physical range, preferably aligned to PUD_SIZE, > + * but settling for aligned to PMD_SIZE as a fallback. If > + * neither of those is found, use the physical address of > + * the start_kernel symbol. > + * > + * The memory doesn't need to be allocated, it just needs to exist > + * as usable memory. It won't be touched. > + * > + * The alignment is recorded, and can be checked to see if we > + * can run the tests that require an actual valid physical > + * address range on some architectures ({pmd,pud}_huge_test > + * on x86). > + */ > + > + phys = __pa_symbol(&start_kernel); > + args->fixed_alignment = PAGE_SIZE; > + > + for_each_mem_range(idx, &pstart, &pend) { > + /* First check for a PUD-aligned area */ > + phys_align_check(pstart, pend, PUD_SIZE, &phys, > + &args->fixed_alignment); > + > + /* If a PUD-aligned area is found, we're done */ > + if (args->fixed_alignment == PUD_SIZE) > + break; > + > + /* > + * If no PMD-aligned area found yet, check for one, > + * but continue the loop to look for a PUD-aligned area. > + */ > + if (args->fixed_alignment < PMD_SIZE) > + phys_align_check(pstart, pend, PMD_SIZE, &phys, > + &args->fixed_alignment); > + } > + > + args->fixed_pgd_pfn = __phys_to_pfn(phys & PGDIR_MASK); > + args->fixed_p4d_pfn = __phys_to_pfn(phys & P4D_MASK); > + args->fixed_pud_pfn = __phys_to_pfn(phys & PUD_MASK); > + args->fixed_pmd_pfn = __phys_to_pfn(phys & PMD_MASK); > + args->fixed_pte_pfn = __phys_to_pfn(phys & PAGE_MASK); > + WARN_ON(!pfn_valid(args->fixed_pte_pfn)); > +} > + > + > static int __init init_args(struct pgtable_debug_args *args) > { > struct page *page = NULL; > - phys_addr_t phys; > int ret = 0; > > /* > @@ -1160,22 +1239,7 @@ static int __init init_args(struct pgtable_debug_args *args) > args->start_ptep = pmd_pgtable(READ_ONCE(*args->pmdp)); > WARN_ON(!args->start_ptep); > > - /* > - * PFN for mapping at PTE level is determined from a standard kernel > - * text symbol. But pfns for higher page table levels are derived by > - * masking lower bits of this real pfn. These derived pfns might not > - * exist on the platform but that does not really matter as pfn_pxx() > - * helpers will still create appropriate entries for the test. This > - * helps avoid large memory block allocations to be used for mapping > - * at higher page table levels in some of the tests. > - */ > - phys = __pa_symbol(&start_kernel); > - args->fixed_pgd_pfn = __phys_to_pfn(phys & PGDIR_MASK); > - args->fixed_p4d_pfn = __phys_to_pfn(phys & P4D_MASK); > - args->fixed_pud_pfn = __phys_to_pfn(phys & PUD_MASK); > - args->fixed_pmd_pfn = __phys_to_pfn(phys & PMD_MASK); > - args->fixed_pte_pfn = __phys_to_pfn(phys & PAGE_MASK); > - WARN_ON(!pfn_valid(args->fixed_pte_pfn)); > + init_fixed_pfns(args); > > /* > * Allocate (huge) pages because some of the tests need to access