Commit 5de6b467 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'loongarch-fixes-6.9-1' of...

Merge tag 'loongarch-fixes-6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson

Pull LoongArch fixes from Huacai Chen:

 - make {virt, phys, page, pfn} translation work with KFENCE for
   LoongArch (otherwise NVMe and virtio-blk cannot work with KFENCE
   enabled)

 - update dts files for Loongson-2K series to make devices work
   correctly

 - fix a build error

* tag 'loongarch-fixes-6.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson:
  LoongArch: Include linux/sizes.h in addrspace.h to prevent build errors
  LoongArch: Update dts for Loongson-2K2000 to support GMAC/GNET
  LoongArch: Update dts for Loongson-2K2000 to support PCI-MSI
  LoongArch: Update dts for Loongson-2K2000 to support ISA/LPC
  LoongArch: Update dts for Loongson-2K1000 to support ISA/LPC
  LoongArch: Make virt_addr_valid()/__virt_addr_valid() work with KFENCE
  LoongArch: Make {virt, phys, page, pfn} translation work with KFENCE
  mm: Move lowmem_page_address() a little later
parents e1dc191d a07c772f
...@@ -100,6 +100,13 @@ bus@10000000 { ...@@ -100,6 +100,13 @@ bus@10000000 {
#size-cells = <2>; #size-cells = <2>;
dma-coherent; dma-coherent;
isa@18000000 {
compatible = "isa";
#size-cells = <1>;
#address-cells = <2>;
ranges = <1 0x0 0x0 0x18000000 0x4000>;
};
liointc0: interrupt-controller@1fe01400 { liointc0: interrupt-controller@1fe01400 {
compatible = "loongson,liointc-2.0"; compatible = "loongson,liointc-2.0";
reg = <0x0 0x1fe01400 0x0 0x40>, reg = <0x0 0x1fe01400 0x0 0x40>,
......
...@@ -61,12 +61,45 @@ &xhci1 { ...@@ -61,12 +61,45 @@ &xhci1 {
&gmac0 { &gmac0 {
status = "okay"; status = "okay";
phy-mode = "gmii";
phy-handle = <&phy0>;
mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy0: ethernet-phy@0 {
reg = <2>;
};
};
}; };
&gmac1 { &gmac1 {
status = "okay"; status = "okay";
phy-mode = "gmii";
phy-handle = <&phy1>;
mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy1: ethernet-phy@1 {
reg = <2>;
};
};
}; };
&gmac2 { &gmac2 {
status = "okay"; status = "okay";
phy-mode = "rgmii";
phy-handle = <&phy2>;
mdio {
compatible = "snps,dwmac-mdio";
#address-cells = <1>;
#size-cells = <0>;
phy2: ethernet-phy@2 {
reg = <0>;
};
};
}; };
...@@ -51,6 +51,13 @@ bus@10000000 { ...@@ -51,6 +51,13 @@ bus@10000000 {
#address-cells = <2>; #address-cells = <2>;
#size-cells = <2>; #size-cells = <2>;
isa@18400000 {
compatible = "isa";
#size-cells = <1>;
#address-cells = <2>;
ranges = <1 0x0 0x0 0x18400000 0x4000>;
};
pmc: power-management@100d0000 { pmc: power-management@100d0000 {
compatible = "loongson,ls2k2000-pmc", "loongson,ls2k0500-pmc", "syscon"; compatible = "loongson,ls2k2000-pmc", "loongson,ls2k0500-pmc", "syscon";
reg = <0x0 0x100d0000 0x0 0x58>; reg = <0x0 0x100d0000 0x0 0x58>;
...@@ -109,6 +116,8 @@ pic: interrupt-controller@10000000 { ...@@ -109,6 +116,8 @@ pic: interrupt-controller@10000000 {
msi: msi-controller@1fe01140 { msi: msi-controller@1fe01140 {
compatible = "loongson,pch-msi-1.0"; compatible = "loongson,pch-msi-1.0";
reg = <0x0 0x1fe01140 0x0 0x8>; reg = <0x0 0x1fe01140 0x0 0x8>;
interrupt-controller;
#interrupt-cells = <1>;
msi-controller; msi-controller;
loongson,msi-base-vec = <64>; loongson,msi-base-vec = <64>;
loongson,msi-num-vecs = <192>; loongson,msi-num-vecs = <192>;
...@@ -140,27 +149,34 @@ pcie@1a000000 { ...@@ -140,27 +149,34 @@ pcie@1a000000 {
#address-cells = <3>; #address-cells = <3>;
#size-cells = <2>; #size-cells = <2>;
device_type = "pci"; device_type = "pci";
msi-parent = <&msi>;
bus-range = <0x0 0xff>; bus-range = <0x0 0xff>;
ranges = <0x01000000 0x0 0x00008000 0x0 0x18400000 0x0 0x00008000>, ranges = <0x01000000 0x0 0x00008000 0x0 0x18408000 0x0 0x00008000>,
<0x02000000 0x0 0x60000000 0x0 0x60000000 0x0 0x20000000>; <0x02000000 0x0 0x60000000 0x0 0x60000000 0x0 0x20000000>;
gmac0: ethernet@3,0 { gmac0: ethernet@3,0 {
reg = <0x1800 0x0 0x0 0x0 0x0>; reg = <0x1800 0x0 0x0 0x0 0x0>;
interrupts = <12 IRQ_TYPE_LEVEL_HIGH>; interrupts = <12 IRQ_TYPE_LEVEL_HIGH>,
<13 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&pic>; interrupt-parent = <&pic>;
status = "disabled"; status = "disabled";
}; };
gmac1: ethernet@3,1 { gmac1: ethernet@3,1 {
reg = <0x1900 0x0 0x0 0x0 0x0>; reg = <0x1900 0x0 0x0 0x0 0x0>;
interrupts = <14 IRQ_TYPE_LEVEL_HIGH>; interrupts = <14 IRQ_TYPE_LEVEL_HIGH>,
<15 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&pic>; interrupt-parent = <&pic>;
status = "disabled"; status = "disabled";
}; };
gmac2: ethernet@3,2 { gmac2: ethernet@3,2 {
reg = <0x1a00 0x0 0x0 0x0 0x0>; reg = <0x1a00 0x0 0x0 0x0 0x0>;
interrupts = <17 IRQ_TYPE_LEVEL_HIGH>; interrupts = <17 IRQ_TYPE_LEVEL_HIGH>,
<18 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "macirq", "eth_lpi";
interrupt-parent = <&pic>; interrupt-parent = <&pic>;
status = "disabled"; status = "disabled";
}; };
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define _ASM_ADDRSPACE_H #define _ASM_ADDRSPACE_H
#include <linux/const.h> #include <linux/const.h>
#include <linux/sizes.h>
#include <asm/loongarch.h> #include <asm/loongarch.h>
......
...@@ -14,11 +14,6 @@ ...@@ -14,11 +14,6 @@
#include <asm/pgtable-bits.h> #include <asm/pgtable-bits.h>
#include <asm/string.h> #include <asm/string.h>
/*
* Change "struct page" to physical address.
*/
#define page_to_phys(page) ((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT)
extern void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size); extern void __init __iomem *early_ioremap(u64 phys_addr, unsigned long size);
extern void __init early_iounmap(void __iomem *addr, unsigned long size); extern void __init early_iounmap(void __iomem *addr, unsigned long size);
...@@ -73,6 +68,21 @@ extern void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t ...@@ -73,6 +68,21 @@ extern void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t
#define __io_aw() mmiowb() #define __io_aw() mmiowb()
#ifdef CONFIG_KFENCE
#define virt_to_phys(kaddr) \
({ \
(likely((unsigned long)kaddr < vm_map_base)) ? __pa((unsigned long)kaddr) : \
page_to_phys(tlb_virt_to_page((unsigned long)kaddr)) + offset_in_page((unsigned long)kaddr);\
})
#define phys_to_virt(paddr) \
({ \
extern char *__kfence_pool; \
(unlikely(__kfence_pool == NULL)) ? __va((unsigned long)paddr) : \
page_address(phys_to_page((unsigned long)paddr)) + offset_in_page((unsigned long)paddr);\
})
#endif
#include <asm-generic/io.h> #include <asm-generic/io.h>
#define ARCH_HAS_VALID_PHYS_ADDR_RANGE #define ARCH_HAS_VALID_PHYS_ADDR_RANGE
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
static inline bool arch_kfence_init_pool(void) static inline bool arch_kfence_init_pool(void)
{ {
int err; int err;
char *kaddr, *vaddr;
char *kfence_pool = __kfence_pool; char *kfence_pool = __kfence_pool;
struct vm_struct *area; struct vm_struct *area;
...@@ -35,6 +36,14 @@ static inline bool arch_kfence_init_pool(void) ...@@ -35,6 +36,14 @@ static inline bool arch_kfence_init_pool(void)
return false; return false;
} }
kaddr = kfence_pool;
vaddr = __kfence_pool;
while (kaddr < kfence_pool + KFENCE_POOL_SIZE) {
set_page_address(virt_to_page(kaddr), vaddr);
kaddr += PAGE_SIZE;
vaddr += PAGE_SIZE;
}
return true; return true;
} }
......
...@@ -78,7 +78,26 @@ typedef struct { unsigned long pgprot; } pgprot_t; ...@@ -78,7 +78,26 @@ typedef struct { unsigned long pgprot; } pgprot_t;
struct page *dmw_virt_to_page(unsigned long kaddr); struct page *dmw_virt_to_page(unsigned long kaddr);
struct page *tlb_virt_to_page(unsigned long kaddr); struct page *tlb_virt_to_page(unsigned long kaddr);
#define virt_to_pfn(kaddr) PFN_DOWN(PHYSADDR(kaddr)) #define pfn_to_phys(pfn) __pfn_to_phys(pfn)
#define phys_to_pfn(paddr) __phys_to_pfn(paddr)
#define page_to_phys(page) pfn_to_phys(page_to_pfn(page))
#define phys_to_page(paddr) pfn_to_page(phys_to_pfn(paddr))
#ifndef CONFIG_KFENCE
#define page_to_virt(page) __va(page_to_phys(page))
#define virt_to_page(kaddr) phys_to_page(__pa(kaddr))
#else
#define WANT_PAGE_VIRTUAL
#define page_to_virt(page) \
({ \
extern char *__kfence_pool; \
(__kfence_pool == NULL) ? __va(page_to_phys(page)) : page_address(page); \
})
#define virt_to_page(kaddr) \ #define virt_to_page(kaddr) \
({ \ ({ \
...@@ -86,6 +105,11 @@ struct page *tlb_virt_to_page(unsigned long kaddr); ...@@ -86,6 +105,11 @@ struct page *tlb_virt_to_page(unsigned long kaddr);
dmw_virt_to_page((unsigned long)kaddr) : tlb_virt_to_page((unsigned long)kaddr);\ dmw_virt_to_page((unsigned long)kaddr) : tlb_virt_to_page((unsigned long)kaddr);\
}) })
#endif
#define pfn_to_virt(pfn) page_to_virt(pfn_to_page(pfn))
#define virt_to_pfn(kaddr) page_to_pfn(virt_to_page(kaddr))
extern int __virt_addr_valid(volatile void *kaddr); extern int __virt_addr_valid(volatile void *kaddr);
#define virt_addr_valid(kaddr) __virt_addr_valid((volatile void *)(kaddr)) #define virt_addr_valid(kaddr) __virt_addr_valid((volatile void *)(kaddr))
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
*/ */
#include <linux/export.h> #include <linux/export.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/kfence.h>
#include <linux/memblock.h> #include <linux/memblock.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/mman.h> #include <linux/mman.h>
...@@ -111,6 +112,9 @@ int __virt_addr_valid(volatile void *kaddr) ...@@ -111,6 +112,9 @@ int __virt_addr_valid(volatile void *kaddr)
{ {
unsigned long vaddr = (unsigned long)kaddr; unsigned long vaddr = (unsigned long)kaddr;
if (is_kfence_address((void *)kaddr))
return 1;
if ((vaddr < PAGE_OFFSET) || (vaddr >= vm_map_base)) if ((vaddr < PAGE_OFFSET) || (vaddr >= vm_map_base))
return 0; return 0;
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
struct page *dmw_virt_to_page(unsigned long kaddr) struct page *dmw_virt_to_page(unsigned long kaddr)
{ {
return pfn_to_page(virt_to_pfn(kaddr)); return phys_to_page(__pa(kaddr));
} }
EXPORT_SYMBOL(dmw_virt_to_page); EXPORT_SYMBOL(dmw_virt_to_page);
struct page *tlb_virt_to_page(unsigned long kaddr) struct page *tlb_virt_to_page(unsigned long kaddr)
{ {
return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr))); return phys_to_page(pfn_to_phys(pte_pfn(*virt_to_kpte(kaddr))));
} }
EXPORT_SYMBOL(tlb_virt_to_page); EXPORT_SYMBOL(tlb_virt_to_page);
......
...@@ -2207,11 +2207,6 @@ static inline int arch_make_folio_accessible(struct folio *folio) ...@@ -2207,11 +2207,6 @@ static inline int arch_make_folio_accessible(struct folio *folio)
*/ */
#include <linux/vmstat.h> #include <linux/vmstat.h>
static __always_inline void *lowmem_page_address(const struct page *page)
{
return page_to_virt(page);
}
#if defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL) #if defined(CONFIG_HIGHMEM) && !defined(WANT_PAGE_VIRTUAL)
#define HASHED_PAGE_VIRTUAL #define HASHED_PAGE_VIRTUAL
#endif #endif
...@@ -2234,6 +2229,11 @@ void set_page_address(struct page *page, void *virtual); ...@@ -2234,6 +2229,11 @@ void set_page_address(struct page *page, void *virtual);
void page_address_init(void); void page_address_init(void);
#endif #endif
static __always_inline void *lowmem_page_address(const struct page *page)
{
return page_to_virt(page);
}
#if !defined(HASHED_PAGE_VIRTUAL) && !defined(WANT_PAGE_VIRTUAL) #if !defined(HASHED_PAGE_VIRTUAL) && !defined(WANT_PAGE_VIRTUAL)
#define page_address(page) lowmem_page_address(page) #define page_address(page) lowmem_page_address(page)
#define set_page_address(page, address) do { } while(0) #define set_page_address(page, address) do { } while(0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment