arm64: remove the hardcode about PCI address checking

Copy name in find_next_iomem_res() for checking the PCI
address.

Remove the bool check for VM which does not has the ALTRA pci device.

Signed-off-by: Huang Shijie <shijie@os.amperecomputing.com>
Signed-off-by: John Gong <john.gong@amperecomputing.com>
This commit is contained in:
Huang Shijie 2022-04-08 20:43:33 +00:00 committed by Jianping Liu
parent 4fae27e32f
commit b12f0f36ec
5 changed files with 55 additions and 14 deletions

View File

@ -578,6 +578,7 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr,
#ifdef CONFIG_ALTRA_ERRATUM_82288
extern bool have_altra_erratum_82288;
extern bool range_is_pci(phys_addr_t, size_t);
#endif
static inline pte_t pte_mkspecial(pte_t pte)
@ -586,12 +587,9 @@ static inline pte_t pte_mkspecial(pte_t pte)
phys_addr_t phys = __pte_to_phys(pte);
pgprot_t prot = __pgprot(pte_val(pte) & ~PTE_ADDR_MASK);
if (unlikely(have_altra_erratum_82288) &&
(phys < 0x80000000 ||
(phys >= 0x200000000000 && phys < 0x400000000000) ||
(phys >= 0x600000000000 && phys < 0x800000000000))) {
if (range_is_pci(phys, PAGE_SIZE)) {
pte = __pte(__phys_to_pte_val(phys) | pgprot_val(pgprot_device(prot)));
}
}
#endif
return set_pte_bit(pte, __pgprot(PTE_SPECIAL));

View File

@ -2,6 +2,7 @@
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/pci.h>
void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size,
unsigned long prot)

View File

@ -2731,4 +2731,8 @@ void pci_uevent_ers(struct pci_dev *pdev, enum pci_ers_result err_type);
WARN_ONCE(condition, "%s %s: " fmt, \
dev_driver_string(&(pdev)->dev), pci_name(pdev), ##arg)
#ifdef CONFIG_ALTRA_ERRATUM_82288
extern bool range_is_pci(phys_addr_t phys_addr, size_t size);
#endif
#endif /* LINUX_PCI_H */

View File

@ -364,6 +364,7 @@ static int find_next_iomem_res(resource_size_t start, resource_size_t end,
.flags = p->flags,
.desc = p->desc,
.parent = p->parent,
.name = p->name,
};
}
@ -489,6 +490,48 @@ int __weak page_is_ram(unsigned long pfn)
}
EXPORT_SYMBOL_GPL(page_is_ram);
#ifdef CONFIG_ALTRA_ERRATUM_82288
/* Return 0 on success, else return 1 */
static int pci_addr_check(struct resource *r, void *p)
{
if (!r->name)
return 1;
if (strlen(r->name) <= 2)
return 1;
if (memcmp(r->name, "PCI", 3))
return 1;
/* Success */
return 0;
}
bool range_is_pci(phys_addr_t phys_addr, size_t size)
{
u64 start, end;
int ret;
start = phys_addr;
end = phys_addr + size;
/* Check the 32bit */
ret = walk_iomem_res_desc(IORES_DESC_NONE, IORESOURCE_MEM,
start, end, NULL, pci_addr_check);
if (!ret)
return true;
/* Check the 64bit */
ret = walk_iomem_res_desc(IORES_DESC_NONE, IORESOURCE_MEM_64,
start, end, NULL, pci_addr_check);
if (!ret)
return true;
return false;
}
EXPORT_SYMBOL_GPL(range_is_pci);
#endif
static int __region_intersects(struct resource *parent, resource_size_t start,
size_t size, unsigned long flags,
unsigned long desc)

View File

@ -9,20 +9,13 @@
#include <linux/vmalloc.h>
#include <linux/mm.h>
#include <linux/io.h>
#include <linux/pci.h>
#include <linux/export.h>
#include <linux/ioremap.h>
#ifdef CONFIG_ALTRA_ERRATUM_82288
bool have_altra_erratum_82288 __read_mostly;
EXPORT_SYMBOL(have_altra_erratum_82288);
static bool is_altra_pci(phys_addr_t phys_addr, size_t size)
{
phys_addr_t end = phys_addr + size;
return (phys_addr < 0x80000000 ||
(end > 0x200000000000 && phys_addr < 0x400000000000) ||
(end > 0x600000000000 && phys_addr < 0x800000000000));
}
#endif
void __iomem *generic_ioremap_prot(phys_addr_t phys_addr, size_t size,
@ -53,8 +46,10 @@ void __iomem *generic_ioremap_prot(phys_addr_t phys_addr, size_t size,
vaddr = (unsigned long)area->addr;
area->phys_addr = phys_addr;
#ifdef CONFIG_ALTRA_ERRATUM_82288
if (unlikely(have_altra_erratum_82288 && is_altra_pci(phys_addr, size)))
if ((pgprot_val(prot) != pgprot_val(pgprot_device(prot))) &&
range_is_pci(phys_addr, size)) {
prot = pgprot_device(prot);
}
#endif
if (ioremap_page_range(vaddr, vaddr + size, phys_addr, prot)) {
free_vm_area(area);