From: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
To: Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Christian Borntraeger <borntraeger@linux.ibm.com>,
Janis Schoetterl-Glausch <scgl@linux.ibm.com>,
Sven Schnelle <svens@linux.ibm.com>,
Nico Boehr <nrb@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>,
linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH v1 01/10] s390/uaccess: Add storage key checked access to user memory
Date: Tue, 18 Jan 2022 10:52:01 +0100 [thread overview]
Message-ID: <20220118095210.1651483-2-scgl@linux.ibm.com> (raw)
In-Reply-To: <20220118095210.1651483-1-scgl@linux.ibm.com>
KVM needs a mechanism to do accesses to guest memory that honor
storage key protection.
Since the copy_to/from_user implementation makes use of move
instructions that support having an additional access key supplied,
we can implement __copy_from/to_user_with_key by enhancing the
existing implementation.
Signed-off-by: Janis Schoetterl-Glausch <scgl@linux.ibm.com>
---
arch/s390/include/asm/uaccess.h | 32 ++++++++++++++++++
arch/s390/lib/uaccess.c | 57 +++++++++++++++++++++++----------
2 files changed, 72 insertions(+), 17 deletions(-)
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 02b467461163..5138040348cc 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -33,6 +33,38 @@ static inline int __range_ok(unsigned long addr, unsigned long size)
#define access_ok(addr, size) __access_ok(addr, size)
+unsigned long __must_check
+raw_copy_from_user_with_key(void *to, const void __user *from, unsigned long n,
+ char key);
+
+unsigned long __must_check
+raw_copy_to_user_with_key(void __user *to, const void *from, unsigned long n,
+ char key);
+
+static __always_inline __must_check unsigned long
+__copy_from_user_with_key(void *to, const void __user *from, unsigned long n,
+ char key)
+{
+ might_fault();
+ if (should_fail_usercopy())
+ return n;
+ instrument_copy_from_user(to, from, n);
+ check_object_size(to, n, false);
+ return raw_copy_from_user_with_key(to, from, n, key);
+}
+
+static __always_inline __must_check unsigned long
+__copy_to_user_with_key(void __user *to, const void *from, unsigned long n,
+ char key)
+{
+ might_fault();
+ if (should_fail_usercopy())
+ return n;
+ instrument_copy_to_user(to, from, n);
+ check_object_size(from, n, true);
+ return raw_copy_to_user_with_key(to, from, n, key);
+}
+
unsigned long __must_check
raw_copy_from_user(void *to, const void __user *from, unsigned long n);
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
index d3a700385875..ce7a150dd93a 100644
--- a/arch/s390/lib/uaccess.c
+++ b/arch/s390/lib/uaccess.c
@@ -59,11 +59,13 @@ static inline int copy_with_mvcos(void)
#endif
static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr,
- unsigned long size)
+ unsigned long size, char key)
{
unsigned long tmp1, tmp2;
union oac spec = {
+ .oac2.key = key,
.oac2.as = PSW_BITS_AS_SECONDARY,
+ .oac2.k = 1,
.oac2.a = 1,
};
@@ -94,19 +96,19 @@ static inline unsigned long copy_from_user_mvcos(void *x, const void __user *ptr
}
static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr,
- unsigned long size)
+ unsigned long size, char key)
{
unsigned long tmp1, tmp2;
tmp1 = -256UL;
asm volatile(
" sacf 0\n"
- "0: mvcp 0(%0,%2),0(%1),%3\n"
+ "0: mvcp 0(%0,%2),0(%1),%[key]\n"
"7: jz 5f\n"
"1: algr %0,%3\n"
" la %1,256(%1)\n"
" la %2,256(%2)\n"
- "2: mvcp 0(%0,%2),0(%1),%3\n"
+ "2: mvcp 0(%0,%2),0(%1),%[key]\n"
"8: jnz 1b\n"
" j 5f\n"
"3: la %4,255(%1)\n" /* %4 = ptr + 255 */
@@ -115,7 +117,7 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr,
" slgr %4,%1\n"
" clgr %0,%4\n" /* copy crosses next page boundary? */
" jnh 6f\n"
- "4: mvcp 0(%4,%2),0(%1),%3\n"
+ "4: mvcp 0(%4,%2),0(%1),%[key]\n"
"9: slgr %0,%4\n"
" j 6f\n"
"5: slgr %0,%0\n"
@@ -123,24 +125,36 @@ static inline unsigned long copy_from_user_mvcp(void *x, const void __user *ptr,
EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b)
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
- : : "cc", "memory");
+ : [key] "d" (key << 4)
+ : "cc", "memory");
return size;
}
unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (copy_with_mvcos())
- return copy_from_user_mvcos(to, from, n);
- return copy_from_user_mvcp(to, from, n);
+ return copy_from_user_mvcos(to, from, n, 0);
+ return copy_from_user_mvcp(to, from, n, 0);
}
EXPORT_SYMBOL(raw_copy_from_user);
-static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
- unsigned long size)
+unsigned long raw_copy_from_user_with_key(void *to, const void __user *from,
+ unsigned long n, char key)
+{
+ if (copy_with_mvcos())
+ return copy_from_user_mvcos(to, from, n, key);
+ return copy_from_user_mvcp(to, from, n, key);
+}
+EXPORT_SYMBOL(raw_copy_from_user_with_key);
+
+inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
+ unsigned long size, char key)
{
unsigned long tmp1, tmp2;
union oac spec = {
+ .oac1.key = key,
.oac1.as = PSW_BITS_AS_SECONDARY,
+ .oac1.k = 1,
.oac1.a = 1,
};
@@ -171,19 +185,19 @@ static inline unsigned long copy_to_user_mvcos(void __user *ptr, const void *x,
}
static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x,
- unsigned long size)
+ unsigned long size, char key)
{
unsigned long tmp1, tmp2;
tmp1 = -256UL;
asm volatile(
" sacf 0\n"
- "0: mvcs 0(%0,%1),0(%2),%3\n"
+ "0: mvcs 0(%0,%1),0(%2),%[key]\n"
"7: jz 5f\n"
"1: algr %0,%3\n"
" la %1,256(%1)\n"
" la %2,256(%2)\n"
- "2: mvcs 0(%0,%1),0(%2),%3\n"
+ "2: mvcs 0(%0,%1),0(%2),%[key]\n"
"8: jnz 1b\n"
" j 5f\n"
"3: la %4,255(%1)\n" /* %4 = ptr + 255 */
@@ -192,7 +206,7 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x,
" slgr %4,%1\n"
" clgr %0,%4\n" /* copy crosses next page boundary? */
" jnh 6f\n"
- "4: mvcs 0(%4,%1),0(%2),%3\n"
+ "4: mvcs 0(%4,%1),0(%2),%[key]\n"
"9: slgr %0,%4\n"
" j 6f\n"
"5: slgr %0,%0\n"
@@ -200,17 +214,26 @@ static inline unsigned long copy_to_user_mvcs(void __user *ptr, const void *x,
EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b)
EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b)
: "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
- : : "cc", "memory");
+ : [key] "d" (key << 4)
+ : "cc", "memory");
return size;
}
unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n)
{
if (copy_with_mvcos())
- return copy_to_user_mvcos(to, from, n);
- return copy_to_user_mvcs(to, from, n);
+ return copy_to_user_mvcos(to, from, n, 0);
+ return copy_to_user_mvcs(to, from, n, 0);
}
EXPORT_SYMBOL(raw_copy_to_user);
+unsigned long raw_copy_to_user_with_key(void __user *to, const void *from,
+ unsigned long n, char key)
+{
+ if (copy_with_mvcos())
+ return copy_to_user_mvcos(to, from, n, key);
+ return copy_to_user_mvcs(to, from, n, key);
+}
+EXPORT_SYMBOL(raw_copy_to_user_with_key);
static inline unsigned long clear_user_mvcos(void __user *to, unsigned long size)
{
--
2.32.0
next prev parent reply other threads:[~2022-01-18 9:52 UTC|newest]
Thread overview: 52+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-01-18 9:52 [RFC PATCH v1 00/10] KVM: s390: Do storage key checking Janis Schoetterl-Glausch
2022-01-18 9:52 ` Janis Schoetterl-Glausch [this message]
2022-01-18 13:18 ` [RFC PATCH v1 01/10] s390/uaccess: Add storage key checked access to user memory Janosch Frank
2022-01-18 15:37 ` Sven Schnelle
2022-01-18 15:52 ` Janis Schoetterl-Glausch
2022-01-19 9:48 ` Heiko Carstens
2022-01-19 11:02 ` Janis Schoetterl-Glausch
2022-01-19 13:20 ` Heiko Carstens
2022-01-20 8:34 ` Janis Schoetterl-Glausch
2022-01-20 12:56 ` Heiko Carstens
2022-01-20 18:19 ` Heiko Carstens
2022-01-21 7:32 ` Christian Borntraeger
2022-01-21 11:04 ` Heiko Carstens
2022-01-21 13:46 ` Janis Schoetterl-Glausch
2022-01-21 14:26 ` Heiko Carstens
2022-01-24 10:38 ` [RFC PATCH] uaccess: Add mechanism for " Janis Schoetterl-Glausch
2022-01-24 17:41 ` Heiko Carstens
2022-01-25 12:35 ` Janis Schoetterl-Glausch
2022-01-25 13:23 ` Heiko Carstens
2022-01-18 9:52 ` [RFC PATCH v1 02/10] KVM: s390: Honor storage keys when accessing guest memory Janis Schoetterl-Glausch
2022-01-18 14:38 ` Janosch Frank
2022-01-20 10:27 ` Christian Borntraeger
2022-01-20 10:30 ` Janis Schoetterl-Glausch
2022-01-19 19:27 ` Christian Borntraeger
2022-01-20 8:11 ` Janis Schoetterl-Glausch
2022-01-20 8:50 ` Christian Borntraeger
2022-01-20 8:58 ` Janis Schoetterl-Glausch
2022-01-20 9:06 ` Christian Borntraeger
2022-01-18 9:52 ` [RFC PATCH v1 03/10] KVM: s390: handle_tprot: Honor storage keys Janis Schoetterl-Glausch
2022-01-18 9:52 ` [RFC PATCH v1 04/10] KVM: s390: selftests: Test TEST PROTECTION emulation Janis Schoetterl-Glausch
2022-01-20 15:40 ` Janosch Frank
2022-01-21 11:03 ` Janis Schoetterl-Glausch
2022-01-21 12:28 ` Claudio Imbrenda
2022-01-21 13:50 ` Janis Schoetterl-Glausch
2022-01-18 9:52 ` [RFC PATCH v1 05/10] KVM: s390: Add optional storage key checking to MEMOP IOCTL Janis Schoetterl-Glausch
2022-01-18 11:51 ` Christian Borntraeger
2022-01-18 9:52 ` [RFC PATCH v1 06/10] KVM: s390: Add vm IOCTL for key checked guest absolute memory access Janis Schoetterl-Glausch
2022-01-19 11:52 ` Thomas Huth
2022-01-19 12:46 ` Christian Borntraeger
2022-01-19 12:53 ` Thomas Huth
2022-01-19 13:17 ` Janis Schoetterl-Glausch
2022-01-20 10:38 ` Thomas Huth
2022-01-20 11:20 ` Christian Borntraeger
2022-01-20 12:23 ` Janis Schoetterl-Glausch
2022-01-25 12:00 ` Thomas Huth
2022-01-27 16:29 ` Janis Schoetterl-Glausch
2022-01-27 17:34 ` Claudio Imbrenda
2022-01-18 9:52 ` [RFC PATCH v1 07/10] KVM: s390: Rename existing vcpu memop functions Janis Schoetterl-Glausch
2022-01-18 9:52 ` [RFC PATCH v1 08/10] KVM: s390: selftests: Test memops with storage keys Janis Schoetterl-Glausch
2022-01-18 9:52 ` [RFC PATCH v1 09/10] KVM: s390: Add capability for storage key extension of MEM_OP IOCTL Janis Schoetterl-Glausch
2022-01-18 15:12 ` Christian Borntraeger
2022-01-18 9:52 ` [RFC PATCH v1 10/10] KVM: s390: selftests: Make use of capability in MEM_OP test Janis Schoetterl-Glausch
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220118095210.1651483-2-scgl@linux.ibm.com \
--to=scgl@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=nrb@linux.ibm.com \
--cc=svens@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.