diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-03-08 05:53:35 -0500 |
---|---|---|
committer | Christian Borntraeger <borntraeger@de.ibm.com> | 2016-06-10 06:07:27 -0400 |
commit | d3ed1ceeace311af9973d17a07a114bfaf0ca1b1 (patch) | |
tree | 1e9a353c769d89bf8eee9489f931869dcaf0651a /arch/s390/mm | |
parent | c427c42cd612719e8fb8b5891cc9761e7770024e (diff) |
s390/mm: set and get guest storage key mmap locking
Move the mmap semaphore locking out of set_guest_storage_key
and get_guest_storage_key. This makes the two functions more
like the other ptep_xxx operations and allows to avoid repeated
semaphore operations if multiple keys are read or written.
Reviewed-by: David Hildenbrand <dahi@linux.vnet.ibm.com>
Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'arch/s390/mm')
-rw-r--r-- | arch/s390/mm/pgtable.c | 15 |
1 files changed, 3 insertions, 12 deletions
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c index 2a23ca96f9c2..7612a7c3a3a8 100644 --- a/arch/s390/mm/pgtable.c +++ b/arch/s390/mm/pgtable.c | |||
@@ -506,12 +506,9 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, | |||
506 | pgste_t old, new; | 506 | pgste_t old, new; |
507 | pte_t *ptep; | 507 | pte_t *ptep; |
508 | 508 | ||
509 | down_read(&mm->mmap_sem); | ||
510 | ptep = get_locked_pte(mm, addr, &ptl); | 509 | ptep = get_locked_pte(mm, addr, &ptl); |
511 | if (unlikely(!ptep)) { | 510 | if (unlikely(!ptep)) |
512 | up_read(&mm->mmap_sem); | ||
513 | return -EFAULT; | 511 | return -EFAULT; |
514 | } | ||
515 | 512 | ||
516 | new = old = pgste_get_lock(ptep); | 513 | new = old = pgste_get_lock(ptep); |
517 | pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT | | 514 | pgste_val(new) &= ~(PGSTE_GR_BIT | PGSTE_GC_BIT | |
@@ -538,7 +535,6 @@ int set_guest_storage_key(struct mm_struct *mm, unsigned long addr, | |||
538 | 535 | ||
539 | pgste_set_unlock(ptep, new); | 536 | pgste_set_unlock(ptep, new); |
540 | pte_unmap_unlock(ptep, ptl); | 537 | pte_unmap_unlock(ptep, ptl); |
541 | up_read(&mm->mmap_sem); | ||
542 | return 0; | 538 | return 0; |
543 | } | 539 | } |
544 | EXPORT_SYMBOL(set_guest_storage_key); | 540 | EXPORT_SYMBOL(set_guest_storage_key); |
@@ -550,14 +546,11 @@ unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr) | |||
550 | pgste_t pgste; | 546 | pgste_t pgste; |
551 | pte_t *ptep; | 547 | pte_t *ptep; |
552 | 548 | ||
553 | down_read(&mm->mmap_sem); | ||
554 | ptep = get_locked_pte(mm, addr, &ptl); | 549 | ptep = get_locked_pte(mm, addr, &ptl); |
555 | if (unlikely(!ptep)) { | 550 | if (unlikely(!ptep)) |
556 | up_read(&mm->mmap_sem); | ||
557 | return -EFAULT; | 551 | return -EFAULT; |
558 | } | ||
559 | pgste = pgste_get_lock(ptep); | ||
560 | 552 | ||
553 | pgste = pgste_get_lock(ptep); | ||
561 | if (pte_val(*ptep) & _PAGE_INVALID) { | 554 | if (pte_val(*ptep) & _PAGE_INVALID) { |
562 | key = (pgste_val(pgste) & PGSTE_ACC_BITS) >> 56; | 555 | key = (pgste_val(pgste) & PGSTE_ACC_BITS) >> 56; |
563 | key |= (pgste_val(pgste) & PGSTE_FP_BIT) >> 56; | 556 | key |= (pgste_val(pgste) & PGSTE_FP_BIT) >> 56; |
@@ -572,10 +565,8 @@ unsigned long get_guest_storage_key(struct mm_struct *mm, unsigned long addr) | |||
572 | if (pgste_val(pgste) & PGSTE_GC_BIT) | 565 | if (pgste_val(pgste) & PGSTE_GC_BIT) |
573 | key |= _PAGE_CHANGED; | 566 | key |= _PAGE_CHANGED; |
574 | } | 567 | } |
575 | |||
576 | pgste_set_unlock(ptep, pgste); | 568 | pgste_set_unlock(ptep, pgste); |
577 | pte_unmap_unlock(ptep, ptl); | 569 | pte_unmap_unlock(ptep, ptl); |
578 | up_read(&mm->mmap_sem); | ||
579 | return key; | 570 | return key; |
580 | } | 571 | } |
581 | EXPORT_SYMBOL(get_guest_storage_key); | 572 | EXPORT_SYMBOL(get_guest_storage_key); |