diff options
Diffstat (limited to 'arch/s390/lib/uaccess.c')
-rw-r--r-- | arch/s390/lib/uaccess.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c index f6112c7dfcc7..02359c03b809 100644 --- a/arch/s390/lib/uaccess.c +++ b/arch/s390/lib/uaccess.c @@ -13,6 +13,7 @@ #include <linux/mm.h> #include <asm/asm-extable.h> #include <asm/ctlreg.h> +#include <asm/skey.h> #ifdef CONFIG_DEBUG_ENTRY void debug_user_asce(int exit) @@ -156,6 +157,7 @@ int __cmpxchg_user_key1(unsigned long address, unsigned char *uval, bool sacf_flag; int rc = 0; + skey_regions_initialize(); shift = (3 ^ (address & 3)) << 3; address ^= address & 3; _old = (unsigned int)old << shift; @@ -163,7 +165,7 @@ int __cmpxchg_user_key1(unsigned long address, unsigned char *uval, mask = ~(0xff << shift); sacf_flag = enable_sacf_uaccess(); asm_inline volatile( - " spka 0(%[key])\n" + "20: spka 0(%[key])\n" " sacf 256\n" " llill %[count],%[max_loops]\n" "0: l %[prev],%[address]\n" @@ -181,10 +183,12 @@ int __cmpxchg_user_key1(unsigned long address, unsigned char *uval, " brct %[count],2b\n" "5: sacf 768\n" " spka %[default_key]\n" + "21:\n" EX_TABLE_UA_LOAD_REG(0b, 5b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(1b, 5b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(3b, 5b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(4b, 5b, %[rc], %[prev]) + SKEY_REGION(20b, 21b) : [rc] "+&d" (rc), [prev] "=&d" (prev), [address] "+Q" (*(int *)address), @@ -212,6 +216,7 @@ int __cmpxchg_user_key2(unsigned long address, unsigned short *uval, bool sacf_flag; int rc = 0; + skey_regions_initialize(); shift = (2 ^ (address & 2)) << 3; address ^= address & 2; _old = (unsigned int)old << shift; @@ -219,7 +224,7 @@ int __cmpxchg_user_key2(unsigned long address, unsigned short *uval, mask = ~(0xffff << shift); sacf_flag = enable_sacf_uaccess(); asm_inline volatile( - " spka 0(%[key])\n" + "20: spka 0(%[key])\n" " sacf 256\n" " llill %[count],%[max_loops]\n" "0: l %[prev],%[address]\n" @@ -237,10 +242,12 @@ int __cmpxchg_user_key2(unsigned long address, unsigned short *uval, " brct %[count],2b\n" "5: sacf 768\n" " spka %[default_key]\n" + "21:\n" EX_TABLE_UA_LOAD_REG(0b, 5b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(1b, 5b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(3b, 5b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(4b, 5b, %[rc], %[prev]) + SKEY_REGION(20b, 21b) : [rc] "+&d" (rc), [prev] "=&d" (prev), [address] "+Q" (*(int *)address), @@ -267,15 +274,18 @@ int __cmpxchg_user_key4(unsigned long address, unsigned int *uval, bool sacf_flag; int rc = 0; + skey_regions_initialize(); sacf_flag = enable_sacf_uaccess(); asm_inline volatile( - " spka 0(%[key])\n" + "20: spka 0(%[key])\n" " sacf 256\n" "0: cs %[prev],%[new],%[address]\n" "1: sacf 768\n" " spka %[default_key]\n" + "21:\n" EX_TABLE_UA_LOAD_REG(0b, 1b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(1b, 1b, %[rc], %[prev]) + SKEY_REGION(20b, 21b) : [rc] "+&d" (rc), [prev] "+&d" (prev), [address] "+Q" (*(int *)address) @@ -296,15 +306,18 @@ int __cmpxchg_user_key8(unsigned long address, unsigned long *uval, bool sacf_flag; int rc = 0; + skey_regions_initialize(); sacf_flag = enable_sacf_uaccess(); asm_inline volatile( - " spka 0(%[key])\n" + "20: spka 0(%[key])\n" " sacf 256\n" "0: csg %[prev],%[new],%[address]\n" "1: sacf 768\n" " spka %[default_key]\n" + "21:\n" EX_TABLE_UA_LOAD_REG(0b, 1b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REG(1b, 1b, %[rc], %[prev]) + SKEY_REGION(20b, 21b) : [rc] "+&d" (rc), [prev] "+&d" (prev), [address] "+QS" (*(long *)address) @@ -325,15 +338,18 @@ int __cmpxchg_user_key16(unsigned long address, __uint128_t *uval, bool sacf_flag; int rc = 0; + skey_regions_initialize(); sacf_flag = enable_sacf_uaccess(); asm_inline volatile( - " spka 0(%[key])\n" + "20: spka 0(%[key])\n" " sacf 256\n" "0: cdsg %[prev],%[new],%[address]\n" "1: sacf 768\n" " spka %[default_key]\n" + "21:\n" EX_TABLE_UA_LOAD_REGPAIR(0b, 1b, %[rc], %[prev]) EX_TABLE_UA_LOAD_REGPAIR(1b, 1b, %[rc], %[prev]) + SKEY_REGION(20b, 21b) : [rc] "+&d" (rc), [prev] "+&d" (prev), [address] "+QS" (*(__int128_t *)address) |