Skip to content

Commit c6bf072

Browse files
committed
Merge patch series "Memory management patches needed by Rust Binder"
Alice Ryhl <[email protected]> says: This patchset contains some abstractions needed by the Rust implementation of the Binder driver for passing data between userspace, kernelspace, and directly into other processes. These abstractions do not exactly match what was included in the Rust Binder RFC - I have made various improvements and simplifications since then. Nonetheless, please see the Rust Binder RFC [1] to get an understanding for how this will be used: Users of "rust: add userspace pointers" and "rust: add typed accessors for userspace pointers": rust_binder: add binderfs support to Rust binder rust_binder: add threading support rust_binder: add nodes and context managers rust_binder: add oneway transactions rust_binder: add death notifications rust_binder: send nodes in transactions rust_binder: add BINDER_TYPE_PTR support rust_binder: add BINDER_TYPE_FDA support rust_binder: add process freezing Users of "rust: add abstraction for `struct page`": rust_binder: add oneway transactions rust_binder: add vma shrinker Link: https://lore.kernel.org/r/[email protected] [boqun: Resolve conflicts with File patchset]
2 parents 0e303b5 + e995f11 commit c6bf072

File tree

9 files changed

+774
-40
lines changed

9 files changed

+774
-40
lines changed

include/linux/uaccess.h

+24-14
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <linux/fault-inject-usercopy.h>
66
#include <linux/instrumented.h>
77
#include <linux/minmax.h>
8+
#include <linux/nospec.h>
89
#include <linux/sched.h>
910
#include <linux/thread_info.h>
1011

@@ -138,13 +139,18 @@ __copy_to_user(void __user *to, const void *from, unsigned long n)
138139
return raw_copy_to_user(to, from, n);
139140
}
140141

141-
#ifdef INLINE_COPY_FROM_USER
142142
static inline __must_check unsigned long
143-
_copy_from_user(void *to, const void __user *from, unsigned long n)
143+
_inline_copy_from_user(void *to, const void __user *from, unsigned long n)
144144
{
145145
unsigned long res = n;
146146
might_fault();
147147
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
148+
/*
149+
* Ensure that bad access_ok() speculation will not
150+
* lead to nasty side effects *after* the copy is
151+
* finished:
152+
*/
153+
barrier_nospec();
148154
instrument_copy_from_user_before(to, from, n);
149155
res = raw_copy_from_user(to, from, n);
150156
instrument_copy_from_user_after(to, from, n, res);
@@ -153,14 +159,11 @@ _copy_from_user(void *to, const void __user *from, unsigned long n)
153159
memset(to + (n - res), 0, res);
154160
return res;
155161
}
156-
#else
157162
extern __must_check unsigned long
158163
_copy_from_user(void *, const void __user *, unsigned long);
159-
#endif
160164

161-
#ifdef INLINE_COPY_TO_USER
162165
static inline __must_check unsigned long
163-
_copy_to_user(void __user *to, const void *from, unsigned long n)
166+
_inline_copy_to_user(void __user *to, const void *from, unsigned long n)
164167
{
165168
might_fault();
166169
if (should_fail_usercopy())
@@ -171,25 +174,32 @@ _copy_to_user(void __user *to, const void *from, unsigned long n)
171174
}
172175
return n;
173176
}
174-
#else
175177
extern __must_check unsigned long
176178
_copy_to_user(void __user *, const void *, unsigned long);
177-
#endif
178179

179180
static __always_inline unsigned long __must_check
180181
copy_from_user(void *to, const void __user *from, unsigned long n)
181182
{
182-
if (check_copy_size(to, n, false))
183-
n = _copy_from_user(to, from, n);
184-
return n;
183+
if (!check_copy_size(to, n, false))
184+
return n;
185+
#ifdef INLINE_COPY_FROM_USER
186+
return _inline_copy_from_user(to, from, n);
187+
#else
188+
return _copy_from_user(to, from, n);
189+
#endif
185190
}
186191

187192
static __always_inline unsigned long __must_check
188193
copy_to_user(void __user *to, const void *from, unsigned long n)
189194
{
190-
if (check_copy_size(from, n, true))
191-
n = _copy_to_user(to, from, n);
192-
return n;
195+
if (!check_copy_size(from, n, true))
196+
return n;
197+
198+
#ifdef INLINE_COPY_TO_USER
199+
return _inline_copy_to_user(to, from, n);
200+
#else
201+
return _copy_to_user(to, from, n);
202+
#endif
193203
}
194204

195205
#ifndef copy_mc_to_kernel

lib/usercopy.c

+4-26
Original file line numberDiff line numberDiff line change
@@ -7,40 +7,18 @@
77

88
/* out-of-line parts */
99

