Received: by 2002:a05:6a10:a841:0:0:0:0 with SMTP id d1csp968959pxy; Wed, 28 Apr 2021 18:54:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw9hv++FuhB5yfVz2xt3YhRjHZWBDDZe8rmWUeva6VrxOy3vvuHq5ei4lCqnQUYPGQLAD83 X-Received: by 2002:a17:906:a393:: with SMTP id k19mr4066248ejz.26.1619661260421; Wed, 28 Apr 2021 18:54:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1619661260; cv=none; d=google.com; s=arc-20160816; b=QM7011EozghLYZyJdYcLmNsSvO/5y47JafgD97lfoAEbuioVdcSEvXBNjr8vcilbWj qrnAWtSNVuTSzpI3VSAZLNfRNTC/dWuByV+PddXcn/9V3xP9Sx9osKFKuFD0J0E2uaDO SJPk3qquaYhxcFsBF+CgDRdT+Jj/gNqpRHXENDyKEf9puJ9p/rISEOdmh44FsOTSABTr EzcNZXpOB7+QQ9JPK8MxheaCMtOfyt3w9OHhp/zBfwizUTbJ6Ovbp3t0XjTLXnSKx9We dDqvujJWPkKE3tr1uE/zyEmB5TEZrn9LPeinUrfpw8DnidGdLSt8SzGu/JD7aAMfv3VO D2CA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:dkim-signature; bh=Z5QgDM+I2C6Hs4bMlAREKhvOvSoohgfPlmAYHKBQSac=; b=nzB7fzvmnt7/3Vau72CKTonZQPxOa84oyU/gtC3EeGnNo4q3XtEo042qVbZvQbhyQ1 JBFNbPf5s3hJI90p2pMR8mNXAYWiFs/6swkG7pZtNPNWTL09FyLGVZdUjxYCSS78tZCE U5zIdxhvY2azJZcyeeRyNqzTr3syuxiXgqQWp5akZroJMeXiO5l+6ucUFlIqORU1t+h+ CsJ2huI2TRdbfF5ZUCYrZGyttal/4YY9288BOovlrSI11hxBl9Q4SijEmC2yC11ZbvG9 B+j27DZI4x32hYY2Do3ElYFaBvCeWp67bexHMOfNEG+Y+gt6vXmDwWSuABHugqKzSp0A so5g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=wFJzphLM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id l3si1927528ejd.313.2021.04.28.18.53.54; Wed, 28 Apr 2021 18:54:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=wFJzphLM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235404AbhD2Bxb (ORCPT + 99 others); Wed, 28 Apr 2021 21:53:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43362 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229888AbhD2Bxa (ORCPT ); Wed, 28 Apr 2021 21:53:30 -0400 Received: from mail-wm1-x32a.google.com (mail-wm1-x32a.google.com [IPv6:2a00:1450:4864:20::32a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 609A3C06138C for ; Wed, 28 Apr 2021 18:52:44 -0700 (PDT) Received: by mail-wm1-x32a.google.com with SMTP id a22-20020a05600c2256b029014294520f18so5504943wmm.1 for ; Wed, 28 Apr 2021 18:52:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to; bh=Z5QgDM+I2C6Hs4bMlAREKhvOvSoohgfPlmAYHKBQSac=; b=wFJzphLMhpNV3HJcNbszgJWUQQ5CB2rRQ5bjSrZdr83GkfqSRBhtz7ZMMH0hpjQkyB jgaS/mCGWkAmly4Oek4eXoSPOw+p/ysz/hBNsCH3ubP9pImRHtXj8IvLQZjErsWDeh+7 LIztEJskO7o9E695JhLZAxhqUXTFrBAVhKn4OEBlV5suAvf9Rbr7/bTEJkns0w062zf/ 3ocmVA3fQtfN/sZdPexq7kTwPT3ZgMM0/xvoOjI8LvYv0UCZlODD5wHewbHke8xF6IBu X00WdH4KYgdR6c5SRz7nJP11d8D9BSo5PsfLm4SlZT2WbvGeh964ConPMMkuG6vhRyLF RRFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to; bh=Z5QgDM+I2C6Hs4bMlAREKhvOvSoohgfPlmAYHKBQSac=; b=a3NlCK9gyWK7n9yBHpEBOR7BdDrrnW6+u7995qFOe9uV02XPCTW6ugcQHGUxd1MwOW tSKV4kQJQ/cJ1g8djITylpuUgZFiQBqhZ54Fok6174zPXFOHFIQvkwX9xLa+OpLYj7Da m1SRABvhWwCr4juTFfNQVnIlcWTTK7bRqBFeOclNdwLJLilM99CC25gc04/xZum9QpDo zhOk7BaOBzungosx/jvOa8e5i2yoIWTV2yZIVin9/zSKORfwhywhis1mw8vGuT4lwKA8 SztFhrHJ49I9lEaJPvsJuAu3DvB1sZ21a1HgyORR06rba4KknPWRzfXm/7uEcqd/KMSb C6Jg== X-Gm-Message-State: AOAM532ntaE/coAkUMQ+nTvWHqYRRxIzUAXej+Xif5ISV+6mAsN/ScWX 6bfWgGnGLfUbBhgRykSshfJR X-Received: by 2002:a7b:c247:: with SMTP id b7mr7519773wmj.155.1619661162897; Wed, 28 Apr 2021 18:52:42 -0700 (PDT) Received: from google.com ([2a00:79e0:d:209:ee88:aba3:edd5:1bd6]) by smtp.gmail.com with ESMTPSA id f7sm2361837wrp.48.2021.04.28.18.52.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Apr 2021 18:52:42 -0700 (PDT) Date: Thu, 29 Apr 2021 02:52:38 +0100 From: Wedson Almeida Filho To: Linus Walleij Cc: Peter Zijlstra , Miguel Ojeda , Linus Torvalds , Greg Kroah-Hartman , rust-for-linux , linux-kbuild , Linux Doc Mailing List , linux-kernel Subject: Re: [PATCH 00/13] [RFC] Rust support Message-ID: References: <20210414184604.23473-1-ojeda@kernel.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Apr 27, 2021 at 12:54:00PM +0200, Linus Walleij wrote: > I really like the look of this. I don't fully understand it, but what > is needed for driver developers to adopt rust is something like a > detailed walk-through of examples like this that explains the > syntax 100% all the way down. Do you have a suggestion for a good place to host such walk-throughs? Also, do you have other examples in mind that might be useful? Have you had a chance to read the example I posted in Google's security blog? It's not particularly complex stuff but touches on some relevant concepts: https://security.googleblog.com/2021/04/rust-in-linux-kernel.html > This looks good, but cannot be done like this. The assembly versions > of writel() etc have to be used because the compiler simply will not > emit the right type of assembly for IO access, unless the compiler > (LLVM GCC) gains knowledge of what an IO address is, and so far > they have not. That code does not preclude the use of C/assembly wrappers. One way to do it would be to define a trait that allows types to specify their read/write functions. For example: pub trait IoMemType { unsafe fn write(ptr: *mut Self, value: Self); unsafe fn read(ptr: *const Self) -> Self; } Then we restrict T in my original example to only allow types that implement IoMemType. And we implement it for u8/16/32/64 as wrappers to the C/assembly implementations. > One *could* think about putting awareness about crazy stuff like > that into the language but ... I think you may want to avoid it > and just wrap the assembly. So a bit of low-level control of the > behavior there. Yes, I'm happy to have C/assembly be the source of truth, called from Rust through wrappers. > > 2. The only unsafe part that could involve the driver for this would be the > > creation of IoMemBlock: my expectation is that this would be implemented by the > > bus driver or some library that maps the appropriate region and caps the size. > > That is, we can also build a safe abstraction for this. > > I suppose this is part of the problem in a way: a language tends to be > imperialistic: the developers will start thinking "it would all be so much > easier if I just rewrote also this thing in Rust". I'm not sure I agree with this. I actually just want to hook things up to the existing C code and expose a Rust interface that allows developers to benefit from the guarantees it offers. Unnecessarily rewriting things would slow me down, so my incentive is to avoid rewrites. > > 7. We could potentially design a way to limit which offsets are available for a > > given IoMemBlock, I just haven't thought through it yet, but it would also > > reduce the number of mistakes a developer could make. > > The kernel has an abstraction for memory and register accesses, > which is the regmap, for example MMIO regmap for simple > memory-mapped IO: > drivers/base/regmap/regmap-mmio.c > > In a way this is memory safety implemented in C. I wasn't aware of this. I like it. Thanks for sharing. > If Rust wants to do this I would strongly recommend it to > try to look like regmap MMIO. > See for example drivers/clk/sprd/common.c: > > static const struct regmap_config sprdclk_regmap_config = { > .reg_bits = 32, > .reg_stride = 4, > .val_bits = 32, > .max_register = 0xffff, > .fast_io = true, > }; > (...) > regmap = devm_regmap_init_mmio(&pdev->dev, base, > &sprdclk_regmap_config); > > It is also possible to provide a callback function to determine > if addresses are readable/writeable. > > This is really a devil-in-the-details place where Rust needs > to watch out to not reimplement regmap in a substandard > way from what is already available. At the moment we're only providing wrappers for things we need, so it is mostly restricted to what I needed for Binder. If someone wants to write a driver that would benefit from this, we will look into it and possibly wrap the C implementation. > Also in many cases developers do not use regmap MMIO > because it is just too much trouble. They tend to use it > not because "safety is nice" but because a certain register > region is very fractured and it is easy to do mistakes and > write into a read-only register by mistake. So they want > this, optionally, when the situation demands it. In Rust, we want all accesses to be safe (within reason), so we probably want to offer something like IoMemBlock for cases when regmap-mmio is too much hassle. > It looks nice but it is sadly unrealistic because we need to wrap > the real assembly accessors in practice (write memory barriers > and such) and another problem is that it shows that Rust has an > ambition to do a parallel implementation of regmap. There is no such ambition. The code in my previous email was written on the spot as a demonstration per your request. > > Would you mind sharing more about which aspect of this you feel is challenging? > > Good point. > > This explanation is going to take some space. Thanks, I appreciate this. > I am not able to express it in Rust at all and that is what > is challenging about it, the examples provided for Rust > are all about nice behaved computer programs like > cutesey fibonnacci series and such things and not really > complex stuff. I'm sure you're able to express functions and arguments, for example. So going into the details of the code would have been helpful to me. > Your binder example is however very good, the problem > is that it is not a textbook example so the intricacies of > it are not explained, top down. (I'm not blaming you for > this, I just say we need that kind of text to get to know > Rust in the details.) Do you think a write up about some of what's in there would be helpful? I was planning to publish some information about the code, including performance numbers and comparisons of past vulnerabilities once I completed the work. Probably not to the level of detail that you're seeking but I may look into having more details about the code if there is demand for it. > What we need is a good resource to learn it, that > skips the trivial aspects of the language and goes immediately > for the interesting details. > > It's not like I didn't try. > I consulted the Rust book on the website of coure. Did you run into 'Rust for Embedded C Programmers' by any chance (https://docs.opentitan.org/doc/ug/rust_for_c/)? It's not all up to date but I found it useful. > The hard thing to understand in Rust is traits. I don't understand > traits. I have the level of "a little knowledge is dangerous" and > I clearly understand this: all kernel developers must have > a thorough and intuitive understanding of the inner transcendental > meaning of the concept of a TRAIT, how it was devised, how the > authors of the language conceptualized it, what effect it is supposed > to have on generated assembly. Perhaps we need a 'Rust for Linux Kernel Programmers' in a similar vain to the page I linked above. > The language book per se is a bit too terse. > For example if I read > https://doc.rust-lang.org/book/appendix-02-operators.html > > T: ?Sized : Allow generic type parameter to be a dynamically sized type > > This is just self-referential. The description is written in a > strongly context-dependent language to make a pun ... > I think every word in that sentence except "allow"and "to be a" > is dependent on other Rust concepts and thus completely > unreadable without context. > > Instead it is described in a later chapter: > https://doc.rust-lang.org/book/ch19-04-advanced-types.html > > This is more to the point. > > "Rust has a particular trait called the Sized trait to > determine whether or not a type’s size is known at compile time." > (...) "A trait bound on ?Sized is the opposite of a trait bound on > Sized: we would read this as “T may or may not be Sized.” This > syntax is only available for Sized, not any other traits." > > But Jesus Christ. This makes me understand less not > more. I had similar frustrations when I started on the language, which wasn't that long ago. One thing that I found useful was to read through some of the RFCs related to the topic I was interested in: it was time-consuming but helped me understand not only what was going on but the rationale as well. > What I find very disturbing is that the authors of the Rust > language did NOT write it. I think this may be the source > of a serious flaw. We need this information straight from > the horse's mouth. Perhaps you're right... I don't share this feeling though. > I would strongly advice the Rust community to twist the > arms of the original Rust authors to go and review and > edit the Rust book. Possibly rewrite parts of it. This is what > the world needs to get a more adaptable Rust. > > I understand this is a thick requirement, but hey, you are > competing with C. I don't think of this as a competition. I'm not arguing for C to be replaced, only for Rust to be an option for those inclined to use it. Thanks again, -Wedson