mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 17:53:56 +08:00
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/bug.h>
|
||||||
#include <asm/book3s/32/mmu-hash.h>
|
#include <asm/book3s/32/mmu-hash.h>
|
||||||
|
#include <asm/mmu.h>
|
||||||
|
#include <asm/synch.h>
|
||||||
|
|
||||||
#ifndef __ASSEMBLY__
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
@ -28,6 +30,15 @@ static inline void kuep_lock(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
update_user_segments(mfsr(0) | SR_NX);
|
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)
|
static inline void kuep_unlock(void)
|
||||||
@ -36,6 +47,15 @@ static inline void kuep_unlock(void)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
update_user_segments(mfsr(0) & ~SR_NX);
|
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
|
#ifdef CONFIG_PPC_KUAP
|
||||||
|
@ -18,16 +18,12 @@
|
|||||||
/*
|
/*
|
||||||
* Updates the attributes of a page in three steps:
|
* Updates the attributes of a page in three steps:
|
||||||
*
|
*
|
||||||
* 1. invalidate the page table entry
|
* 1. take the page_table_lock
|
||||||
* 2. flush the TLB
|
* 2. install the new entry with the updated attributes
|
||||||
* 3. install the new entry with the updated attributes
|
* 3. flush the TLB
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
|
* 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)
|
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);
|
spin_lock(&init_mm.page_table_lock);
|
||||||
|
|
||||||
/* invalidate the PTE so it's safe to modify */
|
pte = ptep_get(ptep);
|
||||||
pte = ptep_get_and_clear(&init_mm, addr, ptep);
|
|
||||||
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
|
|
||||||
|
|
||||||
/* modify the PTE bits as desired, then apply */
|
/* modify the PTE bits as desired, then apply */
|
||||||
switch (action) {
|
switch (action) {
|
||||||
@ -59,11 +53,14 @@ static int change_page_attr(pte_t *ptep, unsigned long addr, void *data)
|
|||||||
break;
|
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() */
|
/* See ptesync comment in radix__set_pte_at() */
|
||||||
if (radix_enabled())
|
if (radix_enabled())
|
||||||
asm volatile("ptesync": : :"memory");
|
asm volatile("ptesync": : :"memory");
|
||||||
|
|
||||||
|
flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
|
||||||
|
|
||||||
spin_unlock(&init_mm.page_table_lock);
|
spin_unlock(&init_mm.page_table_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1170,7 +1170,7 @@ out:
|
|||||||
return ret;
|
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)];
|
struct xive_ipi_desc *xid = &xive_ipis[early_cpu_to_node(cpu)];
|
||||||
int ret;
|
int ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user