Commit 85a97da9 authored by Michael Neuling's avatar Michael Neuling Committed by Michael Ellerman

powerpc/copro: Fix faulting kernel segments

This fixes calculating the key bits (KP and KS) in the SLB VSID for kernel
mappings.

I'm not CCing this to stable as there are no uses of this currently.
Signed-off-by: default avatarMichael Neuling <mikey@neuling.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 8ac75b96
...@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(copro_handle_mm_fault); ...@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(copro_handle_mm_fault);
int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb) int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
{ {
u64 vsid; u64 vsid, vsidkey;
int psize, ssize; int psize, ssize;
switch (REGION_ID(ea)) { switch (REGION_ID(ea)) {
...@@ -109,6 +109,7 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb) ...@@ -109,6 +109,7 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
psize = get_slice_psize(mm, ea); psize = get_slice_psize(mm, ea);
ssize = user_segment_size(ea); ssize = user_segment_size(ea);
vsid = get_vsid(mm->context.id, ea, ssize); vsid = get_vsid(mm->context.id, ea, ssize);
vsidkey = SLB_VSID_USER;
break; break;
case VMALLOC_REGION_ID: case VMALLOC_REGION_ID:
pr_devel("%s: 0x%llx -- VMALLOC_REGION_ID\n", __func__, ea); pr_devel("%s: 0x%llx -- VMALLOC_REGION_ID\n", __func__, ea);
...@@ -118,19 +119,21 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb) ...@@ -118,19 +119,21 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
psize = mmu_io_psize; psize = mmu_io_psize;
ssize = mmu_kernel_ssize; ssize = mmu_kernel_ssize;
vsid = get_kernel_vsid(ea, mmu_kernel_ssize); vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
vsidkey = SLB_VSID_KERNEL;
break; break;
case KERNEL_REGION_ID: case KERNEL_REGION_ID:
pr_devel("%s: 0x%llx -- KERNEL_REGION_ID\n", __func__, ea); pr_devel("%s: 0x%llx -- KERNEL_REGION_ID\n", __func__, ea);
psize = mmu_linear_psize; psize = mmu_linear_psize;
ssize = mmu_kernel_ssize; ssize = mmu_kernel_ssize;
vsid = get_kernel_vsid(ea, mmu_kernel_ssize); vsid = get_kernel_vsid(ea, mmu_kernel_ssize);
vsidkey = SLB_VSID_KERNEL;
break; break;
default: default:
pr_debug("%s: invalid region access at %016llx\n", __func__, ea); pr_debug("%s: invalid region access at %016llx\n", __func__, ea);
return 1; return 1;
} }
vsid = (vsid << slb_vsid_shift(ssize)) | SLB_VSID_USER; vsid = (vsid << slb_vsid_shift(ssize)) | vsidkey;
vsid |= mmu_psize_defs[psize].sllp | vsid |= mmu_psize_defs[psize].sllp |
((ssize == MMU_SEGSIZE_1T) ? SLB_VSID_B_1T : 0); ((ssize == MMU_SEGSIZE_1T) ? SLB_VSID_B_1T : 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment