On Wed, 2022-11-02 at 15:19 +0100, Heiko Carstens wrote:
Add cmpxchg_user_key() which allows to execute a compare and exchange on a user space address. This allows also to specify a storage key which makes sure that key-controlled protection is considered.
This is based on a patch written by Janis Schoetterl-Glausch.
Link: https://lore.kernel.org/all/20220930210751.225873-2-scgl@linux.ibm.com Cc: Janis Schoetterl-Glausch scgl@linux.ibm.com Signed-off-by: Heiko Carstens hca@linux.ibm.com
arch/s390/include/asm/uaccess.h | 183 ++++++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+)
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h index f7038b800cc3..9bbdecb80e06 100644 --- a/arch/s390/include/asm/uaccess.h +++ b/arch/s390/include/asm/uaccess.h @@ -390,4 +390,187 @@ do { \ goto err_label; \ } while (0) +void __cmpxchg_user_key_called_with_bad_pointer(void);
+static __always_inline int __cmpxchg_user_key(unsigned long address, void *uval,
__uint128_t old, __uint128_t new,
unsigned long key, int size)
+{
- int rc = 0;
- switch (size) {
- case 1: {
unsigned int prev, tmp, shift;
shift = (3 ^ (address & 3)) << 3;
address ^= address & 3;
asm volatile(
" spka 0(%[key])\n"
" sacf 256\n"
"0: l %[prev],%[address]\n"
"1: nr %[prev],%[mask]\n"
" lr %[tmp],%[prev]\n"
" or %[prev],%[old]\n"
" or %[tmp],%[new]\n"
"2: cs %[prev],%[tmp],%[address]\n"
"3: jnl 4f\n"
" xr %[tmp],%[prev]\n"
" nr %[tmp],%[mask]\n"
Are you only entertaining cosmetic changes to cmpxchg.h? The loop condition being imprecise seems non-ideal.
" jnz 1b\n"
"4: sacf 768\n"
" spka %[default_key]\n"
EX_TABLE_UA_LOAD_REG(0b, 4b, %[rc], %[prev])
EX_TABLE_UA_LOAD_REG(1b, 4b, %[rc], %[prev])
EX_TABLE_UA_LOAD_REG(2b, 4b, %[rc], %[prev])
EX_TABLE_UA_LOAD_REG(3b, 4b, %[rc], %[prev])
: [rc] "+&d" (rc),
[prev] "=&d" (prev),
[tmp] "=&d" (tmp),
[address] "+Q" (*(int *)address)
: [old] "d" (((unsigned int)old & 0xff) << shift),
[new] "d" (((unsigned int)new & 0xff) << shift),
[mask] "d" (~(0xff << shift)),
[key] "a" (key),
Why did you get rid of the << 4 shift? That's inconsistent with the other uaccess functions that take an access key.
[default_key] "J" (PAGE_DEFAULT_KEY)
: "memory", "cc");
*(unsigned char *)uval = prev >> shift;
return rc;
- }
[...]