Commit 7a934f4b authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'riscv-for-linus-6.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fixes from Palmer Dabbelt:

 - A fix for a missing fence when generating the NOMMU sigreturn
   trampoline

 - A set of fixes for early DTB handling of reserved memory nodes

* tag 'riscv-for-linus-6.3-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  riscv: No need to relocate the dtb as it lies in the fixmap region
  riscv: Do not set initial_boot_params to the linear address of the dtb
  riscv: Move early dtb mapping into the fixmap region
  riscv: add icache flush for nommu sigreturn trampoline
parents 95abc817 1b50f956
...@@ -47,7 +47,7 @@ RISC-V Linux Kernel SV39 ...@@ -47,7 +47,7 @@ RISC-V Linux Kernel SV39
| Kernel-space virtual memory, shared between all processes: | Kernel-space virtual memory, shared between all processes:
____________________________________________________________|___________________________________________________________ ____________________________________________________________|___________________________________________________________
| | | | | | | |
ffffffc6fee00000 | -228 GB | ffffffc6feffffff | 2 MB | fixmap ffffffc6fea00000 | -228 GB | ffffffc6feffffff | 6 MB | fixmap
ffffffc6ff000000 | -228 GB | ffffffc6ffffffff | 16 MB | PCI io ffffffc6ff000000 | -228 GB | ffffffc6ffffffff | 16 MB | PCI io
ffffffc700000000 | -228 GB | ffffffc7ffffffff | 4 GB | vmemmap ffffffc700000000 | -228 GB | ffffffc7ffffffff | 4 GB | vmemmap
ffffffc800000000 | -224 GB | ffffffd7ffffffff | 64 GB | vmalloc/ioremap space ffffffc800000000 | -224 GB | ffffffd7ffffffff | 64 GB | vmalloc/ioremap space
...@@ -83,7 +83,7 @@ RISC-V Linux Kernel SV48 ...@@ -83,7 +83,7 @@ RISC-V Linux Kernel SV48
| Kernel-space virtual memory, shared between all processes: | Kernel-space virtual memory, shared between all processes:
____________________________________________________________|___________________________________________________________ ____________________________________________________________|___________________________________________________________
| | | | | | | |
ffff8d7ffee00000 | -114.5 TB | ffff8d7ffeffffff | 2 MB | fixmap ffff8d7ffea00000 | -114.5 TB | ffff8d7ffeffffff | 6 MB | fixmap
ffff8d7fff000000 | -114.5 TB | ffff8d7fffffffff | 16 MB | PCI io ffff8d7fff000000 | -114.5 TB | ffff8d7fffffffff | 16 MB | PCI io
ffff8d8000000000 | -114.5 TB | ffff8f7fffffffff | 2 TB | vmemmap ffff8d8000000000 | -114.5 TB | ffff8f7fffffffff | 2 TB | vmemmap
ffff8f8000000000 | -112.5 TB | ffffaf7fffffffff | 32 TB | vmalloc/ioremap space ffff8f8000000000 | -112.5 TB | ffffaf7fffffffff | 32 TB | vmalloc/ioremap space
...@@ -119,7 +119,7 @@ RISC-V Linux Kernel SV57 ...@@ -119,7 +119,7 @@ RISC-V Linux Kernel SV57
| Kernel-space virtual memory, shared between all processes: | Kernel-space virtual memory, shared between all processes:
____________________________________________________________|___________________________________________________________ ____________________________________________________________|___________________________________________________________
| | | | | | | |
ff1bfffffee00000 | -57 PB | ff1bfffffeffffff | 2 MB | fixmap ff1bfffffea00000 | -57 PB | ff1bfffffeffffff | 6 MB | fixmap
ff1bffffff000000 | -57 PB | ff1bffffffffffff | 16 MB | PCI io ff1bffffff000000 | -57 PB | ff1bffffffffffff | 16 MB | PCI io
ff1c000000000000 | -57 PB | ff1fffffffffffff | 1 PB | vmemmap ff1c000000000000 | -57 PB | ff1fffffffffffff | 1 PB | vmemmap
ff20000000000000 | -56 PB | ff5fffffffffffff | 16 PB | vmalloc/ioremap space ff20000000000000 | -56 PB | ff5fffffffffffff | 16 PB | vmalloc/ioremap space
......
...@@ -22,6 +22,14 @@ ...@@ -22,6 +22,14 @@
*/ */
enum fixed_addresses { enum fixed_addresses {
FIX_HOLE, FIX_HOLE,
/*
* The fdt fixmap mapping must be PMD aligned and will be mapped
* using PMD entries in fixmap_pmd in 64-bit and a PGD entry in 32-bit.
*/
FIX_FDT_END,
FIX_FDT = FIX_FDT_END + FIX_FDT_SIZE / PAGE_SIZE - 1,
/* Below fixmaps will be mapped using fixmap_pte */
FIX_PTE, FIX_PTE,
FIX_PMD, FIX_PMD,
FIX_PUD, FIX_PUD,
......
...@@ -87,9 +87,13 @@ ...@@ -87,9 +87,13 @@
#define FIXADDR_TOP PCI_IO_START #define FIXADDR_TOP PCI_IO_START
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
#define FIXADDR_SIZE PMD_SIZE #define MAX_FDT_SIZE PMD_SIZE
#define FIX_FDT_SIZE (MAX_FDT_SIZE + SZ_2M)
#define FIXADDR_SIZE (PMD_SIZE + FIX_FDT_SIZE)
#else #else
#define FIXADDR_SIZE PGDIR_SIZE #define MAX_FDT_SIZE PGDIR_SIZE
#define FIX_FDT_SIZE MAX_FDT_SIZE
#define FIXADDR_SIZE (PGDIR_SIZE + FIX_FDT_SIZE)
#endif #endif
#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) #define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE)
......
...@@ -278,12 +278,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -278,12 +278,8 @@ void __init setup_arch(char **cmdline_p)
#if IS_ENABLED(CONFIG_BUILTIN_DTB) #if IS_ENABLED(CONFIG_BUILTIN_DTB)
unflatten_and_copy_device_tree(); unflatten_and_copy_device_tree();
#else #else
if (early_init_dt_verify(__va(XIP_FIXUP(dtb_early_pa)))) unflatten_device_tree();
unflatten_device_tree();
else
pr_err("No DTB found in kernel mappings\n");
#endif #endif
early_init_fdt_scan_reserved_mem();
misc_mem_init(); misc_mem_init();
init_resources(); init_resources();
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <asm/signal32.h> #include <asm/signal32.h>
#include <asm/switch_to.h> #include <asm/switch_to.h>
#include <asm/csr.h> #include <asm/csr.h>
#include <asm/cacheflush.h>
extern u32 __user_rt_sigreturn[2]; extern u32 __user_rt_sigreturn[2];
...@@ -181,6 +182,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, ...@@ -181,6 +182,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
{ {
struct rt_sigframe __user *frame; struct rt_sigframe __user *frame;
long err = 0; long err = 0;
unsigned long __maybe_unused addr;
frame = get_sigframe(ksig, regs, sizeof(*frame)); frame = get_sigframe(ksig, regs, sizeof(*frame));
if (!access_ok(frame, sizeof(*frame))) if (!access_ok(frame, sizeof(*frame)))
...@@ -209,7 +211,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, ...@@ -209,7 +211,12 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn, if (copy_to_user(&frame->sigreturn_code, __user_rt_sigreturn,
sizeof(frame->sigreturn_code))) sizeof(frame->sigreturn_code)))
return -EFAULT; return -EFAULT;
regs->ra = (unsigned long)&frame->sigreturn_code;
addr = (unsigned long)&frame->sigreturn_code;
/* Make sure the two instructions are pushed to icache. */
flush_icache_range(addr, addr + sizeof(frame->sigreturn_code));
regs->ra = addr;
#endif /* CONFIG_MMU */ #endif /* CONFIG_MMU */
/* /*
......
...@@ -57,7 +57,6 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] ...@@ -57,7 +57,6 @@ unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)]
EXPORT_SYMBOL(empty_zero_page); EXPORT_SYMBOL(empty_zero_page);
extern char _start[]; extern char _start[];
#define DTB_EARLY_BASE_VA PGDIR_SIZE
void *_dtb_early_va __initdata; void *_dtb_early_va __initdata;
uintptr_t _dtb_early_pa __initdata; uintptr_t _dtb_early_pa __initdata;
...@@ -236,31 +235,22 @@ static void __init setup_bootmem(void) ...@@ -236,31 +235,22 @@ static void __init setup_bootmem(void)
set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET); set_max_mapnr(max_low_pfn - ARCH_PFN_OFFSET);
reserve_initrd_mem(); reserve_initrd_mem();
/*
* No allocation should be done before reserving the memory as defined
* in the device tree, otherwise the allocation could end up in a
* reserved region.
*/
early_init_fdt_scan_reserved_mem();
/* /*
* If DTB is built in, no need to reserve its memblock. * If DTB is built in, no need to reserve its memblock.
* Otherwise, do reserve it but avoid using * Otherwise, do reserve it but avoid using
* early_init_fdt_reserve_self() since __pa() does * early_init_fdt_reserve_self() since __pa() does
* not work for DTB pointers that are fixmap addresses * not work for DTB pointers that are fixmap addresses
*/ */
if (!IS_ENABLED(CONFIG_BUILTIN_DTB)) { if (!IS_ENABLED(CONFIG_BUILTIN_DTB))
/* memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
* In case the DTB is not located in a memory region we won't
* be able to locate it later on via the linear mapping and
* get a segfault when accessing it via __va(dtb_early_pa).
* To avoid this situation copy DTB to a memory region.
* Note that memblock_phys_alloc will also reserve DTB region.
*/
if (!memblock_is_memory(dtb_early_pa)) {
size_t fdt_size = fdt_totalsize(dtb_early_va);
phys_addr_t new_dtb_early_pa = memblock_phys_alloc(fdt_size, PAGE_SIZE);
void *new_dtb_early_va = early_memremap(new_dtb_early_pa, fdt_size);
memcpy(new_dtb_early_va, dtb_early_va, fdt_size);
early_memunmap(new_dtb_early_va, fdt_size);
_dtb_early_pa = new_dtb_early_pa;
} else
memblock_reserve(dtb_early_pa, fdt_totalsize(dtb_early_va));
}
dma_contiguous_reserve(dma32_phys_limit); dma_contiguous_reserve(dma32_phys_limit);
if (IS_ENABLED(CONFIG_64BIT)) if (IS_ENABLED(CONFIG_64BIT))
...@@ -279,9 +269,6 @@ pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss; ...@@ -279,9 +269,6 @@ pgd_t trampoline_pg_dir[PTRS_PER_PGD] __page_aligned_bss;
static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss; static pte_t fixmap_pte[PTRS_PER_PTE] __page_aligned_bss;
pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE); pgd_t early_pg_dir[PTRS_PER_PGD] __initdata __aligned(PAGE_SIZE);
static p4d_t __maybe_unused early_dtb_p4d[PTRS_PER_P4D] __initdata __aligned(PAGE_SIZE);
static pud_t __maybe_unused early_dtb_pud[PTRS_PER_PUD] __initdata __aligned(PAGE_SIZE);
static pmd_t __maybe_unused early_dtb_pmd[PTRS_PER_PMD] __initdata __aligned(PAGE_SIZE);
#ifdef CONFIG_XIP_KERNEL #ifdef CONFIG_XIP_KERNEL
#define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops)) #define pt_ops (*(struct pt_alloc_ops *)XIP_FIXUP(&pt_ops))
...@@ -626,9 +613,6 @@ static void __init create_p4d_mapping(p4d_t *p4dp, ...@@ -626,9 +613,6 @@ static void __init create_p4d_mapping(p4d_t *p4dp,
#define trampoline_pgd_next (pgtable_l5_enabled ? \ #define trampoline_pgd_next (pgtable_l5_enabled ? \
(uintptr_t)trampoline_p4d : (pgtable_l4_enabled ? \ (uintptr_t)trampoline_p4d : (pgtable_l4_enabled ? \
(uintptr_t)trampoline_pud : (uintptr_t)trampoline_pmd)) (uintptr_t)trampoline_pud : (uintptr_t)trampoline_pmd))
#define early_dtb_pgd_next (pgtable_l5_enabled ? \
(uintptr_t)early_dtb_p4d : (pgtable_l4_enabled ? \
(uintptr_t)early_dtb_pud : (uintptr_t)early_dtb_pmd))
#else #else
#define pgd_next_t pte_t #define pgd_next_t pte_t
#define alloc_pgd_next(__va) pt_ops.alloc_pte(__va) #define alloc_pgd_next(__va) pt_ops.alloc_pte(__va)
...@@ -636,7 +620,6 @@ static void __init create_p4d_mapping(p4d_t *p4dp, ...@@ -636,7 +620,6 @@ static void __init create_p4d_mapping(p4d_t *p4dp,
#define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \ #define create_pgd_next_mapping(__nextp, __va, __pa, __sz, __prot) \
create_pte_mapping(__nextp, __va, __pa, __sz, __prot) create_pte_mapping(__nextp, __va, __pa, __sz, __prot)
#define fixmap_pgd_next ((uintptr_t)fixmap_pte) #define fixmap_pgd_next ((uintptr_t)fixmap_pte)
#define early_dtb_pgd_next ((uintptr_t)early_dtb_pmd)
#define create_p4d_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0) #define create_p4d_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
#define create_pud_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0) #define create_pud_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
#define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0) #define create_pmd_mapping(__pmdp, __va, __pa, __sz, __prot) do {} while(0)
...@@ -860,32 +843,28 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early) ...@@ -860,32 +843,28 @@ static void __init create_kernel_page_table(pgd_t *pgdir, bool early)
* this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR * this means 2 PMD entries whereas for 32-bit kernel, this is only 1 PGDIR
* entry. * entry.
*/ */
static void __init create_fdt_early_page_table(pgd_t *pgdir, uintptr_t dtb_pa) static void __init create_fdt_early_page_table(pgd_t *pgdir,
uintptr_t fix_fdt_va,
uintptr_t dtb_pa)
{ {
#ifndef CONFIG_BUILTIN_DTB
uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1); uintptr_t pa = dtb_pa & ~(PMD_SIZE - 1);
create_pgd_mapping(early_pg_dir, DTB_EARLY_BASE_VA, #ifndef CONFIG_BUILTIN_DTB
IS_ENABLED(CONFIG_64BIT) ? early_dtb_pgd_next : pa, /* Make sure the fdt fixmap address is always aligned on PMD size */
PGDIR_SIZE, BUILD_BUG_ON(FIX_FDT % (PMD_SIZE / PAGE_SIZE));
IS_ENABLED(CONFIG_64BIT) ? PAGE_TABLE : PAGE_KERNEL);
if (pgtable_l5_enabled)
create_p4d_mapping(early_dtb_p4d, DTB_EARLY_BASE_VA,
(uintptr_t)early_dtb_pud, P4D_SIZE, PAGE_TABLE);
if (pgtable_l4_enabled)
create_pud_mapping(early_dtb_pud, DTB_EARLY_BASE_VA,
(uintptr_t)early_dtb_pmd, PUD_SIZE, PAGE_TABLE);
if (IS_ENABLED(CONFIG_64BIT)) { /* In 32-bit only, the fdt lies in its own PGD */
create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA, if (!IS_ENABLED(CONFIG_64BIT)) {
create_pgd_mapping(early_pg_dir, fix_fdt_va,
pa, MAX_FDT_SIZE, PAGE_KERNEL);
} else {
create_pmd_mapping(fixmap_pmd, fix_fdt_va,
pa, PMD_SIZE, PAGE_KERNEL); pa, PMD_SIZE, PAGE_KERNEL);
create_pmd_mapping(early_dtb_pmd, DTB_EARLY_BASE_VA + PMD_SIZE, create_pmd_mapping(fixmap_pmd, fix_fdt_va + PMD_SIZE,
pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL); pa + PMD_SIZE, PMD_SIZE, PAGE_KERNEL);
} }
dtb_early_va = (void *)DTB_EARLY_BASE_VA + (dtb_pa & (PMD_SIZE - 1)); dtb_early_va = (void *)fix_fdt_va + (dtb_pa & (PMD_SIZE - 1));
#else #else
/* /*
* For 64-bit kernel, __va can't be used since it would return a linear * For 64-bit kernel, __va can't be used since it would return a linear
...@@ -1055,7 +1034,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa) ...@@ -1055,7 +1034,8 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
create_kernel_page_table(early_pg_dir, true); create_kernel_page_table(early_pg_dir, true);
/* Setup early mapping for FDT early scan */ /* Setup early mapping for FDT early scan */
create_fdt_early_page_table(early_pg_dir, dtb_pa); create_fdt_early_page_table(early_pg_dir,
__fix_to_virt(FIX_FDT), dtb_pa);
/* /*
* Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap * Bootime fixmap only can handle PMD_SIZE mapping. Thus, boot-ioremap
...@@ -1097,6 +1077,16 @@ static void __init setup_vm_final(void) ...@@ -1097,6 +1077,16 @@ static void __init setup_vm_final(void)
u64 i; u64 i;
/* Setup swapper PGD for fixmap */ /* Setup swapper PGD for fixmap */
#if !defined(CONFIG_64BIT)
/*
* In 32-bit, the device tree lies in a pgd entry, so it must be copied
* directly in swapper_pg_dir in addition to the pgd entry that points
* to fixmap_pte.
*/
unsigned long idx = pgd_index(__fix_to_virt(FIX_FDT));
set_pgd(&swapper_pg_dir[idx], early_pg_dir[idx]);
#endif
create_pgd_mapping(swapper_pg_dir, FIXADDR_START, create_pgd_mapping(swapper_pg_dir, FIXADDR_START,
__pa_symbol(fixmap_pgd_next), __pa_symbol(fixmap_pgd_next),
PGDIR_SIZE, PAGE_TABLE); PGDIR_SIZE, PAGE_TABLE);
......
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