ARM fixes for v6.12

- Fix kernel mapping for XIP kernels
 - Fix SMP support for XIP kernels
 - Fix complication corner case with CFI
 - Fix a typo in nommu code
 - Fix cacheflush syscall when PAN is enabled on LPAE platforms
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEuNNh8scc2k/wOAE+9OeQG+StrGQFAmc5F/UACgkQ9OeQG+St
 rGQBRg/+P9YMx0MZTV8y5B92yAzOk28QW303f8PWzoTXMiQ1nhMFUhk/TFMaeSxs
 6CJfQ+W5S+N9X1hG8XAlBPZruX5GWKXScS1By4J/sBwTXmIomnkeL6SwQRULF63v
 C/dcFWd9avKo2XnZIhQ8mduczR17MoagXxq6kpLvgaLJ6C/b6XJQ+SwqtuGXuJtz
 NpPrU0hSLOZdfGHQC6jyIhWObgNEX+Li8EZorynOAYiy90sYUgpffAsL/qWUV+cM
 VF/cK+BYkvShxChj6rvcv7vlbGBUaV2DhRIdXe4AxD2hkX3cUmLG+10YQ7pq/gb0
 722w7ZsBRXXFnlKle3vPzf4upWdMJEQ1SM3z6nYcZ8JTK9rGIxvAlt4PhFc6iw/v
 2AF3WSXhbdRg1+6kK5Q/fsga40BtXbL/3pS/5Q57MZfrmF/0PYVdFRvKJQuRVvxC
 +FiWTDKuR7yTSK9/5hx+2W6WDjuDvoFeMBo4n9GyqdajIpi13dUminE/KdCTuz57
 OefDS7SGfUlnWj6JAUbF+hg0/Loij5KldZbmQDWLeU2/LTx3UMUMNZ6RLATQ33tT
 +aMnrxwEd2qPXNhlC/hAz/PR5tt14w2jlEK+1x4S5siW6vi4+8F6KfcycZFzkVHI
 gqRNhG//mmpnCzK7FU5q0Od0GrM1zpYhhnAXm92QPP4zJp1R0s8=
 =yhjm
 -----END PGP SIGNATURE-----

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

Pull ARM fixes from Russell King:

 - Fix kernel mapping for XIP kernels

 - Fix SMP support for XIP kernels

 - Fix complication corner case with CFI

 - Fix a typo in nommu code

 - Fix cacheflush syscall when PAN is enabled on LPAE platforms

* tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rmk/linux:
  ARM: fix cacheflush with PAN
  ARM: 9435/1: ARM/nommu: Fix typo "absence"
  ARM: 9434/1: cfi: Fix compilation corner case
  ARM: 9420/1: smp: Fix SMP for xip kernels
  ARM: 9419/1: mm: Fix kernel memory mapping for xip kernels
This commit is contained in:
Linus Torvalds 2024-11-16 15:14:39 -08:00
commit b84eeed05a
7 changed files with 50 additions and 17 deletions

View File

@ -252,11 +252,15 @@ __create_page_tables:
*/
add r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ENTRY_ORDER)
ldr r6, =(_end - 1)
/* For XIP, kernel_sec_start/kernel_sec_end are currently in RO memory */
#ifndef CONFIG_XIP_KERNEL
adr_l r5, kernel_sec_start @ _pa(kernel_sec_start)
#if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
str r8, [r5, #4] @ Save physical start of kernel (BE)
#else
str r8, [r5] @ Save physical start of kernel (LE)
#endif
#endif
orr r3, r8, r7 @ Add the MMU flags
add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ENTRY_ORDER)
@ -264,6 +268,7 @@ __create_page_tables:
add r3, r3, #1 << SECTION_SHIFT
cmp r0, r6
bls 1b
#ifndef CONFIG_XIP_KERNEL
eor r3, r3, r7 @ Remove the MMU flags
adr_l r5, kernel_sec_end @ _pa(kernel_sec_end)
#if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
@ -271,8 +276,7 @@ __create_page_tables:
#else
str r3, [r5] @ Save physical end of kernel (LE)
#endif
#ifdef CONFIG_XIP_KERNEL
#else
/*
* Map the kernel image separately as it is not located in RAM.
*/
@ -407,7 +411,11 @@ ENTRY(secondary_startup)
/*
* Use the page tables supplied from __cpu_up.
*/
#ifdef CONFIG_XIP_KERNEL
ldr r3, =(secondary_data + PLAT_PHYS_OFFSET - PAGE_OFFSET)
#else
adr_l r3, secondary_data
#endif
mov_l r12, __secondary_switched
ldrd r4, r5, [r3, #0] @ get secondary_data.pgdir
ARM_BE8(eor r4, r4, r5) @ Swap r5 and r4 in BE:

View File

@ -45,8 +45,15 @@ extern void secondary_startup(void);
static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
if (psci_ops.cpu_on)
#ifdef CONFIG_XIP_KERNEL
return psci_ops.cpu_on(cpu_logical_map(cpu),
((phys_addr_t)(&secondary_startup)
- XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+ CONFIG_XIP_PHYS_ADDR));
#else
return psci_ops.cpu_on(cpu_logical_map(cpu),
virt_to_idmap(&secondary_startup));
#endif
return -ENODEV;
}

