Skip to content

Commit

Permalink
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/arm64/linux

Pull arm64 fix from Will Deacon:
 "We received a report this week that the generic version of
  pfn_valid(), which we switched to this merge window in 16c9afc
  ("arm64/mm: drop HAVE_ARCH_PFN_VALID"), interacts badly with
  dma_map_resource() due to the following check:

        /* Don't allow RAM to be mapped */
        if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
                return DMA_MAPPING_ERROR;

  Since the ongoing saga to determine the semantics of pfn_valid() is
  unlikely to be resolved this week (does it indicate valid memory, or
  just the presence of a struct page, or whether that struct page has
  been initialised?), just revert back to our old version of pfn_valid()
  for 5.14.

  Summary:

   - Fix dma_map_resource() by reverting back to old pfn_valid() code"

* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
  Partially revert "arm64/mm: drop HAVE_ARCH_PFN_VALID"
  • Loading branch information
Linus Torvalds committed Aug 26, 2021
2 parents 97d8cc2 + 3eb9cdf commit 1a6d80f
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 0 deletions.
1 change: 1 addition & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ config ARM64
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
select HAVE_ARCH_PFN_VALID
select HAVE_ARCH_PREL32_RELOCATIONS
select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET
select HAVE_ARCH_SECCOMP_FILTER
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/include/asm/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void tag_clear_highpage(struct page *to);

typedef struct page *pgtable_t;

int pfn_valid(unsigned long pfn);
int pfn_is_map_memory(unsigned long pfn);

#include <asm/memory.h>
Expand Down
37 changes: 37 additions & 0 deletions arch/arm64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,43 @@ static void __init zone_sizes_init(unsigned long min, unsigned long max)
free_area_init(max_zone_pfns);
}

int pfn_valid(unsigned long pfn)
{
phys_addr_t addr = PFN_PHYS(pfn);
struct mem_section *ms;

/*
* Ensure the upper PAGE_SHIFT bits are clear in the
* pfn. Else it might lead to false positives when
* some of the upper bits are set, but the lower bits
* match a valid pfn.
*/
if (PHYS_PFN(addr) != pfn)
return 0;

if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
return 0;

ms = __pfn_to_section(pfn);
if (!valid_section(ms))
return 0;

/*
* ZONE_DEVICE memory does not have the memblock entries.
* memblock_is_map_memory() check for ZONE_DEVICE based
* addresses will always fail. Even the normal hotplugged
* memory will never have MEMBLOCK_NOMAP flag set in their
* memblock entries. Skip memblock search for all non early
* memory sections covering all of hotplug memory including
* both normal and ZONE_DEVICE based.
*/
if (!early_section(ms))
return pfn_section_valid(ms, pfn);

return memblock_is_memory(addr);
}
EXPORT_SYMBOL(pfn_valid);

int pfn_is_map_memory(unsigned long pfn)
{
phys_addr_t addr = PFN_PHYS(pfn);
Expand Down

0 comments on commit 1a6d80f

Please sign in to comment.