OpenRISC updates for 7.2

A few fixes for text patching related code:
 
  * Update the section of map_page used in text patching.  It was
    left with __init when text patching was introduced to OpenRISC.
  * Add fix to invalidate remote SMP core i-caches after text is patched.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE2cRzVK74bBA6Je/xw7McLV5mJ+QFAmo2KLoACgkQw7McLV5m
 J+Rc6g/+IGKEW1snpoq8Gwfi3nYHhrwpR7oFvq+hwCIMd1srnsKy9r5O2bZmahha
 dSST4ZnSdxu1j0sS8tmNPK+ese7AKP5W0Qp79TnagqF0USTgp/ea5POA0mCxiswB
 YjmV6FbueYJV85sX6caiJyV4WHYoFr3RyydmJvq64eiTV5u4oekRpvFtXEJfTY+J
 ACvJ7hVDg6ZogdUfhWJDdMGTS+fdeOeBLyspFVDaWUCaWVyADgC8zMJT2+Z3mgDt
 2tUgN/QGW3vfWsjttstvvCRB5KwmSo1NhUumcUsWr30qioxR04DZwV1UgT3MNqE1
 pj9dNakhYU5PMosKK6GQ4JTh8tLJ4sbo1CLUrmtMMhZc65K30gF9v0xX+oYsh+J7
 Rmb/hLqp/nOptp0PHcwPgPXJIujBEHCul5vDbgYFd3CpQLl1CtCy/+FHldNm11NW
 CmfUgXLLLd5ftZqcXVRyo1f5r03bvidgNi4xdVvS4g/H0wHt0A6L8j7VZO6DjmAF
 AwbBJBQRXf7xSBbzYNzoZz+WClJ8CKsL1GKr07CRLS7vTQVtLWQXE/2wLqYTKTcq
 R7JoaaBvQIMQDhTM++26rQwSp5Y3dl7GAWjUNiMHMCUiwIZ1k30W5qbE+v2upf72
 bD8vgc3A8bYSAz70rCwjC4vBexVGYB6imq6HoQNDTfZZo5od49E=
 =aHUx
 -----END PGP SIGNATURE-----

Merge tag 'for-linus' of https://github.com/openrisc/linux

Pull OpenRISC updates from Stafford Horne:
 "A few fixes for text patching related code:

   - Update the section of map_page used in text patching. It was
     left with __init when text patching was introduced to OpenRISC

   - Add fix to invalidate remote SMP core i-caches after text is
     patched"

* tag 'for-linus' of https://github.com/openrisc/linux:
  openrisc: Fix jump_label smp syncing
  openrisc: Add full instruction cache invalidate functions
  openrisc: Cache invalidation cleanup
  openrisc: mm: Fix section mismatch between map_page and __set_fixmap
This commit is contained in:
Linus Torvalds 2026-06-21 09:43:59 -07:00
commit 1e762b53a8
7 changed files with 46 additions and 12 deletions

View File

@ -26,6 +26,7 @@ extern void local_icache_page_inv(struct page *page);
extern void local_dcache_range_flush(unsigned long start, unsigned long end);
extern void local_dcache_range_inv(unsigned long start, unsigned long end);
extern void local_icache_range_inv(unsigned long start, unsigned long end);
extern void local_icache_all_inv(void);
/*
* Data cache flushing always happen on the local cpu. Instruction cache
@ -35,10 +36,13 @@ extern void local_icache_range_inv(unsigned long start, unsigned long end);
#ifndef CONFIG_SMP
#define dcache_page_flush(page) local_dcache_page_flush(page)
#define icache_page_inv(page) local_icache_page_inv(page)
#define icache_all_inv() local_icache_all_inv()
#else /* CONFIG_SMP */
#define dcache_page_flush(page) local_dcache_page_flush(page)
#define icache_page_inv(page) smp_icache_page_inv(page)
#define icache_all_inv() smp_icache_all_inv()
extern void smp_icache_page_inv(struct page *page);
extern void smp_icache_all_inv(void);
#endif /* CONFIG_SMP */
/*

View File

@ -852,26 +852,19 @@ _ic_enable:
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_ICCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate IC */
l.addi r6,r0,0
l.sll r5,r14,r28
// l.mul r5,r14,r16
// l.trap 1
// l.addi r5,r0,IC_SIZE
1:
l.mtspr r0,r6,SPR_ICBIR
l.sfne r6,r5
l.bf 1b
l.add r6,r6,r14
// l.addi r6,r6,IC_LINE
/* Enable IC */
l.mfspr r6,r0,SPR_SR
@ -918,13 +911,10 @@ _dc_enable:
l.sll r14,r30,r28
/* Establish number of cache sets
r16 contains number of cache sets
r28 contains log(# of cache sets)
*/
l.andi r26,r24,SPR_DCCFGR_NCS
l.srli r28,r26,3
l.ori r30,r0,1
l.sll r16,r30,r28
/* Invalidate DC */
l.addi r6,r0,0

View File

@ -47,5 +47,5 @@ bool arch_jump_label_transform_queue(struct jump_entry *entry,
void arch_jump_label_transform_apply(void)
{
kick_all_cpus_sync();
icache_all_inv();
}

View File

@ -49,6 +49,9 @@ static int __patch_insn_write(void *addr, u32 insn)
waddr = patch_map(addr, FIX_TEXT_POKE0);
ret = copy_to_kernel_nofault(waddr, &insn, OPENRISC_INSN_SIZE);
if (!IS_ENABLED(CONFIG_DCACHE_WRITETHROUGH))
local_dcache_range_flush((unsigned long)waddr,
(unsigned long)waddr + OPENRISC_INSN_SIZE);
local_icache_range_inv((unsigned long)waddr,
(unsigned long)waddr + OPENRISC_INSN_SIZE);

View File

@ -346,3 +346,24 @@ void smp_icache_page_inv(struct page *page)
on_each_cpu(ipi_icache_page_inv, page, 1);
}
EXPORT_SYMBOL(smp_icache_page_inv);
static void ipi_icache_all_inv(void *arg)
{
local_icache_all_inv();
}
void smp_icache_all_inv(void)
{
if (num_online_cpus() < 2) {
local_icache_all_inv();
return;
}
/*
* Ensure stores complete before we request remote icaches
* to invalidate.
*/
mb();
on_each_cpu(ipi_icache_all_inv, NULL, 1);
}

View File

@ -63,6 +63,22 @@ void local_icache_page_inv(struct page *page)
}
EXPORT_SYMBOL(local_icache_page_inv);
void local_icache_all_inv(void)
{
if (cpu_cache_is_present(SPR_UPR_ICP)) {
unsigned long iccfgr = mfspr(SPR_ICCFGR);
unsigned long sets = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
unsigned long block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7);
unsigned long paddr = 0;
unsigned long end = sets * block_size;
while (paddr < end) {
mtspr(SPR_ICBIR, paddr);
paddr += block_size;
}
}
}
void local_dcache_range_flush(unsigned long start, unsigned long end)
{
cache_loop(start, end, SPR_DCBFR, SPR_UPR_DCP);

View File

@ -193,7 +193,7 @@ void __init mem_init(void)
return;
}
static int __init map_page(unsigned long va, phys_addr_t pa, pgprot_t prot)
static int map_page(unsigned long va, phys_addr_t pa, pgprot_t prot)
{
p4d_t *p4d;
pud_t *pud;