s390/mm: convert pgste locking functions to C
authorClaudio Imbrenda <imbrenda@linux.ibm.com>
Tue, 5 Dec 2023 17:32:52 +0000 (18:32 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Mon, 11 Dec 2023 13:33:07 +0000 (14:33 +0100)
Convert pgste_get_lock() and pgste_set_unlock() to C.

There is no real reasons to keep them in assembler. Having them in C
makes them more readable and maintainable, and better instructions are
used automatically when available.

Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
Acked-by: Alexander Gordeev <agordeev@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Link: https://lore.kernel.org/r/20231205173252.62305-1-imbrenda@linux.ibm.com
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
arch/s390/mm/pgtable.c

index 3bd2ab2a9a3449a411145a938d65a0b1f9a5ad62..6c4523aa4fdfe3165b10c0ef99c1efe3ca551eb0 100644 (file)
@@ -125,32 +125,23 @@ static inline pte_t ptep_flush_lazy(struct mm_struct *mm,
 
 static inline pgste_t pgste_get_lock(pte_t *ptep)
 {
-       unsigned long new = 0;
+       unsigned long value = 0;
 #ifdef CONFIG_PGSTE
-       unsigned long old;
-
-       asm(
-               "       lg      %0,%2\n"
-               "0:     lgr     %1,%0\n"
-               "       nihh    %0,0xff7f\n"    /* clear PCL bit in old */
-               "       oihh    %1,0x0080\n"    /* set PCL bit in new */
-               "       csg     %0,%1,%2\n"
-               "       jl      0b\n"
-               : "=&d" (old), "=&d" (new), "=Q" (ptep[PTRS_PER_PTE])
-               : "Q" (ptep[PTRS_PER_PTE]) : "cc", "memory");
+       unsigned long *ptr = (unsigned long *)(ptep + PTRS_PER_PTE);
+
+       do {
+               value = __atomic64_or_barrier(PGSTE_PCL_BIT, ptr);
+       } while (value & PGSTE_PCL_BIT);
+       value |= PGSTE_PCL_BIT;
 #endif
-       return __pgste(new);
+       return __pgste(value);
 }
 
 static inline void pgste_set_unlock(pte_t *ptep, pgste_t pgste)
 {
 #ifdef CONFIG_PGSTE
-       asm(
-               "       nihh    %1,0xff7f\n"    /* clear PCL bit */
-               "       stg     %1,%0\n"
-               : "=Q" (ptep[PTRS_PER_PTE])
-               : "d" (pgste_val(pgste)), "Q" (ptep[PTRS_PER_PTE])
-               : "cc", "memory");
+       barrier();
+       WRITE_ONCE(*(unsigned long *)(ptep + PTRS_PER_PTE), pgste_val(pgste) & ~PGSTE_PCL_BIT);
 #endif
 }