forked from Minki/linux
powerpc fixes for 5.14 #6
- Fix random crashes on some 32-bit CPUs by adding isync() after locking/unlocking KUEP - Fix intermittent crashes when loading modules with strict module RWX - Fix a section mismatch introduce by a previous fix. Thanks to: Christophe Leroy, Fabiano Rosas, Laurent Vivier, Murilo Opsfelder Araújo, Nathan Chancellor, Stan Johnson. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAmEhjVUTHG1wZUBlbGxl cm1hbi5pZC5hdQAKCRBR6+o8yOGlgM/VD/4o5D9d2Xppt+T0zdnKomq+3ffkC33/ zBK4vqOVOXbnlRpChqIqsHB3LNxMNMvTVaoLvxgy3ZQ57+rnirSDaFOaj4Nbazdx STwWmyxW9xPshqvj8tz8uHadSkvbrCClFy59FXtJf4H/iztTnQORKnXI9r3wxXS+ wBhw8Nhquuqg4O5h4q6yLLRIAaskus7uymDzYHVZkHO0RhfPLEZJwfCxydc29ukK wIRB6qojFBbWm/UscY1w6FiYrBn4Y5F3DzoTzJ7xlO6l1NYaE+58aun/oTGU7922 /8fXYs34TnkF6sA9qGhOtOc1MXfH8meFoH9s/fY3Z3O88xTe8k15wo2Ujlk/u0X1 1Gzv9FZI0RnpPtSLPiiu72/zS/vFOxAVCFMTvcodlte9RN90fW5Qwt/O1ya22vWt Ea3O9iNmYgQ+lV7ZZYDtKQ22WHIublg6cY5d3NDyj5HrzN/vGyp3QJFb2dnWoEpx k/KkK16oiIlduLGiFoYjn1ELyHUBTvp483y7zmspA4fCb0ue6W8b2zt8FszH0hI7 N4uroGXuk9OyhNsLWR8UHUR0s6Gi0XSaQ0O4XgWfoDAAvdev4oZiCqw0q5552OvX eE/Ogxc7INCiaoeLwOhYhCKjr+jBP8fhqyQzquyqMgUqEbxLtcFZCJ09bpXHjjiH OlAvZwlzOhwcKg== =K2B0 -----END PGP SIGNATURE----- Merge tag 'powerpc-5.14-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux Pull powerpc fixes from Michael Ellerman: - Fix random crashes on some 32-bit CPUs by adding isync() after locking/unlocking KUEP - Fix intermittent crashes when loading modules with strict module RWX - Fix a section mismatch introduce by a previous fix. Thanks to Christophe Leroy, Fabiano Rosas, Laurent Vivier, Murilo Opsfelder Araújo, Nathan Chancellor, and Stan Johnson. h# -----BEGIN PGP SIGNATURE----- * tag 'powerpc-5.14-6' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/mm: Fix set_memory_*() against concurrent accesses powerpc/32s: Fix random crashes by adding isync() after locking/unlocking KUEP powerpc/xive: Do not mark xive_request_ipi() as __init
This commit is contained in:
commit
1bdc3d5be7
@ -4,6 +4,8 @@
|
||||
|
||||
#include <asm/bug.h>
|
||||
#include <asm/book3s/32/mmu-hash.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/synch.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
@ -28,6 +30,15 @@ static inline void kuep_lock(void)
|
||||
return;
|
||||
|
||||
update_user_segments(mfsr(0) | SR_NX);
|
||||
/*
|
||||
* This isync() shouldn't be necessary as the kernel is not excepted to
|
||||
* run any instruction in userspace soon after the update of segments,
|
||||
* but hash based cores (at least G3) seem to exhibit a random
|
||||
* behaviour when the 'isync' is not there. 603 cores don't have this
|
||||
* behaviour so don't do the 'isync' as it saves several CPU cycles.
|
||||
*/
|
||||
if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
isync(); /* Context sync required after mtsr() */
|
||||
}
|
||||
|
||||
static inline void kuep_unlock(void)
|
||||
@ -36,6 +47,15 @@ static inline void kuep_unlock(void)
|
||||
return;
|
||||
|
||||
update_user_segments(mfsr(0) & ~SR_NX);
|
||||
/*
|
||||
* This isync() shouldn't be necessary as a 'rfi' will soon be executed
|
||||
* to return to userspace, but hash based cores (at least G3) seem to
|
||||
* exhibit a random behaviour when the 'isync' is not there. 603 cores
|
||||
* don't have this behaviour so don't do the 'isync' as it saves several
|
||||
* CPU cycles.
|
||||
*/
|
||||
if (mmu_has_feature(MMU_FTR_HPTE_TABLE))
|
||||
isync(); /* Context sync required after mtsr() */
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC_KUAP
|
||||
|
@ -18,16 +18,12 @@
|
||||
/*
|
||||
* Updates the attributes of a page in three steps:
|
||||
*
|
||||
* 1. invalidate the page table entry
|
||||
* 2. flush the TLB
|
||||
* 3. install the new entry with the updated attributes
|
||||
*
|
||||
* Invalidating the pte means there are situations where this will not work
|
||||
* when in theory it should.
|
||||
* For example:
|
||||
* - removing write from page whilst it is being executed
|
||||
* - setting a page read-only whilst it is being read by another CPU
|
||||
* 1. take the page_table_lock
|
||||
* 2. install the new entry with the updated attributes
|
||||
* 3. flush the TLB
|
||||
*
|
||||
* This sequence is safe against concurrent updates, and also allows updating the
|
||||
* attributes of a page currently being executed or accessed.
|
||||
*/
|
||||
static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
|
||||
{
|
||||
@ -36,9 +32,7 @@ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
|
||||
|
||||
spin_lock(&init_mm.page_table_lock);
|
||||
|
||||
/* invalidate the PTE so it's safe to modify */
|
||||
pte = ptep_get_and_clear(&init_mm, addr, ptep);
|
||||
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
|
||||
pte = ptep_get(ptep);
|
||||
|
||||
/* modify the PTE bits as desired, then apply */
|
||||
switch (action) {
|
||||
@ -59,11 +53,14 @@ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
|
||||
break;
|
||||
}
|
||||
|
||||
set_pte_at(&init_mm, addr, ptep, pte);
|
||||
pte_update(&init_mm, addr, ptep, ~0UL, pte_val(pte), 0);
|
||||
|
||||
/* See ptesync comment in radix__set_pte_at() */
|
||||
if (radix_enabled())
|
||||
asm volatile("ptesync": : :"memory");
|
||||
|
||||
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
|
||||
|
||||
spin_unlock(&init_mm.page_table_lock);
|
||||
|
||||
return 0;
|
||||
|
@ -1170,7 +1170,7 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __init xive_request_ipi(unsigned int cpu)
|
||||
static int xive_request_ipi(unsigned int cpu)
|
||||
{
|
||||
struct xive_ipi_desc *xid = &xive_ipis[early_cpu_to_node(cpu)];
|
||||
int ret;
|
||||
|
Loading…
Reference in New Issue
Block a user