aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/mm/slb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/mm/slb.c')
-rw-r--r--arch/powerpc/mm/slb.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index 304375a73574..b0697017d0e8 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -53,7 +53,8 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
53 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags; 53 return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
54} 54}
55 55
56static inline void slb_shadow_update(unsigned long esid, unsigned long vsid, 56static inline void slb_shadow_update(unsigned long ea,
57 unsigned long flags,
57 unsigned long entry) 58 unsigned long entry)
58{ 59{
59 /* 60 /*
@@ -61,11 +62,11 @@ static inline void slb_shadow_update(unsigned long esid, unsigned long vsid,
61 * updating it. 62 * updating it.
62 */ 63 */
63 get_slb_shadow()->save_area[entry].esid = 0; 64 get_slb_shadow()->save_area[entry].esid = 0;
64 barrier(); 65 smp_wmb();
65 get_slb_shadow()->save_area[entry].vsid = vsid; 66 get_slb_shadow()->save_area[entry].vsid = mk_vsid_data(ea, flags);
66 barrier(); 67 smp_wmb();
67 get_slb_shadow()->save_area[entry].esid = esid; 68 get_slb_shadow()->save_area[entry].esid = mk_esid_data(ea, entry);
68 69 smp_wmb();
69} 70}
70 71
71static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags, 72static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
@@ -76,8 +77,7 @@ static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
76 * we don't get a stale entry here if we get preempted by PHYP 77 * we don't get a stale entry here if we get preempted by PHYP
77 * between these two statements. 78 * between these two statements.
78 */ 79 */
79 slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags), 80 slb_shadow_update(ea, flags, entry);
80 entry);
81 81
82 asm volatile("slbmte %0,%1" : 82 asm volatile("slbmte %0,%1" :
83 : "r" (mk_vsid_data(ea, flags)), 83 : "r" (mk_vsid_data(ea, flags)),
@@ -104,8 +104,7 @@ void slb_flush_and_rebolt(void)
104 ksp_esid_data &= ~SLB_ESID_V; 104 ksp_esid_data &= ~SLB_ESID_V;
105 105
106 /* Only third entry (stack) may change here so only resave that */ 106 /* Only third entry (stack) may change here so only resave that */
107 slb_shadow_update(ksp_esid_data, 107 slb_shadow_update(get_paca()->kstack, lflags, 2);
108 mk_vsid_data(ksp_esid_data, lflags), 2);
109 108
110 /* We need to do this all in asm, so we're sure we don't touch 109 /* We need to do this all in asm, so we're sure we don't touch
111 * the stack between the slbia and rebolting it. */ 110 * the stack between the slbia and rebolting it. */
@@ -123,6 +122,15 @@ void slb_flush_and_rebolt(void)
123 : "memory"); 122 : "memory");
124} 123}
125 124
125void slb_vmalloc_update(void)
126{
127 unsigned long vflags;
128
129 vflags = SLB_VSID_KERNEL | mmu_psize_defs[mmu_vmalloc_psize].sllp;
130 slb_shadow_update(VMALLOC_START, vflags, 1);
131 slb_flush_and_rebolt();
132}
133
126/* Flush all user entries from the segment table of the current processor. */ 134/* Flush all user entries from the segment table of the current processor. */
127void switch_slb(struct task_struct *tsk, struct mm_struct *mm) 135void switch_slb(struct task_struct *tsk, struct mm_struct *mm)
128{ 136{