View File

@ -570,6 +570,7 @@ static int bad_syscall(int n, struct pt_regs *regs)
static inline int
__do_cache_op(unsigned long start, unsigned long end)
{
unsigned int ua_flags;
int ret;
do {
@ -578,7 +579,9 @@ __do_cache_op(unsigned long start, unsigned long end)
if (fatal_signal_pending(current))
return 0;
ua_flags = uaccess_save_and_enable();
ret = flush_icache_user_range(start, start + chunk);
uaccess_restore(ua_flags);
if (ret)
return ret;

View File

@ -39,7 +39,7 @@ void arch_setup_dma_ops(struct device *dev, bool coherent)
/*
* Cache support for v7m is optional, so can be treated as
* coherent if no cache has been detected. Note that it is not
* enough to check if MPU is in use or not since in absense of
* enough to check if MPU is in use or not since in absence of
* MPU system memory map is used.
*/
dev->dma_coherent = cacheid ? coherent : true;

View File

@ -84,8 +84,15 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
unsigned long addr, end;
unsigned long next;
#ifdef CONFIG_XIP_KERNEL
addr = (phys_addr_t)(text_start) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+ CONFIG_XIP_PHYS_ADDR;
end = (phys_addr_t)(text_end) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+ CONFIG_XIP_PHYS_ADDR;
#else
addr = virt_to_idmap(text_start);
end = virt_to_idmap(text_end);
#endif
pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);
prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;

View File

@ -1402,18 +1402,6 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
create_mapping(&map);
}
/*
* Map the kernel if it is XIP.
* It is always first in the modulearea.
*/
#ifdef CONFIG_XIP_KERNEL
map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
map.virtual = MODULES_VADDR;
map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
map.type = MT_ROM;
create_mapping(&map);
#endif
/*
* Map the cache flushing regions.
*/
@ -1603,12 +1591,27 @@ static void __init map_kernel(void)
* This will only persist until we turn on proper memory management later on
* and we remap the whole kernel with page granularity.
*/
#ifdef CONFIG_XIP_KERNEL
phys_addr_t kernel_nx_start = kernel_sec_start;
#else
phys_addr_t kernel_x_start = kernel_sec_start;
phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
phys_addr_t kernel_nx_start = kernel_x_end;
#endif
phys_addr_t kernel_nx_end = kernel_sec_end;
struct map_desc map;
/*
* Map the kernel if it is XIP.
* It is always first in the modulearea.
*/
#ifdef CONFIG_XIP_KERNEL
map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
map.virtual = MODULES_VADDR;
map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
map.type = MT_ROM;
create_mapping(&map);
#else
map.pfn = __phys_to_pfn(kernel_x_start);
map.virtual = __phys_to_virt(kernel_x_start);
map.length = kernel_x_end - kernel_x_start;
@ -1618,7 +1621,7 @@ static void __init map_kernel(void)
/* If the nx part is small it may end up covered by the tail of the RWX section */
if (kernel_x_end == kernel_nx_end)
return;
#endif
map.pfn = __phys_to_pfn(kernel_nx_start);
map.virtual = __phys_to_virt(kernel_nx_start);
map.length = kernel_nx_end - kernel_nx_start;
@ -1764,6 +1767,11 @@ void __init paging_init(const struct machine_desc *mdesc)
{
void *zero_page;
#ifdef CONFIG_XIP_KERNEL
/* Store the kernel RW RAM region start/end in these variables */
kernel_sec_start = CONFIG_PHYS_OFFSET & SECTION_MASK;
kernel_sec_end = round_up(__pa(_end), SECTION_SIZE);
#endif
pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
kernel_sec_start, kernel_sec_end);

View File

@ -94,7 +94,7 @@ SYM_TYPED_FUNC_START(cpu_v7_dcache_clean_area)
ret lr
SYM_FUNC_END(cpu_v7_dcache_clean_area)
#ifdef CONFIG_ARM_PSCI
#if defined(CONFIG_ARM_PSCI) && defined(CONFIG_HARDEN_BRANCH_PREDICTOR)
.arch_extension sec
SYM_TYPED_FUNC_START(cpu_v7_smc_switch_mm)
stmfd sp!, {r0 - r3}