Re: [PATCH RFC] uaccess: user_access_begin_after_access_ok()

From: Jason Wang
Date: Tue Jun 02 2020 - 06:16:20 EST



On 2020/6/2 äå4:45, Michael S. Tsirkin wrote:
So vhost needs to poke at userspace *a lot* in a quick succession. It
is thus benefitial to enable userspace access, do our thing, then
disable. Except access_ok has already been pre-validated with all the
relevant nospec checks, so we don't need that. Add an API to allow
userspace access after access_ok and barrier_nospec are done.

Signed-off-by: Michael S. Tsirkin <mst@xxxxxxxxxx>
---

Jason, so I've been thinking using something along these lines,
then switching vhost to use unsafe_copy_to_user and friends would
solve lots of problems you observed with SMAP.

What do you think?


I'm fine with this approach.


Do we need any other APIs to make it practical?


It's not clear whether we need a new API, I think __uaccess_being() has the assumption that the address has been validated by access_ok().

Thanks



arch/x86/include/asm/uaccess.h | 1 +
include/linux/uaccess.h | 1 +
2 files changed, 2 insertions(+)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index d8f283b9a569..fa5afb3a54fe 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -483,6 +483,7 @@ static __must_check __always_inline bool user_access_begin(const void __user *pt
return 1;
}
#define user_access_begin(a,b) user_access_begin(a,b)
+#define user_access_begin_after_access_ok() __uaccess_begin()
#define user_access_end() __uaccess_end()
#define user_access_save() smap_save()
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 67f016010aad..4c0a959ad639 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -370,6 +370,7 @@ extern long strnlen_unsafe_user(const void __user *unsafe_addr, long count);
#ifndef user_access_begin
#define user_access_begin(ptr,len) access_ok(ptr, len)
+#define user_access_begin_after_access_ok() do { } while (0)
#define user_access_end() do { } while (0)
#define unsafe_op_wrap(op, err) do { if (unlikely(op)) goto err; } while (0)
#define unsafe_get_user(x,p,e) unsafe_op_wrap(__get_user(x,p),e)