10-
#ifndef INLINE_COPY_FROM_USER
10+
#if !defined(INLINE_COPY_FROM_USER) || defined(CONFIG_RUST)
1111
unsigned long _copy_from_user(void *to, const void __user *from, unsigned long n)
1212
{
13-
unsigned long res = n;
14-
might_fault();
15-
if (!should_fail_usercopy() && likely(access_ok(from, n))) {
16-
/*
17-
* Ensure that bad access_ok() speculation will not
18-
* lead to nasty side effects *after* the copy is
19-
* finished:
20-
*/
21-
barrier_nospec();
22-
instrument_copy_from_user_before(to, from, n);
23-
res = raw_copy_from_user(to, from, n);
24-
instrument_copy_from_user_after(to, from, n, res);
25-
}
26-
if (unlikely(res))
27-
memset(to + (n - res), 0, res);
28-
return res;
13+
return _inline_copy_from_user(to, from, n);
2914
}
3015
EXPORT_SYMBOL(_copy_from_user);
3116
#endif
3217

33-
#ifndef INLINE_COPY_TO_USER
18+
#if !defined(INLINE_COPY_TO_USER) || defined(CONFIG_RUST)
3419
unsigned long _copy_to_user(void __user *to, const void *from, unsigned long n)
3520
{
36-
might_fault();
37-
if (should_fail_usercopy())
38-
return n;
39-
if (likely(access_ok(to, n))) {
40-
instrument_copy_to_user(to, from, n);
41-
n = raw_copy_to_user(to, from, n);
42-
}
43-
return n;
21+
return _inline_copy_to_user(to, from, n);
4422
}
4523
EXPORT_SYMBOL(_copy_to_user);
4624
#endif

rust/bindings/bindings_helper.h

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
/* `bindgen` gets confused at certain things. */
3030
const size_t RUST_CONST_HELPER_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN;
31+
const size_t RUST_CONST_HELPER_PAGE_SIZE = PAGE_SIZE;
3132
const gfp_t RUST_CONST_HELPER_GFP_ATOMIC = GFP_ATOMIC;
3233
const gfp_t RUST_CONST_HELPER_GFP_KERNEL = GFP_KERNEL;
3334
const gfp_t RUST_CONST_HELPER_GFP_KERNEL_ACCOUNT = GFP_KERNEL_ACCOUNT;

rust/helpers.c

+34
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include <linux/err.h>
2828
#include <linux/errname.h>
2929
#include <linux/fs.h>
30+
#include <linux/gfp.h>
31+
#include <linux/highmem.h>
3032
#include <linux/mutex.h>
3133
#include <linux/refcount.h>
3234
#include <linux/sched/signal.h>
@@ -42,6 +44,20 @@ __noreturn void rust_helper_BUG(void)
4244
}
4345
EXPORT_SYMBOL_GPL(rust_helper_BUG);
4446

47+
unsigned long rust_helper_copy_from_user(void *to, const void __user *from,
48+
unsigned long n)
49+
{
50+
return copy_from_user(to, from, n);
51+
}
52+
EXPORT_SYMBOL_GPL(rust_helper_copy_from_user);
53+
54+
unsigned long rust_helper_copy_to_user(void __user *to, const void *from,
55+
unsigned long n)
56+
{
57+
return copy_to_user(to, from, n);
58+
}
59+
EXPORT_SYMBOL_GPL(rust_helper_copy_to_user);
60+
4561
void rust_helper_mutex_lock(struct mutex *lock)
4662
{
4763
mutex_lock(lock);
@@ -83,6 +99,24 @@ int rust_helper_signal_pending(struct task_struct *t)
8399
}
84100
EXPORT_SYMBOL_GPL(rust_helper_signal_pending);
85101

102+
struct page *rust_helper_alloc_pages(gfp_t gfp_mask, unsigned int order)
103+
{
104+
return alloc_pages(gfp_mask, order);
105+
}
106+
EXPORT_SYMBOL_GPL(rust_helper_alloc_pages);
107+
108+
void *rust_helper_kmap_local_page(struct page *page)
109+
{
110+
return kmap_local_page(page);
111+
}
112+
EXPORT_SYMBOL_GPL(rust_helper_kmap_local_page);
113+
114+
void rust_helper_kunmap_local(const void *addr)
115+
{
116+
kunmap_local(addr);
117+
}
118+
EXPORT_SYMBOL_GPL(rust_helper_kunmap_local);
119+
86120
refcount_t rust_helper_REFCOUNT_INIT(int n)
87121
{
88122
return (refcount_t)REFCOUNT_INIT(n);

rust/kernel/alloc.rs

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ pub struct AllocError;
2020
#[derive(Clone, Copy)]
2121
pub struct Flags(u32);
2222

23+
impl Flags {
24+
/// Get the raw representation of this flag.
25+
pub(crate) fn as_raw(self) -> u32 {
26+
self.0
27+
}
28+
}
29+
2330
impl core::ops::BitOr for Flags {
2431
type Output = Self;
2532
fn bitor(self, rhs: Self) -> Self::Output {

rust/kernel/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ pub mod ioctl;
3737
pub mod kunit;
3838
#[cfg(CONFIG_NET)]
3939
pub mod net;
40+
pub mod page;
4041
pub mod prelude;
4142
pub mod print;
4243
pub mod security;
@@ -48,6 +49,7 @@ pub mod sync;
4849
pub mod task;
4950
pub mod time;
5051
pub mod types;
52+
pub mod uaccess;
5153
pub mod workqueue;
5254

5355
#[doc(hidden)]

0 commit comments

Comments
 (0)