_GLOBAL(do_hash_page_ISI)
li r4,0
_GLOBAL(do_hash_page_DSI)
- rlwimi r4,r23,32-13,30,30 /* Insert MSR_PR as _PAGE_USER */
+ /*
+ * We need to set the _PAGE_USER bit if MSR_PR is set or if we are
+ * accessing a userspace segment (even from the kernel). We assume
+ * kernel addresses always have the high bit set.
+ */
+ rotldi r0,r3,15 /* Move high bit into MSR_PR position */
+ orc r0,r23,r0
+ rlwimi r4,r0,32-13,30,30 /* Insert into _PAGE_USER */
ori r4,r4,1 /* add _PAGE_PRESENT */
mflr r21 /* Save LR in r21 */
unsigned long entry, group, old_esid, castout_entry, i;
unsigned int global_entry;
STE *ste, *castout_ste;
+ unsigned long kernel_segment = (REGION_ID(esid << SID_SHIFT) !=
+ USER_REGION_ID);
/* Search the primary group first. */
global_entry = (esid & 0x1f) << 3;
ste->dw1.dw1.vsid = vsid;
ste->dw0.dw0.esid = esid;
ste->dw0.dw0.kp = 1;
+ if (!kernel_segment)
+ ste->dw0.dw0.ks = 1;
asm volatile("eieio":::"memory");
ste->dw0.dw0.v = 1;
return (global_entry | entry);
old_esid = castout_ste->dw0.dw0.esid;
castout_ste->dw0.dw0.esid = esid;
castout_ste->dw0.dw0.kp = 1;
+ if (!kernel_segment)
+ castout_ste->dw0.dw0.ks = 1;
asm volatile("eieio" : : : "memory"); /* Order update */
castout_ste->dw0.dw0.v = 1;
asm volatile("slbie %0" : : "r" (old_esid << SID_SHIFT));
vsid_data.data.l = 1;
if (kernel_segment)
vsid_data.data.c = 1;
+ else
+ vsid_data.data.ks = 1;
esid_data.word0 = 0;
esid_data.data.esid = esid;