Re: [PATCH v2 02/17] powerpc/cell: Move data segment faulting code out of cell platform
From: Michael Neuling <hidden>
Date: 2014-10-02 00:58:06
Also in:
lkml
On Wed, 2014-10-01 at 15:23 +0530, Aneesh Kumar K.V wrote:
Michael Neuling [off-list ref] writes: =20quoted
From: Ian Munsie <redacted> __spu_trap_data_seg() currently contains code to determine the VSID and=
ESID
quoted
required for a particular EA and mm struct. This code is generically useful for other co-processors. This moves th=
e code
quoted
of the cell platform so it can be used by other powerpc code. It also =
adds 1TB
quoted
segment handling which Cell didn't have. Signed-off-by: Ian Munsie <redacted> Signed-off-by: Michael Neuling <redacted> --- arch/powerpc/include/asm/mmu-hash64.h | 7 ++++- arch/powerpc/mm/copro_fault.c | 48 ++++++++++++++++++++++++++=
++++++++
quoted
arch/powerpc/mm/slb.c | 3 --- arch/powerpc/platforms/cell/spu_base.c | 41 +++-----------------------=
---
quoted
4 files changed, 58 insertions(+), 41 deletions(-)diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/inclu=
de/asm/mmu-hash64.h
quoted
index d765144..6d0b7a2 100644--- a/arch/powerpc/include/asm/mmu-hash64.h +++ b/arch/powerpc/include/asm/mmu-hash64.h@@ -189,7 +189,12 @@ static inline unsigned int mmu_psize_to_shift(unsi=
gned int mmu_psize)
quoted
#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT) =20 #ifndef __ASSEMBLY__ - +static inline int slb_vsid_shift(int ssize) +{ + if (ssize =3D=3D MMU_SEGSIZE_256M) + return SLB_VSID_SHIFT; + return SLB_VSID_SHIFT_1T; +} static inline int segment_shift(int ssize) { if (ssize =3D=3D MMU_SEGSIZE_256M)diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_faul=
t.c
quoted
index ba7df14..b865697 100644--- a/arch/powerpc/mm/copro_fault.c +++ b/arch/powerpc/mm/copro_fault.c@@ -90,3 +90,51 @@ out_unlock: return ret; } EXPORT_SYMBOL_GPL(copro_handle_mm_fault); + +int copro_data_segment(struct mm_struct *mm, u64 ea, u64 *esid, u64 *v=
sid)
quoted
+{ + int psize, ssize; + + *esid =3D (ea & ESID_MASK) | SLB_ESID_V; + + switch (REGION_ID(ea)) { + case USER_REGION_ID: + pr_devel("copro_data_segment: 0x%llx -- USER_REGION_ID\n", ea); +#ifdef CONFIG_PPC_MM_SLICES + psize =3D get_slice_psize(mm, ea); +#else + psize =3D mm->context.user_psize; +#endif + ssize =3D user_segment_size(ea); + *vsid =3D (get_vsid(mm->context.id, ea, ssize) + << slb_vsid_shift(ssize)) | SLB_VSID_USER; + break; + case VMALLOC_REGION_ID: + pr_devel("copro_data_segment: 0x%llx -- VMALLOC_REGION_ID\n", ea); + if (ea < VMALLOC_END) + psize =3D mmu_vmalloc_psize; + else + psize =3D mmu_io_psize; + ssize =3D mmu_kernel_ssize; + *vsid =3D (get_kernel_vsid(ea, mmu_kernel_ssize) + << SLB_VSID_SHIFT) | SLB_VSID_KERNEL;=20 why not *vsid =3D (get_kernel_vsid(ea, mmu_kernel_ssize) << slb_vsid_shift(ssize)) | SLB_VSID_KERNEL; =20 for vmalloc and kernel region ? We could end up using 1T segments for ker=
nel mapping too. Yep, but I'm going to do this in patch 10 where the other optimisations are for this. Mikey