diff options
Diffstat (limited to 'arch/s390/mm/pgtable.c')
-rw-r--r-- | arch/s390/mm/pgtable.c | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 4d1f2bce87b3..5d56c2b95b14 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -160,6 +160,8 @@ struct gmap *gmap_alloc(struct mm_struct *mm) | |||
160 | table = (unsigned long *) page_to_phys(page); | 160 | table = (unsigned long *) page_to_phys(page); |
161 | crst_table_init(table, _REGION1_ENTRY_EMPTY); | 161 | crst_table_init(table, _REGION1_ENTRY_EMPTY); |
162 | gmap->table = table; | 162 | gmap->table = table; |
163 | gmap->asce = _ASCE_TYPE_REGION1 | _ASCE_TABLE_LENGTH | | ||
164 | _ASCE_USER_BITS | __pa(table); | ||
163 | list_add(&gmap->list, &mm->context.gmap_list); | 165 | list_add(&gmap->list, &mm->context.gmap_list); |
164 | return gmap; | 166 | return gmap; |
165 | 167 | ||
@@ -240,10 +242,6 @@ EXPORT_SYMBOL_GPL(gmap_free); | |||
240 | */ | 242 | */ |
241 | void gmap_enable(struct gmap *gmap) | 243 | void gmap_enable(struct gmap *gmap) |
242 | { | 244 | { |
243 | /* Load primary space page table origin. */ | ||
244 | S390_lowcore.user_asce = _ASCE_TYPE_REGION1 | _ASCE_TABLE_LENGTH | | ||
245 | _ASCE_USER_BITS | __pa(gmap->table); | ||
246 | asm volatile("lctlg 1,1,%0\n" : : "m" (S390_lowcore.user_asce) ); | ||
247 | S390_lowcore.gmap = (unsigned long) gmap; | 245 | S390_lowcore.gmap = (unsigned long) gmap; |
248 | } | 246 | } |
249 | EXPORT_SYMBOL_GPL(gmap_enable); | 247 | EXPORT_SYMBOL_GPL(gmap_enable); |
@@ -254,10 +252,6 @@ EXPORT_SYMBOL_GPL(gmap_enable); | |||
254 | */ | 252 | */ |
255 | void gmap_disable(struct gmap *gmap) | 253 | void gmap_disable(struct gmap *gmap) |
256 | { | 254 | { |
257 | /* Load primary space page table origin. */ | ||
258 | S390_lowcore.user_asce = | ||
259 | gmap->mm->context.asce_bits | __pa(gmap->mm->pgd); | ||
260 | asm volatile("lctlg 1,1,%0\n" : : "m" (S390_lowcore.user_asce) ); | ||
261 | S390_lowcore.gmap = 0UL; | 255 | S390_lowcore.gmap = 0UL; |
262 | } | 256 | } |
263 | EXPORT_SYMBOL_GPL(gmap_disable); | 257 | EXPORT_SYMBOL_GPL(gmap_disable); |
@@ -309,15 +303,15 @@ int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len) | |||
309 | /* Walk the guest addr space page table */ | 303 | /* Walk the guest addr space page table */ |
310 | table = gmap->table + (((to + off) >> 53) & 0x7ff); | 304 | table = gmap->table + (((to + off) >> 53) & 0x7ff); |
311 | if (*table & _REGION_ENTRY_INV) | 305 | if (*table & _REGION_ENTRY_INV) |
312 | return 0; | 306 | goto out; |
313 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 307 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
314 | table = table + (((to + off) >> 42) & 0x7ff); | 308 | table = table + (((to + off) >> 42) & 0x7ff); |
315 | if (*table & _REGION_ENTRY_INV) | 309 | if (*table & _REGION_ENTRY_INV) |
316 | return 0; | 310 | goto out; |
317 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 311 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
318 | table = table + (((to + off) >> 31) & 0x7ff); | 312 | table = table + (((to + off) >> 31) & 0x7ff); |
319 | if (*table & _REGION_ENTRY_INV) | 313 | if (*table & _REGION_ENTRY_INV) |
320 | return 0; | 314 | goto out; |
321 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); | 315 | table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN); |
322 | table = table + (((to + off) >> 20) & 0x7ff); | 316 | table = table + (((to + off) >> 20) & 0x7ff); |
323 | 317 | ||
@@ -325,6 +319,7 @@ int gmap_unmap_segment(struct gmap *gmap, unsigned long to, unsigned long len) | |||
325 | flush |= gmap_unlink_segment(gmap, table); | 319 | flush |= gmap_unlink_segment(gmap, table); |
326 | *table = _SEGMENT_ENTRY_INV; | 320 | *table = _SEGMENT_ENTRY_INV; |
327 | } | 321 | } |
322 | out: | ||
328 | up_read(&gmap->mm->mmap_sem); | 323 | up_read(&gmap->mm->mmap_sem); |
329 | if (flush) | 324 | if (flush) |
330 | gmap_flush_tlb(gmap); | 325 | gmap_flush_tlb(gmap); |